package nckd.jxccl.sit.hcsi.rptdata;

import kd.bos.algo.DataSet;
import kd.bos.algo.GroupbyDataSet;
import kd.bos.algo.JoinDataSet;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.report.AbstractReportListDataPlugin;
import kd.bos.entity.report.FilterInfo;
import kd.bos.entity.report.ReportQueryParam;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
import kd.sdk.plugin.Plugin;
import nckd.jxccl.sit.hcsi.utils.ReportUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * Tyx 2025-10-22
 * 社保明细差异对比表取数插件 nckd_detailcomparerpt
 */
public class DetailCompareReportDataPlugin extends AbstractReportListDataPlugin implements Plugin {

    private static final Log logger = LogFactory.getLog(DetailCompareReportDataPlugin.class);
    private static final String SINSURTASK = "hcsi_sinsurtask";
    private static final String CALPERSON = "hcsi_calperson";
    private static final String SINSURIMPTASK = "nckd_sinsurimptask";
    private static final String SINSURTEMPDATA = "nckd_sinsurtempdata";


    /**
     * 查询数据：
     * 1、先根据期间+参保单位获取到社保计算任务 【hcsi_sinsurtask】
     * 2、根据社保计算任务获取到计算人员及明细 【hcsi_calperson】
     * 3、根据期间+参保单位获取到外部系统导入任务和外部系统中间表数据 【nckd_sinsurimptask】和【nckd_sinsurtempdata】
     * @param reportQueryParam
     * @param o
     * @return
     * @throws Throwable
     */
    @Override
    public DataSet query(ReportQueryParam reportQueryParam, Object o) throws Throwable {
        logger.info("-------- begin query data --------");
        // 社保计算任务过滤条件
        QFilter taskFilter = buildTaskFilter(reportQueryParam);
        // 查找社保计算任务
        DynamicObjectCollection taskCols = queryDynamicObjectCollection(taskFilter, SINSURTASK, "id");
        // 获取所有计算任务Id
        List<Long> taskIds = taskCols.stream().map(obj -> obj.getLong("id")).collect(Collectors.toList());
        // 根据计算任务Id+险种获取到计算结果明细数据
        DataSet calPersonDataSet = queryCalPersonDetail(reportQueryParam, taskIds);
        // 按照个人和单位分组汇总 type = 1为个人，type = 2为单位，这里仅为系统内数据
        DataSet groupDataSet = groupCalPersonDetail(calPersonDataSet);
        // 再关联外部数据导入
        DataSet outsidePersonDetail = ReportUtils.queryOutsidePersonDetail(reportQueryParam);
        // 按照个人和单位分组汇总 type = 1为个人，type = 2为单位，这里仅为系统内数据
        DataSet groupDataSetOut = groupCalPersonDetailOut(outsidePersonDetail);

        // 再join
        String[] leftFields = new String[]{"welfarepayer", "welfaretypeid", "empnumber", "empname", "empidcard", "type", "personSysValue", "companySysValue"};
        String[] rightFields =  new String[]{"personOutValue", "companyOutValue"};
        DataSet finalDataSet = groupDataSet.join(groupDataSetOut).on("welfarepayer", "welfarepayer").on("welfaretypeid", "welfaretypeid").
                on("empnumber", "empnumber").on("empname", "empname").
                on("empidcard", "empidcard").select(leftFields, rightFields).finish();
        return finalDataSet;
    }

    public DataSet queryDataSet(ReportQueryParam reportQueryParam, QFilter filter, String entityName, String selectFields) {
        HRBaseServiceHelper helper = new HRBaseServiceHelper(entityName);
        DataSet dataSet = helper.queryDataSet("AttendanceRateReportQuery-Absent", selectFields, new QFilter[]{filter});
        return dataSet;
    }

    public DynamicObjectCollection queryDynamicObjectCollection(QFilter filter, String entityName, String selectFields) {
        HRBaseServiceHelper helper = new HRBaseServiceHelper(entityName);
        DynamicObjectCollection cols = helper.queryOriginalCollection(selectFields, new QFilter[]{filter});
        return cols;
    }

