package com.seeyon.apps.src_hxinvoice.quartz;

import cn.hutool.log.Log;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.seeyon.apps.common.config.ICstConfigApi;
import com.seeyon.apps.common.plugin.vo.ConfigVo;
import com.seeyon.apps.ext.quartz.AbstractQuartzTask;
import com.seeyon.apps.src_hxinvoice.constants.HxinvoiceConstants;
import com.seeyon.apps.src_hxinvoice.dao.IHxinvoiceDao;
import com.seeyon.apps.src_hxinvoice.service.IInvoiceService;
import com.seeyon.apps.src_hxinvoice.util.FileUtil;
import com.seeyon.apps.src_hxinvoice.util.ProtUtil;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.SystemEnvironment;
import com.seeyon.ctp.common.po.filemanager.Attachment;
import com.seeyon.ctp.organization.bo.V3xOrgAccount;
import com.seeyon.ctp.organization.bo.V3xOrgMember;
import com.seeyon.ctp.organization.manager.OrgManager;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GetOrderInfoAndInvoiceInfoQuartz extends AbstractQuartzTask {

    private static Log log = Log.get(GetOrderInfoAndInvoiceInfoQuartz.class);

    protected ICstConfigApi cstConfigApi = (ICstConfigApi) AppContext.getBean("cstConfigApi");
    public String getPluginId() {return HxinvoiceConstants.getPluginId();}
    public ConfigVo getHxinvoiceConfig() {return cstConfigApi.getConfig(getPluginId());}

    private IHxinvoiceDao hxinvoiceDao;
    public void setHxinvoiceDao(IHxinvoiceDao hxinvoiceDao) {this.hxinvoiceDao = hxinvoiceDao;}
    public IHxinvoiceDao getHxinvoiceDao() {
        if (this.hxinvoiceDao == null) {this.hxinvoiceDao = ((IHxinvoiceDao) AppContext.getBean("hxinvoiceDao"));}return hxinvoiceDao;
    }

    private IInvoiceService invoiceService;
    public IInvoiceService getInvoiceService() {
        if (this.invoiceService == null) {
            this.invoiceService = ((IInvoiceService) AppContext.getBean("invoiceService"));
        }
        return invoiceService;
    }
    public void setInvoiceService(IInvoiceService invoiceService) {
        this.invoiceService = invoiceService;
    }

    private OrgManager orgManager;
    public void setOrgManager(OrgManager orgManager) {this.orgManager = orgManager; }
    public OrgManager getOrgManager() {
        if (orgManager == null) {orgManager = (OrgManager) AppContext.getBean("orgManager");}return orgManager;
    }

    @Override
    public String taskRun(String p) throws Exception {
        System.out.println("进入定时任务方法"+p);
        FileUtil fileUtil = new FileUtil();
        String path = SystemEnvironment.getApplicationFolder();
        ConfigVo configVo = getHxinvoiceConfig();
        ProtUtil protUtil = new ProtUtil();
        String uploadMemberLoginName = configVo.getParamVal(HxinvoiceConstants.uploadMemberLoginName.name());
        V3xOrgMember v3xOrgMember = orgManager.getMemberByLoginName(uploadMemberLoginName);
        String updateAccountName = configVo.getParamVal(HxinvoiceConstants.updateAccountName.name());
        V3xOrgAccount v3xOrgAccount = orgManager.getAccountByName(updateAccountName);
        String methodName = "/sims-api/invoice/api/v6/GetOrderInfoAndInvoiceInfo";
        String ipport = configVo.getParamVal(HxinvoiceConstants.ipport.name());
        String url = ipport+methodName;
//        System.out.println("调用接口路径"+url);
        log.info("调用接口路径"+url);
//        查询当前档案表中所有没有成功和失败的开票信息
        try{
        List<Map<String,String>> lists = hxinvoiceDao.getInvoicesByState();
//            System.out.println("查询符合要求的数据量"+lists.size());
            log.info("查询符合要求的数据量"+lists.size());
//        循环查询到的所有订单信息
        for (Map<String ,String> invoiceMap:lists) {
//            调用接口查询当前订单内容
            JSONObject jsonObject =invoiceService.getInvoiceTypeParam(methodName,invoiceMap);
            log.info("请求参数为"+jsonObject);
            JSONObject res = protUtil.doPost(jsonObject.toString(),"http://"+url);
            String contentStr =invoiceService.getInvoiceContentRes(res);
            String s = "{'param':"+contentStr+"}";
//        JSONArray jso = JSONArray.parseObject(str);
            JSONObject js = JSONObject.parseObject(s);
            log.info("开票状态查询返回结果转json"+js);
            JSONObject paramjson = js.getJSONObject("param");
            if("000000".equals(paramjson.getString("ZTDM"))){
                JSONArray DDFPZXXS = paramjson.getJSONArray("DDFPZXX");
                JSONObject DDFPZXX = DDFPZXXS.getJSONObject(0);
                JSONObject DDFPXX = DDFPZXX.getJSONObject("DDFPXX");
                String DDQQLSH = DDFPXX.getString("DDQQLSH");
                String XHFSBH = DDFPXX.getString("XHFSBH");
                String formId = hxinvoiceDao.getInvoiceIdByCode(DDQQLSH,XHFSBH);
//                System.out.println(DDQQLSH+XHFSBH+"查询到的主表ID为"+formId);
                log.info(DDQQLSH+XHFSBH+"查询到的主表ID为"+formId);
                if(!"0".equals(formId)){
//                FormExport formExport = new FormExport();
                    Map<String ,String> map = new HashMap<>();
                    String FPDM = DDFPXX.getString("FPDM");//发票代码
                    String FPHM = DDFPXX.getString("FPHM");//发票号码
                    String KPRQ = DDFPXX.getString("KPRQ");//开票日期
//                String SDEWMURL = DDFPXX.getString("SDEWMURL");//数电二维码交付地址
                    String DDZT = DDFPXX.getString("DDZT");//订单状态
                    String DDZTXX = DDFPXX.getString("DDZTXX");//订单状态描述
                    String DDH = DDFPXX.getString("DDH");//订单状态描述
                    String JSHJ = DDFPXX.getString("JSHJ");//主表价税合计
                    String HJJE = DDFPXX.getString("HJJE");//主表合计金额
                    String HJSE = DDFPXX.getString("HJSE");//主表合计税额
                    log.info("定时任务关键字段回写：发票代码："+FPDM+"发票号码"+FPHM+"开票日期"+KPRQ+"订单状态"+DDZT+"订单状态描述"+DDZTXX);
                    map.put("发票代码",FPDM);
                    map.put("发票号码",FPHM);
                    map.put("订单状态描述",DDZTXX);
                    map.put("实际开票日期",KPRQ);
                    map.put("订单号",DDH);
                    map.put("合计金额",JSHJ);
                    map.put("合计税额",HJSE);
//  "030000","订单开票成功""031000","订单未开票""031999","订单开票失败""032000","订单开票中""032999","订单无效"
//                查询枚举想信息
                    String stateEnumId = configVo.getParamVal(HxinvoiceConstants.stateEnumId.name());
                    Map<String,String> stateEnum = hxinvoiceDao.getCtpEnumItemsByEnumId(stateEnumId);
                    switch(DDZT){
                        case "030000":
                            map.put("订单状态",stateEnum.get("订单开票成功"));
                            map.put("开票事项说明","开票成功："+DDZTXX);
                            break;
                        case "031000":
                            map.put("订单状态",stateEnum.get("订单未开票"));
                            map.put("开票事项说明","未开票："+DDZTXX);
                            break;
                        case "031999":
                            map.put("订单状态",stateEnum.get("订单开票失败"));
                            map.put("开票事项说明","开票失败："+DDZTXX);
                            break;
                        case "032000":
                            map.put("订单状态",stateEnum.get("订单开票中"));
                            map.put("开票事项说明","开票中："+DDZTXX);
                            break;
                        case "032999":
                            map.put("订单状态",stateEnum.get("订单无效"));
                            map.put("开票事项说明","无效："+DDZTXX);
                            break;
                    }
                    map.put("电子税票系统返回结果",DDZTXX);
//                    System.out.println("对应MAP数据："+map.toString());
                    log.info("对应MAP数据："+map.toString());
//                List<ValueExport> valueExports = formExportUtil.setFormValue(map);
//                formExport.setValues(valueExports);
//        数据id   登录名   表单编码  数据
//                long l = getFormFactory().updateBusinessFormData(Long.parseLong(formId),"oatest","KPSJDA",formExport);
//                附件处理
                    if("030000".equals(DDZT)){
                        JSONArray FILEITEMLISTS = DDFPZXX.getJSONArray("FILEITEMLIST");
                        List<String> fileNames = new ArrayList<String>();
                        log.info("进行文件处理");
                        for(int n = 0 ; n < FILEITEMLISTS.size() ; n++){
                            JSONObject FILEITEMLIST = FILEITEMLISTS.getJSONObject(n);
//                    获取后缀
                            String WJLX = FILEITEMLIST.getString("WJLX");
                            String FILECONTENT = FILEITEMLIST.getString("FILECONTENT");
//                    bese64解密
                            byte[] fileBytes = Base64.decodeBase64(FILECONTENT);
                            try {
//                        判断文件路径是否存在
                                fileUtil.isFilePath(path+"/invoiceDate/"+DDQQLSH);
                                String GMFMC = DDFPXX.getString("GMFMC");
                                String newKPRQStr = KPRQ.replace("-", "").replace(" ", "").replace(":", "");
                                String fileInvoiceName = "dzfp_"+FPHM+"_"+GMFMC+"_"+newKPRQStr;
                                String fileName = path+"/invoiceDate/"+DDQQLSH+"/"+fileInvoiceName+"."+WJLX;
                                log.info("将文件保存在指定地址"+fileName);
                                FileOutputStream fos = new FileOutputStream(fileName);
                                int bufferSize = 1024; // 每次写入的块大小为1KB
                                for (int t = 0; t < fileBytes.length; t += bufferSize) {
                                    int length = Math.min(bufferSize, fileBytes.length - t);
                                    fos.write(fileBytes, t, length);
                                }
                                fos.close();
                                fileNames.add(fileName);
                                log.info("保存文件成功");
                            }catch (IOException e) {
//                                System.out.println("保存文件时出错：" + e.getMessage());
                                log.info("保存文件时出错：" + e.getMessage());
                            }
                        }
                        List<Attachment> attachments = fileUtil.fileUpload(fileNames,formId,v3xOrgMember.getId(),v3xOrgAccount.getId());
                        log.info("调用方法上传附件成");
                        String id = attachments.get(0).getSubReference()+"";
                        log.info("上传附件ID为"+id);
                        map.put("数电发票附件",id);
                    }else{
                        map.put("数电发票附件","");
                    }
                    int updateFormNum = hxinvoiceDao.updateInvoiceDataByNoCode(formId,map);
//                    System.out.println(formId+"修改主表数据为"+updateFormNum);
                    log.info(formId+"修改主表数据为"+updateFormNum);
                    if(updateFormNum==0){
                        log.info("修改主表数据失败，进行下一个档案表数据修改操作");
                        continue;
                    }
//                    根据批次号查询是否为单一开票流程
                    String dyFlowFormId = hxinvoiceDao.getInvoiceDYFlowIdByCode(DDQQLSH,XHFSBH);
                    if(!"0".equals(dyFlowFormId) && StringUtils.isNotEmpty(dyFlowFormId)){
//                        查询到当前流程号对应单一开票流程，设置返回值修改流程表单数据
                        int updateInvoiceNum = hxinvoiceDao.updateInvoiceDYFlowByCode(map.get("开票事项说明"),DDQQLSH,XHFSBH);
                        if(updateInvoiceNum==0){
                            log.info("修改单一开票流程数据失败，进行下一个档案表数据修改操作");
                            continue;
                        }
                    }else{
//                      根据批次号查询是否为批量开票流程
                        if(DDQQLSH.contains("_")){
                            String[] ddqqlshs = DDQQLSH.split("_");
                            Map<String,String> plFlowFromData = hxinvoiceDao.getInvoicePLFlowIdByCode(ddqqlshs[0],XHFSBH);
                            if(plFlowFromData!=null){
                                if(!"0".equals(plFlowFromData.get("id")) || StringUtils.isNotEmpty(plFlowFromData.get("id"))){
//                                    根据返回结果，设置返回值修改流程表数据，查询到当前流程号对应单一开票流程，设置返回值修改流程表单数据

//                                    判断返回结果是否存在对应的编号信息
                                    String[] resDatas = plFlowFromData.get("resdata").split(";");
                                    String msg = "";
                                    for (String resData: resDatas) {
                                        String[] ress = resData.split(":");
                                        if(ress[0].equals(ddqqlshs[1])){
                                            msg+=ress[0]+":"+map.get("开票事项说明")+";";
                                        }else{
                                            msg+= resData+";";
                                        }
                                    }
                                    msg = msg.substring(0,msg.length()-1);
                                    int updateInvoiceNum = hxinvoiceDao.updateInvoicePLFlowByCode(msg,DDQQLSH,XHFSBH);
                                    if(updateInvoiceNum==0){
                                        log.info("修改批量开票流程数据失败，进行下一个档案表数据修改操作");
                                        continue;
                                    }
                                }
                            }
                        }
                    }
                    JSONArray DDMXXXS = DDFPZXX.getJSONArray("DDMXXX");
                    for(int n = 0 ; n < DDMXXXS.size(); n++){
                        JSONObject DDMXXX = DDMXXXS.getJSONObject(n);
                        String SE = DDMXXX.getString("SE");
                        String SPBM = DDMXXX.getString("SPBM");
                        int num = hxinvoiceDao.updateInvoiceByGoodsCode(formId,SPBM,SE);
                        if(num == 0 ){
                            log.info("修改明细表数据为0记录修改参数"+formId+":"+SPBM+":"+SE);
                        }
                        System.out.println("修改明细表数据为"+num);
                    }
                }else{
                    System.out.println("没有查询到数据");
                }
            }else{
                   log.info("查询失败请检查参数信息"+invoiceMap.toString());
                String DDQQLSH = invoiceMap.get("ddqqlsh");
                String XHFSBH = invoiceMap.get("shuihao");
                JSONObject param = js.getJSONObject("param");
                String ZTXX = param.getString("ZTXX");
                String formId = hxinvoiceDao.getInvoiceIdByCode(DDQQLSH,XHFSBH);
                Map<String ,String> map = new HashMap<>();
                String stateEnumId = configVo.getParamVal(HxinvoiceConstants.stateEnumId.name());
                Map<String,String> stateEnum = hxinvoiceDao.getCtpEnumItemsByEnumId(stateEnumId);

                map.put("订单状态",stateEnum.get("订单开票失败"));
                map.put("开票事项说明","开票失败："+ZTXX);
                int updateFormNum = hxinvoiceDao.updateInvoiceDataByNoCode(formId,map);
//                    System.out.println(formId+"修改主表数据为"+updateFormNum);
                log.info(formId+"返回结果为空时修改主表数据为"+updateFormNum);

            }
//            System.out.println(contentStr);

        }
        }catch (Exception e){
            log.info(e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String getName() {
        return "开票订单状态查询定时任务";
    }
}
