package nckd.jxccl.hr.gzbb;

import kd.bos.algo.DataSet;
import kd.bos.algo.Row;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.entity.LocaleString;
import kd.bos.db.DB;
import kd.bos.db.DBRoute;
import kd.bos.entity.datamodel.IDataModel;
import kd.bos.form.events.AfterDoOperationEventArgs;
import kd.bos.form.events.BeforeDoOperationEventArgs;
import kd.bos.form.operate.FormOperate;
import kd.bos.form.plugin.AbstractFormPlugin;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.login.utils.DateUtils;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

/**
 * 央国企人事云》国资报表ext》单据》数据填报
 * 数据填报初始化各级单位劳动情况统计表
 * nckd_sjtbrw
 * duanyuqi
 * */
public class SjtbInitLdqkFormPlugin extends AbstractFormPlugin {

    private static final Log logger = LogFactory.getLog(SjtbInitLdqkFormPlugin.class);

    @Override
    public void beforeDoOperation(BeforeDoOperationEventArgs args) {
        super.beforeDoOperation(args);
    }

    @Override
    public void afterDoOperation(AfterDoOperationEventArgs ags) {
        FormOperate formOperate = (FormOperate) ags.getSource();
        if ("nckd_getldqktj".equals(formOperate.getOperateKey())) { // 拉取各级单位劳动情况统计表数据
            //this.getView().showLoading(new LocaleString("正在加载"));

            // 查询数据填报配置
            List<QFilter> qfilterLzdpz = new ArrayList<QFilter>();
            qfilterLzdpz.add(new QFilter("number", "=", "SJTBRWSET"));
            QFilter[] filtersQueryLzdpz = (QFilter[]) qfilterLzdpz.toArray(new QFilter[qfilterLzdpz.size()]);
            DynamicObject lzdpzDynamicObject = BusinessDataServiceHelper.loadSingle("nckd_sjtbrwpz", "id,number,nckd_bdlzfz,nckd_qtlzfz,nckd_jhgsbm,nckd_fdgsbm", filtersQueryLzdpz);
            String nckd_bdlzfz = lzdpzDynamicObject.getString("nckd_bdlzfz");// 被动离职分组
            String nckd_qtlzfz = lzdpzDynamicObject.getString("nckd_qtlzfz");// 其他离职分组
            String nckd_jhgsbm = lzdpzDynamicObject.getString("nckd_jhgsbm");// 江西晶昊盐化有限公司编码
            String nckd_fdgsbm = lzdpzDynamicObject.getString("nckd_fdgsbm");// 江西富达盐化有限公司编码

            // 获取数据填报年月
            Date nckd_tbsjny = this.getModel().getDataEntity().getDate("nckd_tbsjny");
            String nckd_tbsjxm = DateUtils.formatDate(nckd_tbsjny, "yyyy-MM-dd");
            LocalDate date = LocalDate.parse(nckd_tbsjxm, DateTimeFormatter.ISO_LOCAL_DATE);
            LocalDate nckdTbsjxmLastDay = date.with(TemporalAdjusters.lastDayOfMonth());
            LocalDate nckdTbsjxmFirstDay = date.with(TemporalAdjusters.firstDayOfMonth());

            // 获取填报组织
            Object tbzzId = this.getModel().getDataEntity().get("org.id");// 填报组织id
            // 查询所有下级组织
            List<QFilter> qfilterHr = new ArrayList<QFilter>();
            qfilterHr.add(new QFilter("iscurrentversion", "=", "1"));// 是否当前版本
            qfilterHr.add(new QFilter("datastatus", "=", "1"));// 数据版本状态
            qfilterHr.add(new QFilter("nckd_sssjgsdata.id", "=", tbzzId).or(new QFilter("id", "=", tbzzId)));// 所属公司为填报组织
            QFilter[] filtersQueryHr = (QFilter[]) qfilterHr.toArray(new QFilter[qfilterHr.size()]);
            String selectHrFields = "id,number,structnumber,structlongnumber,name,nckd_qyszhy.id,nckd_gjdq.id,nckd_xzqh.id,nckd_sscj.id," +
                    "nckd_qygm.id,nckd_sslx.id,nckd_sfnrhbbb,nckd_sfsykjxqy" +
                    ",nckd_kjxqylx.id,nckd_qyfl.id,nckd_zcqjl,nckd_jbsszcqjl,nckd_zqypxm,simplename";
            DynamicObjectCollection hrObjectCollection = QueryServiceHelper.query("haos_adminorghr", selectHrFields, filtersQueryHr, "sortcode asc");
            if (hrObjectCollection.size() > 0) {
                List<String> orgIds = new ArrayList<String>();
                for (int i = 0; i < hrObjectCollection.size(); i++) {
                    DynamicObject dynamicObject = hrObjectCollection.get(i);
                    orgIds.add(String.valueOf(dynamicObject.getLong("id")));
                }
                // 格式化组织id
                String orgIdStr = String.join(",", orgIds);
                // 获取所有的月份
                List<LocalDate> nckd_tbsjxmMonthList = this.getLastDaysOfPreviousMonths(nckd_tbsjxm);
                // 取在职平均数
                int zgUserCount = 0;// 在岗职工
                int lwUserCount = 0;// 劳务工
                int nmgUserCount = 0;// 农民工
                int lwpqUserCount = 0;// 劳务派遣
                int txfpUserCount = 0;// 退休返聘
                int qtUserCount = 0;// 其他
                for (LocalDate nckd_tbsjxmMonth : nckd_tbsjxmMonthList) {
                    Map<String, Integer> orgUserMap = this.findZaiZhiHuaMingCe(nckd_tbsjxmMonth, orgIdStr, nckd_jhgsbm, nckd_fdgsbm);
                    zgUserCount += orgUserMap.get("zgUserCount");
                    lwUserCount += orgUserMap.get("lwUserCount");
                    nmgUserCount += orgUserMap.get("nmgUserCount");
                    lwpqUserCount += orgUserMap.get("lwpqUserCount");
                    txfpUserCount += orgUserMap.get("txfpUserCount");
                    qtUserCount += orgUserMap.get("qtUserCount");
                }

                BigDecimal monthDecimal = new BigDecimal(nckd_tbsjxmMonthList.size());
                BigDecimal zgUserCountDeciaml = new BigDecimal(zgUserCount).divide(monthDecimal, 8, BigDecimal.ROUND_HALF_UP);
                BigDecimal lwUserCountDeciaml = new BigDecimal(lwUserCount).divide(monthDecimal, 8, BigDecimal.ROUND_HALF_UP);
                BigDecimal nmgUserCountDeciaml = new BigDecimal(nmgUserCount).divide(monthDecimal, 8, BigDecimal.ROUND_HALF_UP);
                BigDecimal lwpqUserCountDeciaml = new BigDecimal(lwpqUserCount).divide(monthDecimal, 8, BigDecimal.ROUND_HALF_UP);
                BigDecimal txfpUserCountDeciaml = new BigDecimal(txfpUserCount).divide(monthDecimal, 8, BigDecimal.ROUND_HALF_UP);
                BigDecimal qtUserCountDeciaml = new BigDecimal(qtUserCount).divide(monthDecimal, 8, BigDecimal.ROUND_HALF_UP);

                BigDecimal atcyUserCountDeciaml = lwUserCountDeciaml.add(nmgUserCountDeciaml).add(lwpqUserCountDeciaml).add(txfpUserCountDeciaml).add(qtUserCountDeciaml);
                BigDecimal cyryUserCountDeciaml = new BigDecimal(zgUserCount).add(atcyUserCountDeciaml);

                IDataModel dataModel = this.getModel();
                int createNewRow = 1;
                int newRow = this.getModel().getEntryEntity("nckd_dwldqkentry").size();
                dataModel.batchCreateNewEntryRow("nckd_dwldqkentry", createNewRow);
                dataModel.setValue("nckd_gtjny", nckd_tbsjny, newRow);// 统计年月
                dataModel.setValue("nckd_gzzdata", tbzzId, newRow);// 单位名称
                dataModel.setValue("nckd_gcyryxs", cyryUserCountDeciaml, newRow);// 从业人员
                dataModel.setValue("nckd_gzgzgxs", zgUserCountDeciaml, newRow);// 在岗职工
                dataModel.setValue("nckd_gqtcyryxs", atcyUserCountDeciaml, newRow);// 其他从业人员
                dataModel.setValue("nckd_glwgxs", lwUserCountDeciaml, newRow);// 劳务工
                dataModel.setValue("nckd_gnmgxs", nmgUserCountDeciaml, newRow);// 农民工
                dataModel.setValue("nckd_glwpqxs", lwpqUserCountDeciaml, newRow);// 劳务派遣人员
                dataModel.setValue("nckd_gtxfpryxs", txfpUserCountDeciaml, newRow);// 退休返聘人员
                dataModel.setValue("nckd_gqtxs", qtUserCountDeciaml, newRow);// 其他
                // 取离职总数
                int txlzUserCount = 0;
                int jchtlzUserCount = 0;
                int khbhglzUserCount = 0;
                int swlzUserCount = 0;
                int qtlzUserCount = 0;
                for (LocalDate nckd_tbsjxmMonth : nckd_tbsjxmMonthList) {
                    Map<String, Integer> orgUserMap = this.findLiZhiHuaMingCe(nckd_tbsjxmMonth, nckd_tbsjxmMonth, orgIdStr, nckd_bdlzfz, nckd_qtlzfz);
                    txlzUserCount += orgUserMap.get("txlzUserCount");
                    jchtlzUserCount += orgUserMap.get("jchtlzUserCount");
                    khbhglzUserCount += orgUserMap.get("khbhglzUserCount");
                    swlzUserCount += orgUserMap.get("swlzUserCount");
                    qtlzUserCount += orgUserMap.get("qtlzUserCount");
                }
                int jsrs = txlzUserCount + jchtlzUserCount + khbhglzUserCount + swlzUserCount + qtlzUserCount;
                dataModel.setValue("nckd_gjsrs", jsrs, newRow);// 减少人数
                dataModel.setValue("nckd_gtx", txlzUserCount, newRow);// 退休
                dataModel.setValue("nckd_gjcht", jchtlzUserCount, newRow);// 解除合同
                dataModel.setValue("nckd_gkhbhg", khbhglzUserCount, newRow);// 考核不合格解除合同
                dataModel.setValue("nckd_gsw", swlzUserCount, newRow);// 死亡
                dataModel.setValue("nckd_gqtry", qtlzUserCount, newRow);// 其他
            };
            //this.getView().showLoading(new LocaleString("正在加载"), 1);
        }
        super.afterDoOperation(ags);
    }