    /**
     * 查询计算详情
     * @param reportQueryParam
     * @param taskIds
     */
    public DataSet queryCalPersonDetail(ReportQueryParam reportQueryParam, List<Long> taskIds) {
        FilterInfo filterInfo = reportQueryParam.getFilter();
        // 险种
        DynamicObjectCollection welfareTypeCols = (DynamicObjectCollection)filterInfo.getFilterItem("nckd_welfaretype").getValue();
        List<Long> welfareTypeIds = welfareTypeCols.stream().map(obj -> obj.getLong("id")).collect(Collectors.toList());
        return ReportUtils.queryCalPersonDetail(welfareTypeIds, taskIds);
    }

    /**
     * 分组汇总人员明细
     * @param calPersonDataSet
     * @return
     */
    public DataSet groupCalPersonDetail (DataSet calPersonDataSet) {
        calPersonDataSet.groupBy(new String[]{"welfarepayer","welfaretypeid","empnumber","empname","empidcard","type"}).sum("value");
        DataSet dataSet1 = calPersonDataSet.copy();
        DataSet dataSet2 = calPersonDataSet.copy();

        // 按照类型分组汇总
        DataSet sumSet1 = dataSet1.filter("type = '1'").groupBy(new String[]{"welfarepayer", "welfaretypeid", "empnumber", "empname", "empidcard", "type"}).sum("value").finish();
        DataSet sumSet2 = dataSet2.filter("type = '2'").groupBy(new String[]{"welfarepayer","welfaretypeid","empnumber","empname","empidcard","type"}).sum("value").finish();

        // join
        JoinDataSet joinDataSet = sumSet1.join(sumSet2).on("welfarepayer", "welfarepayer").on("welfaretypeid", "welfaretypeid").on("empnumber", "empnumber").on("empname", "empname").on("empidcard", "empidcard");
        DataSet dataSet = joinDataSet.select(new String[]{"welfarepayer", "welfaretypeid", "empnumber", "empname", "empidcard", "type", "value as personSysValue"}, new String[]{"value as companySysValue"}).finish();

        return dataSet;
    }

    public DataSet groupCalPersonDetailOut (DataSet calPersonDataSet) {
        calPersonDataSet.groupBy(new String[]{"welfarepayer","welfaretypeid","empnumber","empname","empidcard","type"}).sum("value");
        DataSet dataSet1 = calPersonDataSet.copy();
        DataSet dataSet2 = calPersonDataSet.copy();

        // 按照类型分组汇总
        DataSet sumSet1 = dataSet1.filter("type = '1'").groupBy(new String[]{"welfarepayer", "welfaretypeid", "empnumber", "empname", "empidcard", "type"}).sum("value").finish();
        DataSet sumSet2 = dataSet2.filter("type = '2'").groupBy(new String[]{"welfarepayer","welfaretypeid","empnumber","empname","empidcard","type"}).sum("value").finish();

        // join
        JoinDataSet joinDataSet = sumSet1.join(sumSet2).on("welfarepayer", "welfarepayer").on("welfaretypeid", "welfaretypeid").on("empnumber", "empnumber").on("empname", "empname").on("empidcard", "empidcard");
        DataSet dataSet = joinDataSet.select(new String[]{"welfarepayer", "welfaretypeid", "empnumber", "empname", "empidcard", "type", "value as personOutValue"}, new String[]{"value as companyOutValue"}).finish();

        return dataSet;
    }

    /**
     * 构建查询条件
     * @param reportQueryParam
     * @return
     */
    private QFilter buildTaskFilter(ReportQueryParam reportQueryParam) {
        FilterInfo filterInfo = reportQueryParam.getFilter();
        // 社保期间
        DynamicObject period = (DynamicObject)filterInfo.getFilterItem("nckd_period").getValue();
        // 参保单位
        DynamicObject welfarepayer = (DynamicObject)filterInfo.getFilterItem("nckd_welfarepayer").getValue();
        QFilter filter = new QFilter("sinsurperiod.id", QCP.equals, period.getPkValue());
        filter.and("welfarepayer.id", QCP.equals, welfarepayer.getPkValue());
        return filter;
    }
}