package shkd.repc.task;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.db.DB;
import kd.bos.db.DBRoute;
import kd.bos.exception.KDException;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QFilter;
import kd.bos.schedule.executor.AbstractTask;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.MetadataServiceHelper;
import kd.bos.util.HttpClientUtils;
import kd.sdk.plugin.Plugin;
import shkd.utils.AttachmentFileUtil;
import shkd.utils.DobeDWUtils;
import shkd.utils.OAUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * 后台任务插件
 */
public class DobeContractAttachmentTask extends AbstractTask implements Plugin {

    private static final String entityName = "recon_contractbill";//表名 t_recon_contractbill
    private static final String attachKey = "attachmentcontactdoc";//合同普通附件面板标识
    private static final String zwattKey = "attachmentpanel";//合同正文(盖章件)附件面板标识
    private static final Log logger = LogFactory.getLog(DobeContractAttachmentTask.class);
    private static final String oa_menthod = "/seeyon/rest/ats/dlNas/";//OA接口方法
    public static final String oaUrl = System.getProperty("oaurl");//(测试环境外网地址)http://140.206.96.138:9091

    private static final int connectionTimeout = 5000;//5秒
    private static final int readTimeout = 60000;//60秒
    public static final String updatesql = "UPDATE t_recon_contractbill SET fk_qeug_nofj=0 WHERE fid=?;";

    @Override
    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
        String contractno;
        String fj_oaid;
        String fj_zwid;
        Long contractid;
        DynamicObject contractinfo;
        //先查出合同有附件oa id但是在金蝶中没有附件的记录
        QFilter oaidFtr = QFilter.isNotNull("qeug_fjoaid");//合同的附件OAID不为空
        QFilter nofjFtr = new QFilter("qeug_nofj","=","1");//合同未上传OA附件的标记为true
        String selectStr = "id,billno,qeug_fjoaid,qeug_fjzwid,qeug_nofj";
        DynamicObject[] cons = BusinessDataServiceHelper.load(entityName,selectStr,new QFilter[]{oaidFtr.and(nofjFtr)});
        if(cons.length == 0){
            return;
        }
        //获取appId
        String appId = MetadataServiceHelper.getDataEntityType(entityName).getAppId();
        //获取oa token 此token时效是多少
        String oaToken = OAUtils.getOaToken("oa-contract-attachment");
        if(DobeDWUtils.isEmpty(oaToken)){
            return;
        }
        //定义请求头
        Map<String, String> customerHeader = new HashMap<>();
        customerHeader.put("Content-Type", "application/json");
        customerHeader.put("token", oaToken);
        String resultjson;
        String requrl;
        String nasPath = null;
        JSONObject resultjsonObject;
        JSONArray filenames;
        for (int i = 0; i < cons.length; i++) {
            contractinfo = cons[i];
            //根据合同中的编号、附件oa id、正文oa id三个字段调用OA附件接口,记录日志
            contractid = contractinfo.getLong("id");
            contractno = contractinfo.getString("billno");
            fj_oaid = contractinfo.getString("qeug_fjoaid");//流程ID(Excel导入模板中的附件字段) 必填
            fj_zwid = contractinfo.getString("qeug_fjzwid");//正文ID(Excel导入模板中的合同正文字段) 非必填

            //拿到OA附件接口返回的NAS文件存放路径
            requrl = oaUrl+oa_menthod+contractno+"?summaryId="+fj_oaid+"&subReference="+fj_zwid;
            logger.info(contractno+" OA附件接口请求地址\n{}", requrl);
            try {
                // 发送get请求oa附件接口并获取响应,目前有合同readTimeout 将此字段值修改大一点
                resultjson = HttpClientUtils.get(requrl, customerHeader,null,connectionTimeout,readTimeout);
                logger.info(contractno+" OA附件接口返回结果\n{}", resultjson);
                resultjsonObject = JSONObject.parseObject(resultjson);
                // 检查JSON对象是否为空
                if (resultjsonObject != null && !resultjsonObject.isEmpty()) {
                    if(resultjsonObject.getBoolean("success")){
                        // /isc/prod/ZLHT20250105001/
                        //其中isc为供应链系统标志,prod为生产/uat为测试,ZLHT20250105001为接口传入的code字段
                        nasPath = resultjsonObject.getString("nasPath");
                    }else{
                        nasPath = null;
                    }
                }else{
                    nasPath = null;
                }
                //记录OA附件调用结果日志
                DobeDWUtils.saveLog(contractno,"致远附件",requrl,resultjson,true,"调用OA附件接口");
            } catch (Exception e) {
                //记录OA接口异常信息
                logger.info(contractno+" 调用OA附件接口异常\n{}"+e.getMessage());
                DobeDWUtils.saveLog(contractno,"致远附件",requrl,e.getMessage(), false,"调用OA附件接口");
                throw new RuntimeException(e);
            }
            //访问NAS文件指定存放路径,拿到当前附件和正文目录下的所有文件对象,记录日志
            //在nas路径里,需要供应链系统在/isc/oa/prod/{code}/下继续组装相对地址:
            // /isc/oa/prod/{code}/{summaryId}/下文件夹内为表单附件,/isc/oa/prod/{code}/{subReference}/为合同正文附件
            if(!DobeDWUtils.isEmpty(nasPath)){
                //处理表单附件目录 Y:\\ISC\\oa\\prod\\ht-202410413-zjs
                if(nasPath.startsWith("Y:\\ISC")){
                    //处理正式路径,需要去掉顶层ISC
                    nasPath = nasPath.substring(6).replace("\\","/");
                }else{
                    nasPath = nasPath.substring(2).replace("\\","/");
                }
                try {
                    boolean upresult = false;
                    //nasPath+fj_oaid;
                    filenames = resultjsonObject.getJSONArray("att_fileNames");//流程附件文件名称清单
                    if(filenames != null && !filenames.isEmpty()){
                        upresult = AttachmentFileUtil.saveDirFile2Attchment(appId,entityName,contractid,nasPath+"/"+fj_oaid,attachKey,filenames);
                    }
                    //处理合同正文附件目录
                    if(!DobeDWUtils.isEmpty(fj_zwid)){
                        filenames = resultjsonObject.getJSONArray("contract_fileNames");//合同正文文件名称清单
                        if(filenames != null && !filenames.isEmpty()){
                            AttachmentFileUtil.saveDirFile2Attchment(appId,entityName,contractid,nasPath+"/"+fj_zwid,zwattKey,filenames);
                        }
                    }
                    //上传成功后更新合同未上传附件的标记为false
                    if(upresult){
                        DB.update(DBRoute.of("scm"), updatesql, new Object[]{contractid});
                        //记录成功日志
                        DobeDWUtils.saveLog(contractno,"NAS附件",null,null,true,"NAS上传文件至星瀚");
                    }

                } catch (Exception e) {
                    //记录附件上传异常信息
                    logger.info(contractno+" 从NAS上传文件至星瀚异常"+e.getMessage());
                    DobeDWUtils.saveLog(contractno,"NAS附件",nasPath,e.getMessage(),false,"NAS上传文件至星瀚");
                }
            }else{
                logger.info(contractno+" OA附件接口返回路径nasPath为空,fj_oaid"+ fj_oaid);
            }
        }
    }

}