    public static boolean isNullEmpty(Object obj) {
        return obj == null || (obj instanceof String && ((String) obj).isEmpty());
    }

    public Map<String,  Integer> findZaiZhiHuaMingCe(LocalDate nckdTbsjxmLastDay, String orgIdStr, String nckd_jhgsbm, String nckd_fdgsbm) {
        // 花名册查询在职人员
        String ksql_zz = " SELECT Q.femployeeid as qfemployeeid,Q.fname as qfname,E.FPERSONID as efpersonid,E.FEMPNUMBER as efempnumber, " +
                " A.FNAME as afname,A.FNUMBER as afnumber,M.FNAME as mfname,M.FNUMBER as mfnumber,P.FNUMBER AS pfnumber,P.FNAME as pfname " +
                " FROM t_hrpi_ermanfile Q" +
                " LEFT OUTER JOIN t_haos_adminorg P ON Q.forgid = P.fid " +
                " LEFT OUTER JOIN t_hrpi_employee E ON Q.femployeeid = E.fboid " +
                " AND E.fiscurrentversion = '0' AND E.fdatastatus IN ('0', '1', '2') AND" +
                " (E.fbsed <= {TS '"+nckdTbsjxmLastDay+"'}) AND (E.fbsled >= {TS '"+nckdTbsjxmLastDay+"'}) " +
                " LEFT OUTER JOIN t_hrpi_empposorgrel F ON Q.fempposrelid = F.FId " +
                " AND F.fiscurrentversion = '1' AND F.fdatastatus = '1' AND (F.fstartdate <= {TS '"+nckdTbsjxmLastDay+"'}) " +
                " AND (F.fenddate >= {TS '"+nckdTbsjxmLastDay+"'}) " +
                " LEFT OUTER JOIN t_hbss_laborrelstatus A ON E.flaborrelstatus = A.FId " +
                " left OUTER join t_hbss_labrelstatusprd K on a.flabrelstatusprdid = K.fid " +
                " LEFT OUTER JOIN t_hbss_laborreltype M ON E.flaborreltypeid = M.FID " +
                " WHERE 1 = 1 " +
                " AND Q.fiscurrentversion = '1' AND Q.fdatastatus = '1'  " +
                " AND (Q.fpersonid != 0) AND (Q.femployeeid != 0) AND (Q.fdepempid != 0) AND Q.finitstatus = '2'" +
                " AND A.flabrelstatusprdid = 1010 AND (Q.fstartdate <= {TS '"+nckdTbsjxmLastDay+"'}) AND (Q.fenddate >= {TS '"+nckdTbsjxmLastDay+"'}) " +
                " AND F.fisprimary = '1' AND (Q.FId IS NOT NULL) AND Q.forgid IN ("+orgIdStr+") AND F.fpostypeid = '1010'" +
                " ORDER BY Q.fstartdate DESC  ";
        logger.info("花名册查询在职人员："+ksql_zz);
        DataSet dataSet_zz = DB.queryDataSet(this.getClass().getName(), DBRoute.of("hr"), ksql_zz);
        Iterator<Row> iterator_zz = dataSet_zz.iterator();
        int zgUserCount = 0;// 在岗职工
        int lwUserCount = 0;// 劳务工
        int nmgUserCount = 0;// 农民工
        int lwpqUserCount = 0;// 劳务派遣
        int txfpUserCount = 0;// 退休返聘
        int qtUserCount = 0;// 其他
        while (iterator_zz.hasNext()) {
            Row row = iterator_zz.next();
            String pfnumber = row.getString("pfnumber");// 所属公司编码
            String mfnumber = row.getString("mfnumber");// 用工关系类型
            if ("1010_S".equals(mfnumber)) {// 劳动合同
                zgUserCount ++;
            } else if ("1030_S".equals(mfnumber)) {// 劳务派遣
                if (pfnumber.equals(nckd_jhgsbm) || pfnumber.equals(nckd_fdgsbm)) {// 晶昊盐化有限公司编码 或 富达有限公司编码
                    zgUserCount ++;
                } else {
                    lwUserCount ++;
                }
            } else if ("1040_S".equals(mfnumber)) {// 劳务协议（离岗退养返聘）
                lwpqUserCount ++;
            } else if ("1070_S".equals(mfnumber)) {// 劳务协议（退休返聘）
                txfpUserCount ++;
            } else {// 其他
                qtUserCount ++;
            }
        }
        Map<String,  Integer> result = new HashMap<String,  Integer>();
        result.put("zgUserCount", zgUserCount);
        result.put("lwUserCount", lwUserCount);
        result.put("nmgUserCount", nmgUserCount);
        result.put("lwpqUserCount", lwpqUserCount);
        result.put("txfpUserCount", txfpUserCount);
        result.put("qtUserCount", qtUserCount);
        logger.info("花名册查询在职人员结果："+result);
        return result;
    }

