package com.engine.salary.entity.siarchives.bo;

import com.engine.salary.constant.SalaryDefaultTenantConstant;
import com.engine.salary.entity.siarchives.po.InsuranceArchivesBaseInfoPO;
import com.engine.salary.entity.taxagent.po.TaxAgentEmpChangePO;
import com.engine.salary.enums.siaccount.EmployeeStatusEnum;
import com.engine.salary.enums.taxagent.TaxAgentEmpChangeTypeEnum;
import com.engine.salary.util.SalaryEntityUtil;
import com.google.common.collect.Lists;
import com.engine.salary.util.db.IdGenerator;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.math.NumberUtils;

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

/**
 * @Author: sy
 * @Description: 社保福利档案基础信息
 * @Date: 2022/10/13
 **/
public class InsuranceArchivesBaseInfoBO {

    @Override
    public String toString() {
        return "InsuranceArchivesBaseInfoBO{}";
    }

    /**
     * 构建增量数据
     */
    public static InsuranceArchivesBaseInfoBO.ChangeData buildChangeData(List<TaxAgentEmpChangePO> taxAgentEmpChangeList, List<InsuranceArchivesBaseInfoPO> insuranceArchivesBaseInfoList, Long currentEmployeeId) {
        List<Long> changeIds = taxAgentEmpChangeList.stream().map(TaxAgentEmpChangePO::getId).collect(Collectors.toList());
        // 根据个税扣缴义务人和人员以及增量类型分组
        Map<String, Long> changeTypeMap = taxAgentEmpChangeList.stream().collect(Collectors.groupingBy(change -> change.getTaxAgentId() + "-" + change.getEmployeeId() + "-" + change.getChangeType(), Collectors.counting()));
        // 顺序倒转
        Collections.reverse(taxAgentEmpChangeList);
        // 去重
        taxAgentEmpChangeList = taxAgentEmpChangeList.stream()
                .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(f -> f.getTaxAgentId() + "-" + f.getEmployeeId()))), ArrayList::new));
        List<TaxAgentEmpChangePO> taxAgentEmpChanges = taxAgentEmpChangeList
                .stream()
                // 不相等则保留，否则忽略
                .filter(change -> !Objects.equals(changeTypeMap.get(change.getTaxAgentId() + "-" + change.getEmployeeId() + "-" + TaxAgentEmpChangeTypeEnum.ADD.getValue())
                        , changeTypeMap.get(change.getTaxAgentId() + "-" + change.getEmployeeId() + "-" + TaxAgentEmpChangeTypeEnum.DEL.getValue())))
                .collect(Collectors.toList());

        Date now = new Date();
        Date today = new Date();
        List<InsuranceArchivesBaseInfoPO> baseInfoAddTodoList = Lists.newArrayList();
        List<InsuranceArchivesBaseInfoPO> baseInfoUpdateTodoList = Lists.newArrayList();

        Map<String, InsuranceArchivesBaseInfoPO> insuranceArchivesBaseInfoListMap = SalaryEntityUtil.convert2Map(insuranceArchivesBaseInfoList, k -> k.getPaymentOrganization() + "-" + k.getEmployeeId());
        taxAgentEmpChanges.forEach(change -> {
//            //以人员id筛选出侧面比较的档案数据，避免存在当前个税扣缴义务人外的该人员档案数据
//            List<InsuranceArchivesBaseInfoPO> moreBaseInfos = insuranceArchivesBaseInfoList.stream().filter(f -> f.getEmployeeId().equals(change.getEmployeeId())).collect(Collectors.toList());
            //以个税扣缴义务人和人员id为条件筛选当前数据直接对比的档案数据
            InsuranceArchivesBaseInfoPO insuranceBaseInfo = insuranceArchivesBaseInfoListMap.get(change.getTaxAgentId() + "-" + change.getEmployeeId());
            // 如果是新增 说明：如果没有档案，则新增，如果有档案而且是停止缴纳，就转移到待增员中，以个税扣缴义务人和人员id判断唯一
            if (change.getChangeType() == TaxAgentEmpChangeTypeEnum.ADD.getValue()) {
                if (insuranceBaseInfo != null) {
                    // 停止缴纳->待增员
                    if (insuranceBaseInfo.getRunStatus().equals(EmployeeStatusEnum.STOP_PAYMENT_FROM_DEL.getValue()) || insuranceBaseInfo.getRunStatus().equals(EmployeeStatusEnum.STOP_PAYMENT_FROM_ADD.getValue())) {
                        insuranceBaseInfo.setRunStatus(EmployeeStatusEnum.STAY_ADD.getValue());
                        insuranceBaseInfo.setUpdateTime(now);
                        baseInfoUpdateTodoList.add(insuranceBaseInfo);
                    }
                } else {
                    //新增社保、公积金、其他福利档案
                    // 新增基础信息
                    baseInfoAddTodoList.add(InsuranceArchivesBaseInfoPO.builder()
                            .id(IdGenerator.generate())
                            .employeeId(change.getEmployeeId())
                            .paymentOrganization(change.getTaxAgentId())
                            .runStatus(EmployeeStatusEnum.STAY_ADD.getValue())
                            .createTime(now)
                            .updateTime(now)
                            .creator(currentEmployeeId)
                            .deleteType(NumberUtils.INTEGER_ZERO)
                            .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
                            .employeeType(change.getEmployeeType())
                            .build());
                }
                // 如果是删除 说明：如果有档案并且是在缴纳中才处理，没档案不用管
            } else if (change.getChangeType() == TaxAgentEmpChangeTypeEnum.DEL.getValue()) {
                if (insuranceBaseInfo != null) {
                    if (insuranceBaseInfo.getRunStatus().equals(EmployeeStatusEnum.PAYING.getValue())) {
                        // 正在缴纳->待减员
                        insuranceBaseInfo.setRunStatus(EmployeeStatusEnum.STAY_DEL.getValue());
                        insuranceBaseInfo.setUpdateTime(now);
                        baseInfoUpdateTodoList.add(insuranceBaseInfo);

                    } else if (insuranceBaseInfo.getRunStatus().equals(EmployeeStatusEnum.STAY_ADD.getValue())) {
                        // 待增员->逻辑删除
                        insuranceBaseInfo.setDeleteType(1);
                        insuranceBaseInfo.setUpdateTime(now);
                        baseInfoUpdateTodoList.add(insuranceBaseInfo);
                    }
                }
            }
        });

        return ChangeData.builder()
                .baseInfoAddTodoList(baseInfoAddTodoList)
                .baseInfoUpdateTodoList(baseInfoUpdateTodoList)
                .changeIds(changeIds)
                .build();
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class ChangeData {

        /**
         * 需要批量修改的福利档案基础信息
         */
        private List<InsuranceArchivesBaseInfoPO> baseInfoAddTodoList;

        /**
         * 需要批量新增的福利档案基础信息
         */
        private List<InsuranceArchivesBaseInfoPO> baseInfoUpdateTodoList;

        /**
         * 需要删除的增量数据
         */
        private List<Long> changeIds;
    }
}
