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

import com.engine.salary.constant.TaxDeclarationDataIndexConstant;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.entity.taxdeclaration.dto.TaxDeclarationAnnualListDTO;
import com.engine.salary.entity.taxdeclaration.dto.TaxDeclarationEmployeeDTO;
import com.engine.salary.entity.taxdeclaration.dto.TaxDeclarationLaborListDTO;
import com.engine.salary.entity.taxdeclaration.dto.TaxDeclarationWageListDTO;
import com.engine.salary.entity.taxdeclaration.po.TaxDeclarationDetailPO;
import com.engine.salary.enums.salaryaccounting.EmployeeTypeEnum;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import weaver.general.Util;

import java.util.*;

/**
 * 个税申报表详情
 * <p>Copyright: Copyright (c) 2022</p>
 * <p>Company: 泛微软件</p>
 *
 * @author qiantao
 * @version 1.0
 **/
public class TaxDeclarationDetailBO {

    /**
     * 转换成个税申报表详情列表（正常工资薪金所得）
     *
     * @param taxDeclarationDetailPOS
     * @param simpleEmployees
     * @return
     */
    public static List<TaxDeclarationWageListDTO> convert2ListDTO4Wage(List<TaxDeclarationDetailPO> taxDeclarationDetailPOS,
                                                                       List<TaxDeclarationEmployeeDTO> taxDeclarationEmployeeDTOS,
                                                                       List<DataCollectionEmployee> simpleEmployees) {
        if (CollectionUtils.isEmpty(taxDeclarationDetailPOS)) {
            return Collections.emptyList();
        }
        List<TaxDeclarationWageListDTO> taxDeclarationWageListDTOS = Lists.newArrayListWithExpectedSize(taxDeclarationEmployeeDTOS.size());
        Map<String, List<TaxDeclarationDetailPO>> employeeIdKeyTaxDeclarationDetailPOMap = SalaryEntityUtil.group2Map(taxDeclarationDetailPOS,
                taxDeclarationDetailPO -> EmployeeTypeEnum.ORGANIZATION.getValue() + "_" + taxDeclarationDetailPO.getEmployeeId());
        Map<Long, DataCollectionEmployee> simpleEmployeeMap = SalaryEntityUtil.convert2Map(simpleEmployees, DataCollectionEmployee::getEmployeeId);
        for (TaxDeclarationEmployeeDTO dto : taxDeclarationEmployeeDTOS) {
            Map<String, String> fieldCodeKeyFieldValueMap = SalaryEntityUtil.convert2Map(employeeIdKeyTaxDeclarationDetailPOMap.get(dto.getEmployeeType() + "_" + dto.getEmployeeId()),
                    TaxDeclarationDetailPO::getFieldCode, TaxDeclarationDetailPO::getFieldValue);
            TaxDeclarationWageListDTO taxDeclarationWageListDTO = TaxDeclarationWageListDTO.builder()
                    .cardType(SalaryI18nUtil.getI18nLabel(105564, "居民身份证"))
                    .income(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.INCOME))
                    .taxFreeIncome(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.TAX_FREE_INCOME))
                    .endowmentInsurance(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.ENDOWMENT_INSURANCE))
                    .medicalInsurance(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.MEDICAL_INSURANCE))
                    .unemploymentInsurance(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.UNEMPLOYMENT_INSURANCE))
                    .housingProvidentFund(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.HOUSING_PROVIDENT_FUND))
                    .addUpChildEducation(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.ADD_UP_CHILD_EDUCATION))
                    .addUpHousingLoanInterest(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.ADD_UP_HOUSING_LOAN_INTEREST))
                    .addUpHousingRent(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.ADD_UP_HOUSING_RENT))
                    .addUpContinuingEducation(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.ADD_UP_CONTINUING_EDUCATION))
                    .addUpSupportElderly(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.ADD_UP_SUPPORT_ELDERLY))
                    .addUpIllnessMedical(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.ADD_UP_ILLNESS_MEDICAL))
                    .addUpInfantCare(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.ADD_UP_INFANT_CARE))
                    .addUpPrivatePension(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.ADD_UP_PRIVATE_PENSION))
                    .annuity(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.ANNUITY))
                    .commercialHealthInsurance(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.COMMERCIAL_HEALTH_INSURANCE))
                    .taxDeferredEndowmentInsurance(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.TAX_DEFERRED_ENDOWMENT_INSURANCE))
                    .other(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.OTHER))
                    .allowedDonation(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.ALLOWED_DONATION))
                    .taxDeduction(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.TAX_DEDUCTION))
                    .description(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.DESCRIPTION)).build();
            if (dto.getEmployeeType() == null || Objects.equals(dto.getEmployeeType(), EmployeeTypeEnum.ORGANIZATION.getValue())) {
                DataCollectionEmployee simpleEmployee = simpleEmployeeMap.get(dto.getEmployeeId());
                taxDeclarationWageListDTO.setId(simpleEmployee.getEmployeeId())
                        .setEmployeeId(simpleEmployee.getEmployeeId())
                        .setJobNum(simpleEmployee.getWorkcode())
                        .setUsername(simpleEmployee.getUsername())
                        .setCardNum(Optional.ofNullable(simpleEmployee).map(DataCollectionEmployee::getIdNo).orElse(StringUtils.EMPTY));
            } else {
//                ExtEmployeePO extEmployeePO = extEmployeePOMap.get(dto.getEmployeeId());
//                taxDeclarationWageListDTO.setId(extEmployeePO.getId())
//                        .setEmployeeId(extEmployeePO.getId())
//                        .setJobNum(StringUtils.EMPTY)
//                        .setUsername(extEmployeePO.getUsername())
//                        .setCardNum(extEmployeePO.getCardNum());
            }
            taxDeclarationWageListDTOS.add(taxDeclarationWageListDTO);
        }
        return taxDeclarationWageListDTOS;
    }

    /**
     * 转换成个税申报表详情列表（劳务报酬所得）
     *
     * @param taxDeclarationDetailPOS
     * @param simpleEmployees
     * @return
     */
    public static List<TaxDeclarationLaborListDTO> convert2ListDTO4Labor(List<TaxDeclarationDetailPO> taxDeclarationDetailPOS,
                                                                         List<TaxDeclarationEmployeeDTO> taxDeclarationEmployeeDTOS,
                                                                         List<DataCollectionEmployee> simpleEmployees) {
        if (CollectionUtils.isEmpty(taxDeclarationDetailPOS)) {
            return Collections.emptyList();
        }
        List<TaxDeclarationLaborListDTO> taxDeclarationLaborListDTOS = Lists.newArrayListWithExpectedSize(taxDeclarationEmployeeDTOS.size());
        Map<String, List<TaxDeclarationDetailPO>> employeeIdKeyTaxDeclarationDetailPOMap = SalaryEntityUtil.group2Map(taxDeclarationDetailPOS,
                taxDeclarationDetailPO -> taxDeclarationDetailPO.getEmployeeType() + "_" + taxDeclarationDetailPO.getEmployeeId());
        Map<Long, DataCollectionEmployee> simpleEmployeeMap = SalaryEntityUtil.convert2Map(simpleEmployees, DataCollectionEmployee::getEmployeeId);
        for (TaxDeclarationEmployeeDTO dto : taxDeclarationEmployeeDTOS) {
            Map<String, String> fieldCodeKeyFieldValueMap = SalaryEntityUtil.convert2Map(employeeIdKeyTaxDeclarationDetailPOMap.get(dto.getEmployeeType() + "_" + dto.getEmployeeId()),
                    TaxDeclarationDetailPO::getFieldCode, TaxDeclarationDetailPO::getFieldValue);
            TaxDeclarationLaborListDTO taxDeclarationLaborListDTO = new TaxDeclarationLaborListDTO()
                    .setId(dto.getEmployeeId())
                    .setEmployeeId(dto.getEmployeeId())
                    .setCardType(SalaryI18nUtil.getI18nLabel(105564, "居民身份证"))
                    .setIncomeItems(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.INCOME_ITEMS))
                    .setLaborIncome(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.LABOR_INCOME))
                    .setLaborTaxFreeIncome(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.LABOR_TAX_FREE_INCOME))
                    .setCommercialHealthInsurance(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.COMMERCIAL_HEALTH_INSURANCE))
                    .setTaxDeferredEndowmentInsurance(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.TAX_DEFERRED_ENDOWMENT_INSURANCE))
                    .setOther(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.OTHER))
                    .setAllowedDonation(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.ALLOWED_DONATION))
                    .setTaxDeduction(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.TAX_DEDUCTION))
                    .setDescription(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.DESCRIPTION));
            if (dto.getEmployeeType() == null || Objects.equals(dto.getEmployeeType(), EmployeeTypeEnum.ORGANIZATION.getValue())) {
                DataCollectionEmployee simpleEmployee = simpleEmployeeMap.get(dto.getEmployeeId());
                taxDeclarationLaborListDTO.setJobNum(simpleEmployee.getWorkcode())
                        .setUsername(simpleEmployee.getUsername())
                        .setCardNum(Optional.ofNullable(simpleEmployee).map(DataCollectionEmployee::getIdNo).orElse(StringUtils.EMPTY));
            } else {

            }
            taxDeclarationLaborListDTOS.add(taxDeclarationLaborListDTO);
        }
        return taxDeclarationLaborListDTOS;
    }

    /**
     * 转换成个税申报表详情列表（年终奖）
     *
     * @param taxDeclarationDetailPOS
     * @param simpleEmployees
     * @return
     */
    public static List<TaxDeclarationAnnualListDTO> convert2ListDTO4Annual(List<TaxDeclarationDetailPO> taxDeclarationDetailPOS,
                                                                          List<TaxDeclarationEmployeeDTO> taxDeclarationEmployeeDTOS,
                                                                          List<DataCollectionEmployee> simpleEmployees) {
        if (CollectionUtils.isEmpty(taxDeclarationDetailPOS)) {
            return Collections.emptyList();
        }
        List<TaxDeclarationAnnualListDTO> taxDeclarationLaborListDTOS = Lists.newArrayListWithExpectedSize(taxDeclarationEmployeeDTOS.size());
        Map<String, List<TaxDeclarationDetailPO>> employeeIdKeyTaxDeclarationDetailPOMap = SalaryEntityUtil.group2Map(taxDeclarationDetailPOS,
                taxDeclarationDetailPO -> taxDeclarationDetailPO.getEmployeeType() + "_" + taxDeclarationDetailPO.getEmployeeId());
        Map<Long, DataCollectionEmployee> simpleEmployeeMap = SalaryEntityUtil.convert2Map(simpleEmployees, DataCollectionEmployee::getEmployeeId);
        for (TaxDeclarationEmployeeDTO dto : taxDeclarationEmployeeDTOS) {
            Map<String, String> fieldCodeKeyFieldValueMap = SalaryEntityUtil.convert2Map(employeeIdKeyTaxDeclarationDetailPOMap.get(dto.getEmployeeType() + "_" + dto.getEmployeeId()),
                    TaxDeclarationDetailPO::getFieldCode, TaxDeclarationDetailPO::getFieldValue);
            TaxDeclarationAnnualListDTO taxDeclarationLaborListDTO = new TaxDeclarationAnnualListDTO()
                    .setId(dto.getEmployeeId())
                    .setEmployeeId(dto.getEmployeeId())
                    .setCardType(SalaryI18nUtil.getI18nLabel(105564, "居民身份证"))
                    .setAnnualIncome(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.ANNUAL_INCOME))
                    .setAnnualTaxFreeIncome(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.ANNUAL_TAX_FREE_INCOME))
                    .setAnnualOther(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.ANNUAL_OTHER))
                    .setAnnualDonateTax(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.ANNUAL_DONATE_TAX))
                    .setAnnualTaxSavings(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.ANNUAL_TAX_SAVINGS))
                    .setAnnualRemark(fieldCodeKeyFieldValueMap.get(TaxDeclarationDataIndexConstant.ANNUAL_REMARK));
            if (dto.getEmployeeType() == null || Objects.equals(dto.getEmployeeType(), EmployeeTypeEnum.ORGANIZATION.getValue())) {
                DataCollectionEmployee simpleEmployee = simpleEmployeeMap.getOrDefault(dto.getEmployeeId(),new DataCollectionEmployee());
                taxDeclarationLaborListDTO.setJobNum(Util.null2String(simpleEmployee.getWorkcode()))
                        .setUsername(Util.null2String(simpleEmployee.getUsername()))
                        .setCardNum(Optional.ofNullable(simpleEmployee).map(DataCollectionEmployee::getIdNo).orElse(StringUtils.EMPTY));
            } else {

            }
            taxDeclarationLaborListDTOS.add(taxDeclarationLaborListDTO);
        }
        return taxDeclarationLaborListDTOS;
    }
}
