package com.engine.htsc.payment.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.engine.htsc.payment.enums.BudgetWF;
import com.engine.htsc.payment.pojo.*;
import com.engine.htsc.payment.service.BudgetCommand;
import com.engine.htsc.payment.service.BudgetStrategy;
import com.engine.htsc.payment.service.SettlePaymentFlowService;
import com.engine.htsc.payment.util.BizUtils;
import com.engine.htsc.payment.util.BudgetStrategyFactory;
import com.engine.htsc.payment.util.IpUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;
import weaver.conn.RecordSet;
import weaver.general.Util;
import weaver.hrm.company.DepartmentComInfo;
import weaver.hrm.resource.ResourceComInfo;
import weaver.interfaces.htsc.GlobatTools.JAVATools;
import weaver.interfaces.htsc.comInfo.PropBean;
import weaver.interfaces.htsc.cus.HTUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SettlePaymentCommand implements BudgetCommand {
    private final Log log = LogFactory.getLog(HeadPaymentBudgetCommand.class);

    private final BudgetStrategy<BudgetDTO> bg = BudgetStrategyFactory.getBudgetStrategyForCgscPayment(
            BudgetWF.CGSCPAYMENT.getCode());
    SettlePaymentFlowService settlePaymentFlowService = new SettlePaymentFlowServiceImpl();
    @Override
    public String submit(String requestNo, String billStatus) throws Exception {
        assert bg != null;
        BizUtils bizUtils = new BizUtils();
        //1,获取预算信息
        BudgetDTO budgetDTO = bg.buildNewBudgetParamFromWorkflowDB(requestNo, billStatus);
        Map<String, Object> stringObjectMap = bizUtils.convertDtoToMap(budgetDTO);
        log.info("\n 执行采购商城付款预算 >>> 当前状态submit");
        log.info("\n 调用预算参数(状态:" + billStatus + ") >>> \n " + JSON.toJSONString(stringObjectMap));
        //2,记录日志信息
        WbLog wbLog = new WbLog();
        DateTime today = new DateTime();
        wbLog.setRequestNo(requestNo);
        wbLog.setTime(today.toString("yyyy-MM-dd HH:mm:ss"));
        wbLog.setUrl(String.format("%s/cwbase/JTGL/BudgetProcess.asmx?wsdl",
                Util.null2String(new PropBean().getPropName("budgetIp"))));
        wbLog.setMethod("weaver.interfaces.htsc.cus.HTUtil.budgetCommit");
        wbLog.setIp(IpUtils.getHostIp());
        try {
            //3,提交预算,调用接口
            String resp = new HTUtil().budgetCommit(stringObjectMap);
            log.info("\n 调用预算返回(状态:" + billStatus + ") >>> \n " + resp);
            //4,更新预算记录表,UF_YSJLB
            bizUtils.refreshBudgetRecord(requestNo, billStatus, JSON.toJSONString(budgetDTO), "0");
            //5,跟新中间表
//            boolean b = bizUtils.updateBudgetMidTable(requestNo, billStatus);
            boolean isUpdate = settlePaymentFlowService.doBudgetMiddleTable(requestNo, billStatus);

            log.info("\n 调用预算更新中间表返回 >>> \n " + isUpdate);
            wbLog.setResponse(resp);
            if ("F1001".equals(resp)) {
                wbLog.setResult("预算成功");
            } else {
                wbLog.setResult("预算失败,返回值:" + resp);
            }
            wbLog.setRequest(JSON.toJSONString(stringObjectMap));
            return resp; //F1001
        } catch (Exception e) {
            //记录日志
            wbLog.setResponse("");
            wbLog.setResult("预算失败");
            wbLog.setRequest(JSON.toJSONString(stringObjectMap));
            throw new Exception("预算失败");
        } finally {
            BizUtils.saveLog(wbLog);
        }
    }

    @Override
    public String reSubmit(String requestNo) throws Exception {
        String reject = reject(requestNo);
        if ("F1001".equalsIgnoreCase(reject)) {
            return submit(requestNo, "3"); //重新预占
        } else {
            return reject;
        }
    }

    @Override
    public String reject(String requestNo) throws Exception {
        assert bg != null;
        BizUtils bizUtils = new BizUtils();
        BudgetDTO lastBudgetDTO = bg.getLastBudgetParamFromModeDB(requestNo, "0");
        if(null!=lastBudgetDTO){
            log.info("\n 从建模表中获取的参数@ \n" + JSON.toJSONString(lastBudgetDTO));
            lastBudgetDTO.setBillStatus("2"); //回退
            Map<String, Object> stringObjectMap = bizUtils.convertDtoToMap(lastBudgetDTO);
            log.info("\n 执行总部通用付款预算 >>> 当前状态reject");
            log.info("\n 调用预算参数(回退) >>> \n " + JSON.toJSONString(stringObjectMap));
            //记录日志信息
            WbLog wbLog = new WbLog();
            DateTime today = new DateTime();
            wbLog.setRequestNo(requestNo);
            wbLog.setTime(today.toString("yyyy-MM-dd HH:mm:ss"));
            wbLog.setUrl(String.format("%s/cwbase/JTGL/BudgetProcess.asmx?wsdl",
                    Util.null2String(new PropBean().getPropName("budgetIp"))));
            wbLog.setMethod("weaver.interfaces.htsc.cus.HTUtil.budgetCommit");
            wbLog.setIp(IpUtils.getHostIp());
            try {
                String resp = new HTUtil().budgetCommit(stringObjectMap);
                log.info("\n 调用预算返回(回退) >>> \n " + resp);
                //4,更新预算记录表,UF_YSJLB]
                bizUtils.refreshBudgetRecord(requestNo, "2", JSON.toJSONString(lastBudgetDTO), "0");

                boolean isUpdate = settlePaymentFlowService.doBudgetMiddleTable(requestNo, "2");
                log.info("\n 调用预算更新中间表返回(回退) >>> \n " + isUpdate);
                //记录日志
                wbLog.setResponse(resp);
                wbLog.setResult("预算成功");
                wbLog.setRequest(JSON.toJSONString(stringObjectMap));
                return resp;
            } catch (Exception e) {
                //记录日志
                wbLog.setResponse("");
                wbLog.setResult("预算失败");
                wbLog.setRequest(JSON.toJSONString(stringObjectMap));
                throw new Exception("预算失败");
            } finally {
                BizUtils.saveLog(wbLog);
            }
        }else {
            return "F1001";
        }

    }

    @Override
    public String finish(String requestNo) throws Exception {
        return submit(requestNo, "1");
    }


    /**
     * 取消发票关联
     */
    public void cancelInvLink(String requestId) throws Exception {
        RecordSet rs = new RecordSet();
        String tableName = JAVATools.getMaintable(requestId);
        String sql = "SELECT ID,NGRGH,LCBH FROM " + tableName + " WHERE REQUESTID = ?";
        rs.executeQuery(sql, requestId);
        String ngrgh = "";
        String lcbh = "";
        String mainId = "";
        if (rs.next()) {
            ngrgh = Util.null2String(rs.getString("NGRGH"));
            lcbh = Util.null2String(rs.getString("LCBH"));
            mainId = Util.null2String(rs.getString("ID"));
        }
        rs.writeLog(String.format(" 取消发票关联, requestid:%s; lcbh:%s, ngrgh:%s", requestId, lcbh, ngrgh));
        if (StringUtils.isNotBlank(ngrgh) && StringUtils.isNotBlank(lcbh)) {
            //删除uf表中所关联的发票数据
            String delSql = "delete from UF_PJXXGL where REQUESTID=?";
            boolean b = rs.executeUpdate(delSql, requestId);
            rs.writeLog(String.format("删除uf表中所关联的发票数据: boolean:%s", b));
            //调用浪潮发票重置接口
            cancelInvLink4Lang(mainId, tableName + "_dt5", ngrgh, lcbh);
            cancelInvLink4Lang(mainId, tableName + "_dt6", ngrgh, lcbh);
            if (lcbh.contains("差旅")) {
                cancelInvLink4Lang(mainId, tableName + "_dt4", ngrgh, lcbh);
            }
        }
    }

    /**
     * cancelInvLink4Lang,重置浪潮发票关联
     */
    private void cancelInvLink4Lang(String mainId, String dtTableName, String ngrgh, String lcbh) {
        RecordSet rs = new RecordSet();
        rs.writeLog(String.format("开始重置明细表: %s; mainid:%s", dtTableName, mainId));
        HTUtil ht = new HTUtil();
        String sql = "SELECT WJID,FPHM,FPDM FROM " + dtTableName + " WHERE MAINID = ?";
        rs.executeQuery(sql, mainId);
        while (rs.next()) {
            Map<String, Object> params = new HashMap<>();
            params.put("UserCode", ngrgh);
            params.put("BillID", lcbh);
            params.put("FileID", Util.null2String(rs.getString("WJID")));
            params.put("InvoiceNum", Util.null2String(rs.getString("FPHM")));
            params.put("InvoiceCode", Util.null2String(rs.getString("FPDM")));
            String s = ht.resetImageAndBill(params);
            rs.writeLog("cancelInvLink4Lang: response:%s", JSONObject.toJSONString(s));
        }

    }

    public CostAccountDto generateCommonReimbData(String requestid, String wftype) {
        CostAccountDto costAccDto = new CostAccountDto();
        DepartmentComInfo dc = new DepartmentComInfo();
        RecordSet rs = new RecordSet();
        String tablename = JAVATools.getMaintable(requestid);
        rs.executeQuery(" select id,ngr,szbm,lcbh,djzs,ngrq from " + tablename + " where requestid=? ", new Object[]{requestid});
        if (rs.next()) {
            try {
                String id = Util.null2String(rs.getString("id"));
                String ngr = Util.null2String(rs.getString("ngr"));
                String szbm = Util.null2String(rs.getString("szbm"));
                String lcbh = Util.null2String(rs.getString("lcbh"));
                String djzs = Util.null2String(rs.getString("djzs"));
                String ngsj = Util.null2String(rs.getString("ngrq")) + ":00";

                DepartmentComInfo deptComInfo = new DepartmentComInfo();
                String szbmmc = deptComInfo.getDepartmentName(szbm);
                String szbmbm = deptComInfo.getDepartmentCode(szbm);

                ResourceComInfo resourceComInfo = new ResourceComInfo();
                String ngrmc = resourceComInfo.getWorkcode(ngr);

                rs.executeQuery(" select requestname from workflow_requestbase where requestid=? ", new Object[]{requestid});
                rs.next();
                String requestname = Util.null2String(rs.getString("requestname"));

                costAccDto.setType(wftype);
                costAccDto.setNgrDept(szbmmc);
                costAccDto.setNgrDeptCode(szbmbm);
                costAccDto.setNgrName(ngrmc);
                costAccDto.setRequestMark(lcbh);
                costAccDto.setRequestId(lcbh);
                costAccDto.setAttachmentNum(djzs);
                costAccDto.setLocationName("");
                costAccDto.setTitle(requestname);
                costAccDto.setCurrency("RMB");
                costAccDto.setCreateDate(ngsj);
                costAccDto.setReimbursementWay("");
                costAccDto.setPayOrderNo(lcbh);

                List<KjDetail> kjDetailList = new ArrayList<>();
                String dt12Sql = " select fysjcdbm,JE,SY,HJKM,YSKM from " + tablename + "_dt12 where mainid=? ";
                rs.executeQuery(dt12Sql, new Object[]{id});
                while (rs.next()) {
                    KjDetail kjDetail = new KjDetail();
                    BudgetData budgetData = new BudgetData(); //预算科目
                    SubjectData subjectData = new SubjectData(); //会计科目
                    String fysjcdbm = Util.null2String(rs.getString("fysjcdbm")); //费用承担部门
                    String je = Util.null2String(rs.getString("JE"));
                    String sy = Util.null2String(rs.getString("SY"));
                    String hjkmmc = Util.null2String("");
                    String hjkmbm = Util.null2String(rs.getString("HJKM"));
                    subjectData.setItemCode(hjkmbm);
                    subjectData.setItemName(hjkmmc);
                    String dyyskm = Util.null2String(rs.getString("YSKM"));
                    String dyysmc = "";
                    budgetData.setRelationCode(hjkmbm);
                    budgetData.setItemCode(dyyskm);
                    budgetData.setItemName(dyysmc);
                    kjDetail.setExpenseDeptCode(dc.getDepartmentCode(fysjcdbm));
                    kjDetail.setExpenseDept(dc.getDepartmentmark(fysjcdbm));
                    kjDetail.setExpenseBadge("");
                    kjDetail.setExpensePerson("");
                    kjDetail.setSubjectData(subjectData);
                    kjDetail.setBudgetData(budgetData);
                    kjDetail.setPriceRMB(je);
                    kjDetail.setMoney(je);
                    kjDetail.setProjectCode("");
                    kjDetail.setProject("");
                    kjDetail.setReason(sy);
                    kjDetailList.add(kjDetail);
                }
                costAccDto.setKjDetails(kjDetailList);

                List zfdtList = new ArrayList();
                String dt11Sql = " select yxzfje,xjzfje,khx,yxzh,skdw from " + tablename + "_dt11 where mainid=? ";
                rs.executeQuery(dt11Sql, new Object[]{id});
                while (rs.next()) {
                    String yxzfje = Util.null2String(rs.getString("yxzfje"));
                    String xjzfje = Util.null2String(rs.getString("xjzfje"));
                    String khxmc = Util.null2String(rs.getString("khx"));
                    String yxzh = Util.null2String(rs.getString("yxzh"));
                    String skdw = Util.null2String(rs.getString("skdw"));
                    PayDetail payitem = new PayDetail();
                    payitem.setPayByBank(yxzfje);
                    payitem.setPayByCash(xjzfje);
                    payitem.setBankName(khxmc);
                    payitem.setBankAccount(yxzh);
                    payitem.setEmployeeDept("");
                    payitem.setEmployeeName("");
                    payitem.setPayee(skdw);
                    zfdtList.add(payitem);
                }
                costAccDto.setPayDetails(zfdtList);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return costAccDto;
    }
}