    /**
     * 获取当年小于指定日期的所有月份最后一天的年月日
     * @param nckd_tbsjny 指定的日期字符串
     * @return 包含所有符合条件的年月日的列表
     */
    public List<LocalDate> getLastDaysOfPreviousMonths(String nckd_tbsjny) {
        // 解析输入日期
        LocalDate targetDate = LocalDate.parse(nckd_tbsjny);
        int targetYear = targetDate.getYear();
        int targetMonth = targetDate.getMonthValue();
        List<LocalDate> result = new ArrayList<>();
        // 遍历当年小于目标月份的所有月份
        for (int month = 1; month <= targetMonth; month++) {
            // 获取当前月份的最后一天
            YearMonth yearMonth = YearMonth.of(targetYear, month);
            LocalDate lastDay = yearMonth.atEndOfMonth();
            // 格式化输出
            result.add(lastDay);
        }
        return result;
    }

    public Map<String,  Integer> findLiZhiHuaMingCe(LocalDate nckdTbsjxmLastDay,LocalDate nckdTbsjxmFirstDay, String orgIdStr,String nckd_bdlzfz, String nckd_qtlzfz) {
        int txlzUserCount = 0;
        int jchtlzUserCount = 0;
        int khbhglzUserCount = 0;
        int swlzUserCount = 0;
        int qtlzUserCount = 0;

        // 花名册查询离职人员
        String ksql_lz = " SELECT P.FPERSONID AS pfpersonid FROM t_hrpi_ermanfile P LEFT OUTER JOIN t_hrpi_employee F " +
                " ON P.femployeeid = F.fboid AND F.fiscurrentversion = '0' " +
                " AND F.fdatastatus IN ('0', '1', '2') AND F.fiscurrentversion = '0' AND F.fdatastatus IN ('0', '1', '2')" +
                " AND (F.fbsed <= {TS '"+nckdTbsjxmLastDay+"'}) AND (F.fbsled >= {TS '"+nckdTbsjxmFirstDay+"'}) " +
                " LEFT OUTER JOIN t_hbss_laborrelstatus A ON F.flaborrelstatus = A.FId " +
                " LEFT OUTER JOIN t_hrpi_erfiletype B ON P.ffiletypeid = B.FId WHERE 1 = 1 AND P.fiscurrentversion = '1' AND P.fdatastatus = '1' " +
                " AND (P.fpersonid != 0) AND (P.femployeeid != 0) AND (P.fdepempid != 0) AND P.finitstatus = '2' AND A.flabrelstatusprdid = 1020" +
                " AND B.ferfiletypeassignid = 1030 AND (F.fenddate >= {TS '"+nckdTbsjxmFirstDay+"'}) AND (F.fenddate <= {TS '"+nckdTbsjxmLastDay+"'}) " +
                " AND (P.FId IS NOT NULL) AND (P.FId IS NOT NULL) AND P.forgid IN ("+orgIdStr+") " +
                " ORDER BY P.fstartdate DESC ";
        logger.info("花名册查询离职人员："+ ksql_lz);
        DataSet dataSet_lz = DB.queryDataSet(this.getClass().getName(), DBRoute.of("hr"), ksql_lz);
        Iterator<Row> iterator_lz = dataSet_lz.iterator();
        List<String> personIds = new ArrayList<String>();
        while (iterator_lz.hasNext()) {
            Row row = iterator_lz.next();
            Long personId = row.getLong("pfpersonid");
            personIds.add(String.valueOf(personId));
        }
        if (personIds.size() > 0) {
            // 查询离职申请单
            String personIdsStr = String.join(",", personIds);
            String ksql_lzd = " SELECT A.FID as aid,C.FNAME as cfname,C.FNUMBER as cfnumber,C.FGROUPID AS cfgroupid FROM t_htm_quitapplybill A " +
                    " LEFT OUTER JOIN t_htm_quitapplybill_a B ON A.FID = B.FID" +
                    " LEFT OUTER JOIN t_htm_quittype C ON B.FQUITTYPEID = C.FID" +
                    " WHERE " +
                    " (B.FCONTRACTENDDATE >= {TS '" + nckdTbsjxmFirstDay + "'}) AND (B.FCONTRACTENDDATE <= {TS '" + nckdTbsjxmLastDay + "'}) " +
                    " AND A.FPERSONID IN (" + personIdsStr + ") ";
            logger.info("查询离职申请单：" + ksql_lzd);
            DataSet dataSet_lzd = DB.queryDataSet(this.getClass().getName(), DBRoute.of("hr"), ksql_lzd);
            Iterator<Row> iterator_lzd = dataSet_lzd.iterator();
            while (iterator_lzd.hasNext()) {
                Row row = iterator_lzd.next();
                String cfnumber = row.getString("cfnumber");
                String cfgroupid = row.getString("cfgroupid");
                if (nckd_bdlzfz.equals(cfgroupid)) {// 被动离职分组
                    jchtlzUserCount++;
                    if ("1090_S".equals(cfnumber)) { // 考核不合格离职
                        khbhglzUserCount++;
                    }
                } else if (nckd_qtlzfz.equals(cfgroupid)) {// 其他离职分组
                    swlzUserCount++;
                } else { // 主动离职分组
                    if ("1050_S".equals(cfnumber)) { // 退休离职
                        txlzUserCount++;
                    } else { // 其他离职
                        qtlzUserCount++;
                    }
                }
            }
        }
        Map<String,  Integer> result = new HashMap<>();
        result.put("txlzUserCount", txlzUserCount);
        result.put("jchtlzUserCount", jchtlzUserCount);
        result.put("khbhglzUserCount", khbhglzUserCount);
        result.put("swlzUserCount", swlzUserCount);
        result.put("qtlzUserCount", qtlzUserCount);
        logger.info("花名册查询离职人员结果：" + result);
        return result;
    }

}
