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

import com.alibaba.fastjson.JSONObject;
import com.engine.core.impl.Service;
import com.engine.htsc.lhccsq.pojo.ExistTravelInfo;
import com.engine.htsc.lhccsq.pojo.ExistTravelInfoSpecific;
import com.engine.htsc.lhccsq.service.ComputerSubsidyService;
import weaver.conn.RecordSet;
import weaver.conn.RecordSetTrans;
import weaver.general.Util;
import weaver.workflow.logging.Logger;
import weaver.workflow.logging.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.*;

public class ComputerSubsidyServiceImpl extends Service implements ComputerSubsidyService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 特殊地区
     */
    private static String[] area = {"34", "112", "248", "246"};

    /**
     * 所有出差申请（2021-09-01至今，所有无自付费用带报销的联合出差申请），出差补贴重新计算，计算结果放入新字段（cb_bak）中
     *
     * @return
     */
    @Override
    public Map<String, Object> computeExsitSubsidy() {
        Map<String, Object> result = new HashMap<>();
        RecordSetTrans rst = new RecordSetTrans();
        rst.setAutoCommit(false);
        logger.info("准备刷数据，此次刷数据的目的是所有出差申请（2021-09-01至今，所有无自付费用带报销的联合出差申请），出差补贴重新计算，计算结果放入新字段（cb_bak）中");
        String ccsqMainTable = getMainTableByWfUnNumber("ccsq");
        logger.info("获取的主表名是：" + ccsqMainTable);
        if ("".equals(ccsqMainTable) || "error".equals(ccsqMainTable)) {
            result.put("isSuccess", "false");
            result.put("message", "主表名获取异常，请检查日志");
        } else {
            try {
                // 获取所有需要刷新数据的联合出差申请流程，并将信息存储到ExistTravelInfo实体类中
                List<ExistTravelInfo> existTravelInfos = getNeedUpdateInfo(ccsqMainTable);
                logger.info("需要更新的数据有：" + JSONObject.toJSONString(existTravelInfos));
                for (ExistTravelInfo existTravelInfo : existTravelInfos) {
                    int btMoney = generateBtVal(
                            isSpecialPeople(existTravelInfo.getSfsbsx()),
                            existTravelInfo.getCcrgh(),
                            existTravelInfo.getCclxzxx(),
                            existTravelInfo.getTravelInfo());
                    logger.info("计算的补贴金额是：" + btMoney);
                    String sql = "update " + ccsqMainTable + " set cb_bak = ? where requestid = ?";
                    logger.info("即将执行的sql是：" + sql + "," + btMoney + "," + existTravelInfo.getRequestId());
                    rst.executeUpdate(sql, btMoney, existTravelInfo.getRequestId());
                }
                logger.info("更新完毕，即将提交");
                rst.commit();
                result.put("isSuccess", "true");
                result.put("message", "批量更新数据完成");
            } catch (Exception e) {
                e.getMessage();
                logger.info(e.toString());
                result.put("isSuccess", "false");
                result.put("message", "批量更新数据时发生错误，请查看日志");
            }
        }
        return result;
    }

    /**
     * 获取所有需要刷新数据的联合出差申请流程，并将信息存储到ExistTravelInfo实体类中
     * 2021-09-01至今，所有无自付费用待报销的联合出差申请
     *
     * @return
     */
    public List<ExistTravelInfo> getNeedUpdateInfo(String mainTableName) {
        List<ExistTravelInfo> existTravelInfos = new ArrayList<>();
        logger.info("获取所有需要刷新数据的联合出差申请流程，并将信息存储到ExistTravelInfo实体类中===============");
        logger.info("获取的主表名是：" + mainTableName);
        RecordSet rs = new RecordSet();
        String sql = "select a.id,a.requestid,a.cclxzxx,b.ccrgh,b.sfsbsx," +
                "listagg(c.sfbc,'&') as sfbcs,listagg(c.cfsj,'&') as cfsjs,listagg(c.fhsj,'&') as fhsjs,listagg(c.mddgn,'&') as mddgns " +
                "from " + mainTableName + " a " +
                "join " + mainTableName + "_dt2 b on a.id = b.mainid " +
                "join " + mainTableName + "_dt4 c on a.id = c.mainid " +
                "where ywzffydbx = 1 and ngrq > '2021-09-01 00:00' " +
                "group by a.id,a.requestid,a.cclxzxx,b.ccrgh,b.sfsbsx";
        logger.info("即将执行的SQL是：" + sql);
        rs.executeQuery(sql);
        while (rs.next()) {
            ExistTravelInfo existTravelInfo = new ExistTravelInfo();
            String requestid = Util.null2String(rs.getString("requestid"));
            existTravelInfo.setRequestId(requestid);
            existTravelInfo.setCclxzxx(Util.null2String(rs.getString("cclxzxx")));
            existTravelInfo.setCcrgh(Util.null2String(rs.getString("ccrgh")));
            existTravelInfo.setSfsbsx(Util.null2String(rs.getString("sfsbsx")));
            String sfbcs = Util.null2String(rs.getString("sfbcs"));
            String cfsjs = Util.null2String(rs.getString("cfsjs"));
            String fhsjs = Util.null2String(rs.getString("fhsjs"));
            String mddgns = Util.null2String(rs.getString("mddgns"));
            existTravelInfo.setTravelInfo(parseTravelInfo(sfbcs, cfsjs, fhsjs, mddgns, requestid));
            existTravelInfos.add(existTravelInfo);
        }
        return existTravelInfos;
    }

    private List<ExistTravelInfoSpecific> parseTravelInfo(String sfbcs, String cfsjs, String fhsjs, String mddgns, String requestid) {
        logger.info("进入出差信息解析方法，接收到的参数是：sfbcs：" + sfbcs + ",cfsjs:" + cfsjs + ",fhsjs:" + fhsjs + ",mddgns:" + mddgns);
        List<ExistTravelInfoSpecific> existTravelInfoSpecifics = new ArrayList<>();
        String[] sfbcList = sfbcs.split("&");
        String[] cfsjsList = cfsjs.split("&");
        String[] fhsjsList = fhsjs.split("&");
        String[] mddgnsList = mddgns.split("&");
        if (sfbcList.length == cfsjsList.length && sfbcList.length == fhsjsList.length && sfbcList.length == mddgnsList.length) {
            for (int i = 0; i < sfbcList.length; i++) {
                ExistTravelInfoSpecific existTravelInfoSpecific = new ExistTravelInfoSpecific();
                existTravelInfoSpecific.setSfbc(sfbcList[i]);
                existTravelInfoSpecific.setCfsj(cfsjsList[i]);
                existTravelInfoSpecific.setFhsj(fhsjsList[i]);
                existTravelInfoSpecific.setMddgn(mddgnsList[i]);
                existTravelInfoSpecifics.add(existTravelInfoSpecific);
            }
            logger.info("流程" + requestid + "的解析结果为：" + JSONObject.toJSONString(existTravelInfoSpecifics));
            return existTravelInfoSpecifics;
        } else {
            logger.info("明细表4中存在空值字段，请检查，requestid：" + requestid);
            return null;
        }
    }

    private String getMainTableByWfUnNumber(String unnumber) {
        RecordSet rs = new RecordSet();
        String sql = "";
        logger.info("================获取联合出差申请的主表名============");
        sql = "select distinct(t1.tablename) from workflow_bill t1,workflow_base t2 where t1.id =t2.formid and t2.UNNUMBER = ?";
        logger.info("即将执行的sql是：" + sql);
        rs.executeQuery(sql, unnumber);
        if (rs.getCounts() != 1) {
            return "error";
        } else {
            if (rs.next()) {
                return Util.null2String(rs.getString("tablename"));
            } else {
                return "";
            }
        }
    }

    /**
     * 判断是否是特殊人员
     *
     * @return 是否是特殊人员
     */
    private boolean isSpecialPeople(String sfsbsx) {
        return "0".equals(sfsbsx);
    }

    private int generateBtVal(boolean isSpecial, String ccrgh, String cclxzxx, List<ExistTravelInfoSpecific> travelInfos) {
        logger.info("进入具体计算补贴的方法==================================");
        int bt = 0;
        // 1、如果是实习生，则没有补贴
        logger.info("获取的出差人工号是：" + ccrgh);
        if (ccrgh.contains("sx")) {
            bt = 0;
        } else if (!isSpecial) {
            // 不是特殊人员
            int ts = 0;
            // 获取出差信息，对应G1216
            logger.info("需要进行补贴计算金额的差旅信息是：" + JSONObject.toJSONString(travelInfos));
            if (travelInfos != null) {
                for (int i = 0; i < travelInfos.size(); i++) {
                    ExistTravelInfoSpecific travelInfo = travelInfos.get(i);
                    String cfsj = travelInfo.getCfsj();
                    String fhsj = travelInfo.getFhsj();
                    String mddgn = travelInfo.getMddgn();
                    String sfbc = travelInfo.getSfbc();
                    // 首条数据天数+1
                    if (i == 0) {
                        ts = (int) (1 + getDaysBetween(cfsj, fhsj));
                    } else {
                        if ("0".equals(sfbc)) {
                            ts = (int) getDaysBetween(cfsj, fhsj);
                        } else {
                            ts = (int) (1 + getDaysBetween(cfsj, fhsj));
                        }
                    }
                    // 出差类型  业务
                    if ("3".equals(cclxzxx)) {
                        bt += ts * 50;
                    } else if (!"".equals(mddgn)) {
                        String city = mddgn.split(",")[1];
                        String procince = mddgn.split(",")[0];
                        List<String> areas = Arrays.asList(area);
                        if (areas.contains(city) || "282".equals(procince)) {
                            bt += ts * 100;
                        } else {
                            bt += ts * 80;
                        }
                    }
                }
            }

        }
        return bt;
    }

    /**
     * 获取两个时间点之间的天数
     *
     * @param var0
     * @param var1
     * @return
     */
    private static long getDaysBetween(String var0, String var1) {
        SimpleDateFormat var2 = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date var3 = var2.parse(var1);
            Date var4 = var2.parse(var0);
            return (var3.getTime() - var4.getTime()) / 86400000L;
        } catch (Exception var5) {
            return 0L;
        }
    }
}
