package com.engine.salary.wrapper;

import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.entity.salaryformula.ExpressFormula;
import com.engine.salary.entity.salaryitem.bo.SalaryItemBO;
import com.engine.salary.entity.salaryitem.po.SalaryItemPO;
import com.engine.salary.entity.salarysob.dto.SalarySobBackItemAggregateDTO;
import com.engine.salary.entity.salarysob.dto.SalarySobBackItemDTO;
import com.engine.salary.entity.salarysob.dto.SalarySobBackItemFormDTO;
import com.engine.salary.entity.salarysob.param.SalarySobBackItemSaveParam;
import com.engine.salary.entity.salarysob.po.SalarySobBackItemPO;
import com.engine.salary.enums.SalaryRoundingModeEnum;
import com.engine.salary.enums.SalaryValueTypeEnum;
import com.engine.salary.enums.salaryitem.SalaryDataTypeEnum;
import com.engine.salary.service.SalaryFormulaService;
import com.engine.salary.service.SalaryItemService;
import com.engine.salary.service.SalarySobBackItemService;
import com.engine.salary.service.SysSalaryItemService;
import com.engine.salary.service.impl.SalaryFormulaServiceImpl;
import com.engine.salary.service.impl.SalaryItemServiceImpl;
import com.engine.salary.service.impl.SalarySobBackItemServiceImpl;
import com.engine.salary.service.impl.SysSalaryItemServiceImpl;
import com.engine.salary.util.SalaryEntityUtil;
import com.wbi.util.Util;
import weaver.hrm.User;

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

/**
 * @author Harryxzy
 * @date 2022/11/15 15:56
 * @description 薪资账套的回算项目
 */
public class SalarySobBackItemWrapper extends Service {

    private SalarySobBackItemService getSalarySobBackItemService(User user) {
        return ServiceUtil.getService(SalarySobBackItemServiceImpl.class, user);
    }

    private SalaryItemService getSalaryItemService(User user) {
        return ServiceUtil.getService(SalaryItemServiceImpl.class, user);
    }

    private SalaryFormulaService getSalaryFormulaService(User user) {
        return ServiceUtil.getService(SalaryFormulaServiceImpl.class, user);
    }

    private SysSalaryItemService getSysSalaryItemService(User user) {
        return ServiceUtil.getService(SysSalaryItemServiceImpl.class, user);
    }

    /**
     * @description 查看详情
     * @return SalarySobBackItemAggregateDTO
     * @author Harryxzy
     * @date 2022/11/15 15:59
     */
    public SalarySobBackItemAggregateDTO getAggregate(Long salarySobId) {
        List<SalarySobBackItemPO> salarySobBackItemPOS = getSalarySobBackItemService(user).listBySalarySobId(salarySobId);
        // 查询薪资项目
        Set<Long> salaryItemIds = SalaryEntityUtil.properties(salarySobBackItemPOS, SalarySobBackItemPO::getSalaryItemId);
        List<SalaryItemPO> salaryItemPOS = getSalaryItemService(user).listByIds(salaryItemIds);
        Map<Long, SalaryItemPO> salaryItemMap = SalaryEntityUtil.convert2Map(salaryItemPOS, SalaryItemPO::getId);
        // 查询公式详情
        Set<Long> formulaIds = salarySobBackItemPOS.stream()
                .map(SalarySobBackItemPO::getFormulaId)
                .filter(formulaId -> !Objects.equals(formulaId, 0L))
                .collect(Collectors.toSet());
        List<ExpressFormula> expressFormulas = getSalaryFormulaService(user).listExpressFormula(formulaIds);
        Map<Long, String> expressFormulaContentMap = SalaryEntityUtil.convert2Map(expressFormulas, ExpressFormula::getId, ExpressFormula::getFormula);
        // 已发项目设置
        List<SalarySobBackItemAggregateDTO.SalarySobBackItemDTO> issuedItems = convert2DTO(salarySobBackItemPOS, salaryItemMap,
                expressFormulaContentMap, 0);
        // 补发项目设置
        List<SalarySobBackItemAggregateDTO.SalarySobBackItemDTO> reissueItems = convert2DTO(salarySobBackItemPOS, salaryItemMap,
                expressFormulaContentMap, 1);
        return SalarySobBackItemAggregateDTO.builder()
                .salarySobId(salarySobId)
                .issuedItems(issuedItems)
                .reissueItems(reissueItems).build();
    }

