package com.engine.salary.wrapper;

import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.annotation.SalaryFormulaVar;
import com.engine.salary.entity.salaryformula.ExpressFormula;
import com.engine.salary.entity.salaryformula.dto.SalaryFormulaEmployeeDTO;
import com.engine.salary.entity.salaryitem.bo.SalaryItemBO;
import com.engine.salary.entity.salaryitem.dto.SalaryItemSobListDTO;
import com.engine.salary.entity.salaryitem.param.SalaryItemSearchParam;
import com.engine.salary.entity.salaryitem.po.SalaryItemPO;
import com.engine.salary.entity.salaryitem.po.SysSalaryItemPO;
import com.engine.salary.entity.salarysob.dto.SalarySobItemAggregateDTO;
import com.engine.salary.entity.salarysob.dto.SalarySobItemFormDTO;
import com.engine.salary.entity.salarysob.param.SalarySobItemSaveParam;
import com.engine.salary.entity.salarysob.po.SalarySobItemGroupPO;
import com.engine.salary.entity.salarysob.po.SalarySobItemPO;
import com.engine.salary.entity.taxagent.po.TaxAgentPO;
import com.engine.salary.service.*;
import com.engine.salary.service.impl.*;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.SalaryPageUtil;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import weaver.hrm.User;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 薪资账套的薪资项目
 * <p>Copyright: Copyright (c) 2022</p>
 * <p>Company: 泛微软件</p>
 *
 * @author qiantao
 * @version 1.0
 **/
public class SalarySobItemWrapper extends Service {

    private SalarySobItemService getSalarySobItemService(User user) {
        return ServiceUtil.getService(SalarySobItemServiceImpl.class, user);
    }

    private SalarySobItemGroupService getSalarySobItemGroupService(User user) {
        return ServiceUtil.getService(SalarySobItemGroupServiceImpl.class, user);
    }

    private TaxAgentService getTaxAgentService(User user) {
        return ServiceUtil.getService(TaxAgentServiceImpl.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);
    }

    /**
     * 薪资账套可选薪资项目列表
     *
     * @param queryParam 列表查询条件
     * @return
     */
    public PageInfo<SalaryItemSobListDTO> listPage4SalaryItem(SalaryItemSearchParam queryParam) {
        Integer searchPageSize = queryParam.getPageSize();
        Integer searchCurrent = queryParam.getCurrent();

        // 分页查询薪资项目
        queryParam.setPageSize(10000000);
        queryParam.setCurrent(1);
        PageInfo<SalaryItemPO> page = getSalaryItemService(user).listPageByParam(queryParam);

        List<SalaryItemPO> salaryItemList = page.getList();

        Set<Long> taxAgentIds = getTaxAgentService(user).listAllTaxAgents((long) user.getUID())
                .stream().map(TaxAgentPO::getId)
                .collect(Collectors.toSet());
        salaryItemList = salaryItemList.stream()
                .filter(po -> getSalaryItemService(user).filterInRange(taxAgentIds, po))
                .collect(Collectors.toList());
        
        // 薪资项目排序：薪资项目放在前面（首先按照设置的排序，没有设置按照id倒序，系统薪资项目放在最后），档案字段放在后面
        salaryItemList = salaryItemList.stream()
                .sorted(new Comparator<SalaryItemPO>() {
                    @Override
                    public int compare(SalaryItemPO o1, SalaryItemPO o2) {
                        return Integer.compare(o1.getUseInEmployeeSalary(),o2.getUseInEmployeeSalary());
                    }
                })
                .collect(Collectors.toList());
        salaryItemList = SalaryPageUtil.buildPage(searchCurrent, searchPageSize, salaryItemList).getList();

        //最终返回的分页对象
        PageInfo<SalaryItemSobListDTO> dtoPage = new PageInfo<>(SalaryItemSobListDTO.class);
        dtoPage.setPageSize(searchPageSize);
        dtoPage.setPageNum(searchCurrent);
        dtoPage.setTotal(page.getTotal());
        if (CollectionUtils.isNotEmpty(salaryItemList)) {
            // 查询公式
            Set<Long> formulaIds = SalaryEntityUtil.properties(salaryItemList, SalaryItemPO::getFormulaId);
            List<ExpressFormula> expressFormulas = getSalaryFormulaService(user).listExpressFormula(formulaIds);
            // 查询系统薪资项目
            Set<Long> sysSalaryItemIds = SalaryEntityUtil.properties(salaryItemList, SalaryItemPO::getSysSalaryItemId);
            List<SysSalaryItemPO> sysSalaryItemPOS = getSysSalaryItemService(user).listByIds(sysSalaryItemIds);
            // 转换成薪资项目列表dto
            dtoPage.setList(SalaryItemBO.convert2itemSobListDTO(salaryItemList, expressFormulas, sysSalaryItemPOS));
        }
        return dtoPage;

    }
    /**
     * 获取薪资账套的薪资项目详情
     *
     * @param salarySobItemGroupId 薪资账套的薪资项目的id
     * @return
     */
    public SalarySobItemGroupPO getGroupForm(Long salarySobItemGroupId) {
        return getSalarySobItemGroupService(user).getById(salarySobItemGroupId);
    }

    /**
     * 获取薪资账套的薪资项目详情
     *
     * @param salarySobId 薪资账套的id
     * @return
     */
    public SalarySobItemAggregateDTO getForm(Long salarySobId) {
        return getSalarySobItemService(user).getAggregateBySalarySobId(salarySobId);
    }

    /**
     * 保存
     *
     * @param saveParam 保存参数
     */
    public void save(SalarySobItemSaveParam saveParam) {
        getSalarySobItemService(user).save(saveParam);
    }


    /**
     * 基础信息浏览按钮（下拉框）
     *
     * @return
     */
    public Collection<Map<String, String>> empFieldList() {
        Field[] declaredFields = SalaryFormulaEmployeeDTO.class.getDeclaredFields();
        Map<String, String> empFieldMap = Maps.newHashMapWithExpectedSize(declaredFields.length);
        List<Map<String, String>> list = new ArrayList();
        for (Field declaredField : declaredFields) {
            Map<String, String> item = new HashMap<>();
            if (!declaredField.isAnnotationPresent(SalaryFormulaVar.class)) {
                continue;
            }
            SalaryFormulaVar annotation = declaredField.getAnnotation(SalaryFormulaVar.class);
            empFieldMap.put(declaredField.getName(), SalaryI18nUtil.getI18nLabel(annotation.labelId(), annotation.defaultLabel()));
            item.put("name", SalaryI18nUtil.getI18nLabel(annotation.labelId(), annotation.defaultLabel()));
            item.put("id", declaredField.getName());
            list.add(item);
        }
        return list;
    }

    /**
     * 薪资项目的详情
     */
    public SalarySobItemFormDTO getSalaryItemForm(SalarySobItemPO param) {
        return getSalarySobItemService(user).getSalaryItemForm(param);
    }
}
