package nckd.jxccl.swc.init.business;

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.db.DB;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import nckd.jxccl.base.common.constant.FormConstant;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 员工信息维护（社保专用）列表界面提供一个功能按钮，可以进行即时计算，
 * 后台提供定时任务（每年12月31日24点执行一次），当年度待遇根据上年度12月31日的人员状态和记录计算补助待遇，
 * 按照年度生成多行记录，记录历史。当专员手动执行前端更新按钮时（需选中人员），
 * 系统需根据手动的当前时间获取人员状态和记录计算补助待遇，包括对当前记录进行更新，
 * 新增人员待遇记录生成。（离职人员不做处理）
 * 金额调整
 * 2400--->4800
 * 1800--->3600
 * 1200--->2400
 * 840--->1800
 * @author: turborao
 * @date: 2025/10/27 13:05
 */
public class BaseMedicalAllowanceServiceImpl implements BaseMedicalAllowanceService{

    private static final Log logger = LogFactory.getLog(BaseMedicalAllowanceServiceImpl.class);
    public Map<String, String> calcBaseMedicalAllowanceForAll() {

        //取员工档案
        QFilter filter1 = new QFilter("iscurrentversion", QCP.equals, true); // 启用
        QFilter filter2 = new QFilter("datastatus", QCP.equals, "1"); // 启用

        String selectFields="id,employee.id,employee.number,nckd_benefitentry.nckd_effeyear,nckd_benefitentry.nckd_suppbenefit";
        DynamicObject[] datas = BusinessDataServiceHelper.load(FormConstant.HCSI_SINSURFILE, selectFields, new QFilter[]{filter1.and(filter2)});

        Map<String, String> result = calcBaseMedicalAllowance(datas, true);

        return result;
    }

    public Map<String, String> calcBaseMedicalAllowanceForPersons(List<Long> billIds) {

        //取员工档案
        QFilter filter1 = new QFilter("iscurrentversion", QCP.equals, true); // 启用
        QFilter filter2 = new QFilter("datastatus", QCP.equals, "1"); // 启用
        QFilter filter3 = new QFilter("id", QCP.in, billIds); // 启用

        String selectFields="id,employee.id,employee.number,nckd_benefitentry.nckd_effeyear,nckd_benefitentry.nckd_suppbenefit";
        DynamicObject[] datas = BusinessDataServiceHelper.load(FormConstant.HCSI_SINSURFILE, selectFields, new QFilter[]{filter1.and(filter2).and(filter3)});

        Map<String, String> result = calcBaseMedicalAllowance(datas,false);

        return result;

    }