    private List<SalarySobBackItemAggregateDTO.SalarySobBackItemDTO> convert2DTO(List<SalarySobBackItemPO> salarySobBackItemPOS,
                                                                                 Map<Long, SalaryItemPO> salaryItemMap,
                                                                                 Map<Long, String> expressFormulaContentMap, Integer backCalcType) {
        return salarySobBackItemPOS.stream()
                .filter(salarySobBackItemPO -> Objects.equals(salarySobBackItemPO.getBackCalcType(), backCalcType))
                .map(salarySobBackItemPO -> {
                    SalaryItemPO salaryItemPO = salaryItemMap.get(salarySobBackItemPO.getSalaryItemId());
                    return SalarySobBackItemAggregateDTO.SalarySobBackItemDTO.builder()
                            .id(salarySobBackItemPO.getId())
                            .name(Optional.ofNullable(salaryItemPO).map(SalaryItemPO::getName).orElse(""))
                            .salaryItemId(salarySobBackItemPO.getSalaryItemId())
                            .formulaId(salarySobBackItemPO.getFormulaId())
                            .formulaContent(expressFormulaContentMap.getOrDefault(salarySobBackItemPO.getFormulaId(), "输入"))
                            .dataType(Optional.ofNullable(salaryItemPO).map(SalaryItemPO::getDataType).orElse(""))
                            .sortedIndex(0)
                            .canEdit(true)
                            .canDelete(false)
                            .backCalcType(Objects.equals(backCalcType,0) ? "issuedItems" :"reissueItems").build();
                }).collect(Collectors.toList());
    }


    public SalarySobBackItemFormDTO getForm(Long salarySobBackItemId) {
        // 查询薪资账套的薪资回算项目
        SalarySobBackItemPO salarySobBackItem = getSalarySobBackItemService(user).getById(salarySobBackItemId);
        // 查询薪资项目
        SalaryItemPO salaryItem = getSalaryItemService(user).getById(salarySobBackItem.getSalaryItemId());
        // 查询公式
        ExpressFormula expressFormula = getSalaryFormulaService(user).getExpressFormula(salarySobBackItem.getFormulaId());
        // 转换为dto

        HashMap<String, Object> map = new HashMap<>();
        map.put("id",Util.null2String(salaryItem.getId()));
        map.put("name",salaryItem.getName());
        SalarySobBackItemFormDTO salarySobBackItemFormDTO = SalarySobBackItemFormDTO.builder()
                .id(salarySobBackItem.getId())
                .salaryItem( Collections.singletonList(map))
                .dataType(SalaryDataTypeEnum.parseByValue(salaryItem.getDataType()))
                .roundingMode(SalaryRoundingModeEnum.parseByValue(salarySobBackItem.getRoundingMode()))
                .pattern(Util.null2String(salarySobBackItem.getPattern()))
                .valueType(SalaryValueTypeEnum.parseByValue(salarySobBackItem.getValueType()))
                .formulaId(salarySobBackItem.getFormulaId())
                .formulaContent(expressFormula == null ? "" : expressFormula.getFormula())
                .taxDeclarationColumn(SalaryItemBO.buildTaxDeclarationColumn(salaryItem.getCode())).build();
        return salarySobBackItemFormDTO;
    }

    public List<SalarySobBackItemDTO> save(SalarySobBackItemSaveParam saveParam) {
        return getSalarySobBackItemService(user).save(saveParam);
    }
}