    public Map<String, String> calcBaseMedicalAllowance(DynamicObject[] datas, boolean isAll) {

        // 获取当前日期
        LocalDate currentDate = LocalDate.now();

        // 获取上一年的年份
        //int previousYear = currentDate.minusYears(1).getYear();
        int previousYear = currentDate.getYear();

        Map<Long, DynamicObject> employeeFileMaps = Arrays.stream(datas).collect(
                Collectors.toMap(
                        obj -> obj.getLong("employee.id"),
                        obj -> obj,
                        (k1, k2) -> k1
                )
        );
        //将Map转换为List
        List<Long> employeeIDs = employeeFileMaps.keySet().stream().collect(Collectors.toList());
        ArrayList<DynamicObject> dynList = new ArrayList<>();
        /***
         * 获取员工基本信息
         */
        QFilter qFilter1 = new QFilter("id",QCP.in, employeeIDs);
        QFilter qFilter11 = new QFilter("iscurrentversion", QCP.equals, true); // 启用
        QFilter qFilter12 = new QFilter("datastatus", QCP.equals, "1"); // 启用
        DataSet employeeDS = QueryServiceHelper.queryDataSet(this.getClass().getName(),FormConstant.HRPI_EMPLOYEE, "id,number,name", new QFilter[]{qFilter1,qFilter11,qFilter12},null);
        employeeDS.print(true);
        /***
         * 获取员工档案 任职经历  岗位
         */
        QFilter qFilter2 = new QFilter("employee.id",QCP.in, employeeIDs);
        QFilter qFilter21 = new QFilter("iscurrentdata", QCP.equals, true); // 启用
        QFilter qFilter22 = new QFilter("isprimary", QCP.equals, "1");  //主任职
        QFilter qFilter23 = new QFilter("postype.id", QCP.equals, 1010L); //主任职
        DataSet empOrgRelDS = QueryServiceHelper.queryDataSet(this.getClass().getName(),FormConstant.HRPI_EMPPOSORGREL, "id,employee.id,company.id,company.name,position.id,position.number,position.name,adminorg.number", new QFilter[]{qFilter2,qFilter21,qFilter22,qFilter23},null);
        empOrgRelDS.print(true);
        /***
         * 获取员工档案 雇佣信息  用工关系状态
         */
        QFilter qFilter3 = new QFilter("employee.id",QCP.in, employeeIDs);
        QFilter qFilter31 = new QFilter("iscurrentdata", QCP.equals, true); // 启用
        QFilter qFilter32 = new QFilter("ishired", QCP.equals, "1"); // 是否在职
        DataSet empentrelDS = QueryServiceHelper.queryDataSet(this.getClass().getName(),FormConstant.HRPI_EMPENTREL, "id,employee.id,laborrelstatus.number", new QFilter[]{qFilter3,qFilter31,qFilter32},null);

        /***
         * 获取员工档案 党政职务  职务级别
         */
        QFilter qFilter4 = new QFilter("employee.id",QCP.in, employeeIDs);
        QFilter qFilter41 = new QFilter("iscurrentdata", QCP.equals, true); // 启用
        DataSet posgradeDS = QueryServiceHelper.queryDataSet(this.getClass().getName(), FormConstant.NCKD_HRPI_PARTYPOSH, "id,employee.id,nckd_posgrade.number", new QFilter[]{qFilter4,qFilter41},null);

        /***
         * 获取员工档案 职称信息 职称级别  hrpi_perprotitle
         */
        QFilter qFilter5 = new QFilter("employee.id",QCP.in, employeeIDs);
        QFilter qFilter51 = new QFilter("ishigh", QCP.equals, "1"); // 启用
        DataSet perprotitleDS = QueryServiceHelper.queryDataSet(this.getClass().getName(),FormConstant.HRPI_PERPROTITLE, "id,employee.id,prolevel.number", new QFilter[]{qFilter5,qFilter51},null);

        /***
         * 获取员工档案 职业资格 职业资格等级  hrpi_perocpqual
         */
        QFilter qFilter6 = new QFilter("employee.id",QCP.in, employeeIDs);
        QFilter qFilter61 = new QFilter("ismajor", QCP.equals, "1"); // 启用
        DataSet perocpqualeDS = QueryServiceHelper.queryDataSet(this.getClass().getName(),FormConstant.HRPI_PEROCPQUAL, "id,employee.id,qualevel.number", new QFilter[]{qFilter6,qFilter61},null);


        DataSet reDataset = null;
        reDataset = employeeDS.leftJoin(empOrgRelDS).on("id", "employee.id")
                .select(employeeDS.getRowMeta().getFieldNames(),new String[] {"company.id as compId","company.name as compName","position.id as positionId","position.number as positionNum","position.name as positionName","adminorg.number as adminorgNum"})
                .finish();
        reDataset.print(true);

        reDataset = reDataset.leftJoin(empentrelDS).on("id", "employee.id")
                .select(reDataset.getRowMeta().getFieldNames(),new String[] {"laborrelstatus.number as laborrelstatusNum"})
                .finish();
        reDataset.print(true);

        reDataset = reDataset.leftJoin(posgradeDS).on("id", "employee.id")
                .select(reDataset.getRowMeta().getFieldNames(),new String[] {"nckd_posgrade.number as posgradeNum"})
                .finish();
        reDataset.print(true);

        reDataset = reDataset.leftJoin(perprotitleDS).on("id", "employee.id")
                .select(reDataset.getRowMeta().getFieldNames(),new String[] {"prolevel.number as prolevelNum"})
                .finish();
        reDataset.print(true);

        reDataset = reDataset.leftJoin(perocpqualeDS).on("id", "employee.id")
                .select(reDataset.getRowMeta().getFieldNames(),new String[] {"qualevel.number as qualevelNum"})
                .finish();
        reDataset.print(true);

        Iterator<Row> iterator = reDataset.iterator();
        while (iterator.hasNext()) {
            Row row = iterator.next();
            DynamicObject employeeFile = employeeFileMaps.get(row.getLong("id"));
            String personNum = row.getString("number") == null ? "" : row.getString("number");
            String personName = row.getString("name") == null ? "" : row.getString("name");
            String adminorgNum = row.getString("adminorgNum") == null ? "" : row.getString("adminorgNum");
            String positionNum = row.getString("positionNum") == null ? "" : row.getString("positionNum");
            String positionName = row.getString("positionName") == null ? "" : row.getString("positionName");
            String posgradeNum = row.getString("posgradeNum")  == null ? "" : row.getString("posgradeNum");
            String laborrelstatusNum = row.getString("laborrelstatusNum") == null ? "" : row.getString("laborrelstatusNum");
            String prolevelNum = row.getString("prolevelNum") == null ? "" : row.getString("prolevelNum");
            String qualevelNum = row.getString("qualevelNum")  == null ? "" : row.getString("qualevelNum");

            if(!isAll) {
                logger.info("社保补助待遇标准计算（补充医疗保险） 员工编号：{}, 员工姓名：{}, 部门：{}, 岗位：{}, 职务级别：{}, 职称级别：{}, 职业资格等级：{}, 用工关系状态：{}",
                        personNum, personName, adminorgNum, positionName, posgradeNum, prolevelNum, qualevelNum, laborrelstatusNum);
            }

            int money = 0;
            List<String> L4800 = Arrays.asList("1", "2");
            List<String> L3600 = Arrays.asList("3", "4", "5");
            List<String> L2400 = Arrays.asList("6", "7", "8", "9");
            List<String> prolevelHigeList = Arrays.asList("001", "011");
            List<String> prolevelMiddList = Arrays.asList("002", "010");
            /**
             * 公司领导班子成员：对应组织为集团本部-股份公司领导-公司领导和集团本部-集团公司领导在内的所有正式员工【4800/年】
             */
            if(laborrelstatusNum.equals("1010_S") && (adminorgNum.equals("01010201") || adminorgNum.equals("01010101"))){
                money = 4800;
            }
            /**
             * 监事会主席：对应职位编码为ZW01010377的正式员工 【4800/年】
             * 专职外部董事：对应职位编码为ZW01010173的正式员工 【4800/年】
             */
            else if (laborrelstatusNum.equals("1010_S")  && (positionNum.equals("ZW01010377") || positionNum.equals("ZW01010173"))) {
                money = 4800;
            }
            /**
             * 专职监事正副职：对应职位编码为ZW01010378和ZW01010379的正式员工【3600/年】
             */
            else if (laborrelstatusNum.equals("1010_S")  && (positionNum.equals("ZW01010378") || positionNum.equals("ZW01010379"))) {
                money = 3600;
            }
            /**
             * 职务级别为"厅级、副厅级"的正式员工 4800
             */
            else if (laborrelstatusNum.equals("1010_S")  &&  L4800.contains(posgradeNum) ) {
                money = 4800;
            }
            /**
             * 职务级别为"中层正职、中层副职、中层副职(托管)"的正式员工 3600
             */
            else if (laborrelstatusNum.equals("1010_S")  &&  L3600.contains(posgradeNum) ) {
                money = 3600;
            }
            /**
             * 已聘任正高级职称或特级技师：对应职称级别为正高级、正高级（虚拟）；技能等级为特级技师的正式员工 3600
             */
            else if (laborrelstatusNum.equals("1010_S")  && (prolevelHigeList.contains(prolevelNum)  ||  qualevelNum.equals("0"))) {
                money = 3600;
            }
            /**
             * 已聘任副高级职称或高级技师：对应职称级别为副高级、副高级（虚拟）；技能等级为高级技师的正式员工 2400
             */
            else if (laborrelstatusNum.equals("1010_S")  && (prolevelMiddList.contains(prolevelNum)  ||  qualevelNum.equals("1"))) {
                money = 2400;
            }
            /**
             * 职务级别为"基层正职、基层正职(托管)、基层副职、基层副职(托管)"的正式员工 2400
             */
            else if (laborrelstatusNum.equals("1010_S")  &&  L2400.contains(posgradeNum) ) {
                money = 2400;
            }
            /**
             * 协理员：职位名称包含“协理员”的所有正式员工 【2400/年】
             */
            else if (laborrelstatusNum.equals("1010_S")  &&  positionName.contains("协理员") ) {
                money = 2400;
            }
            /**
             * 职务级别为"其他"的正式员工 1800
             */
            else if (laborrelstatusNum.equals("1010_S")  &&  posgradeNum.equals("10") ) {
                money = 1800;
            }else if (laborrelstatusNum.equals("1010_S")) {
                money = 1800;
            }


            DynamicObjectCollection benefitEntrys = employeeFile.getDynamicObjectCollection("nckd_benefitentry");

            List<DynamicObject> currYearDyn =
                    benefitEntrys.stream().filter(e -> e.getInt("nckd_effeyear") == previousYear).collect(Collectors.toList());
            DynamicObject benefitEntry = null;
            if(currYearDyn.size() == 0){
                benefitEntry = benefitEntrys.addNew() ;
                Long entryid = DB.genGlobalLongId();
                benefitEntry.set("id", entryid);
            }else{
                benefitEntry = currYearDyn.get(0);
            }

            benefitEntry.set("nckd_effeyear", previousYear);
            benefitEntry.set("nckd_suppbenefit", money);

            dynList.add(employeeFile);
        }

        Map<String, String> result = new HashMap<>();
        int length = 0;
        if(dynList.size() == 0) {
            result.put("code", "200");
            result.put("msg", "当年度待遇标准计算（补充医疗保险），执行成功，但本次没有人员数据！" );
        }else{
            //保存
            Object[] update = SaveServiceHelper.save(dynList.toArray(new DynamicObject[0]));
            length = update.length;
            result.put("code", "200");
            result.put("msg", "当年度待遇标准计算（补充医疗保险），执行成功，本次计算人员数量" + length);
        }

        return result;
    }


}
