package com.engine.salary.wrapper;

import com.cloudstore.dev.api.util.Util_DataCache;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.biz.SalaryItemBiz;
import com.engine.salary.constant.SalaryItemConstant;
import com.engine.salary.entity.salaryformula.ExpressFormula;
import com.engine.salary.entity.salaryformula.bo.SalaryFormulaBO;
import com.engine.salary.entity.salaryformula.dto.ExpressFormulaDTO;
import com.engine.salary.entity.salaryformula.param.SalaryFormulaDetailQueryParam;
import com.engine.salary.entity.salaryformula.param.SalaryFormulaFieldQueryParam;
import com.engine.salary.entity.salaryformula.param.SalaryFormulaMockParam;
import com.engine.salary.entity.salaryformula.param.SalaryFormulaSaveParam;
import com.engine.salary.entity.salaryformula.po.FormulaPO;
import com.engine.salary.entity.salaryformula.po.FormulaVar;
import com.engine.salary.entity.siaccount.dto.InsuranceAcctDetailImportFieldDTO;
import com.engine.salary.entity.sicategory.po.ICategoryPO;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.mapper.sicategory.ICategoryMapper;
import com.engine.salary.service.FormulaRunService;
import com.engine.salary.service.RemoteExcelService;
import com.engine.salary.service.SalaryFormulaService;
import com.engine.salary.service.impl.FormulaRunServiceImpl;
import com.engine.salary.service.impl.RemoteExcelServiceImpl;
import com.engine.salary.service.impl.SalaryFormulaServiceImpl;
import com.engine.salary.util.JsonUtil;
import com.engine.salary.util.db.MapperProxyFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import weaver.hrm.User;
import weaver.servicefiles.DataSourceXML;

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

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

    private RemoteExcelService getRemoteExcelService(User user) {
        return ServiceUtil.getService(RemoteExcelServiceImpl.class, user);
    }

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

    private FormulaRunService getFormulaRunService(User user) {
        return ServiceUtil.getService(FormulaRunServiceImpl.class, user);
    }

    private SalaryItemBiz salaryItemBiz = new SalaryItemBiz();

    private ICategoryMapper getICategoryMapper() {
        return MapperProxyFactory.getProxy(ICategoryMapper.class);
    }

    /**
     * 公式字段列表
     *
     * @param param 查询参数
     * @return
     */
    public List<FormulaVar> fieldList(SalaryFormulaFieldQueryParam param) {
        return getRemoteExcelService(user).fieldList(param.getSourceId(), param.getExtendParam());
    }


    /**
     * 公式字段分类
     *
     * @param param 查询参数
     * @return
     */
    public List<Map<String, Object>> fieldGroupList(Map<String, Object> param) {
        return getRemoteExcelService(user).fieldGroupList(param);
    }

    public ExpressFormulaDTO detail(SalaryFormulaDetailQueryParam queryParam) {
        List<ExpressFormula> expressFormulas = getSalaryFormulaService(user).listExpressFormula(Collections.singleton(queryParam.getFormulaId()));
        if (CollectionUtils.isEmpty(expressFormulas)) {
            throw new SalaryRunTimeException("获取公式详情失败");
        }
        Map<Long, String> returnTypeMap = new HashMap<>();
        returnTypeMap.put(queryParam.getFormulaId(),queryParam.getReturnType());
        return SalaryFormulaBO.convert2DTO(expressFormulas, returnTypeMap).get(0);
    }

    public FormulaPO save(SalaryFormulaSaveParam salaryFormulaSaveParam) {
        return getSalaryFormulaService(user).save(salaryFormulaSaveParam);
    }

    public ArrayList datasourceList() {
        DataSourceXML dataSourceXML = new DataSourceXML();
        ArrayList pointArrayList = dataSourceXML.getPointArrayList();
        return pointArrayList;
    }

    /**
     * 获取薪资项目中福利类项目
     */
    public List<InsuranceAcctDetailImportFieldDTO> welfareList() {

        List<InsuranceAcctDetailImportFieldDTO> welfareList = new ArrayList<>();
        SalaryFormulaFieldQueryParam param = new SalaryFormulaFieldQueryParam();
        param.setSourceId("welfare");
        //获取福利类薪资项目
        List<FormulaVar> list = getRemoteExcelService(user).fieldList(param.getSourceId(), param.getExtendParam());
        list = list.stream().filter(f -> !(f.getName().contains("正常缴纳") || f.getName().contains("补缴") || f.getName().contains("补差") || f.getName().contains("申报基数"))).collect(Collectors.toList());
        //提取出福利类项目名称
        for (FormulaVar formulaVar : list) {
            InsuranceAcctDetailImportFieldDTO insuranceAcctDetailImportFieldDTO = new InsuranceAcctDetailImportFieldDTO();
            insuranceAcctDetailImportFieldDTO.setFieldId(formulaVar.getFieldId().contains("welfare_") ? formulaVar.getFieldId().substring(8) : formulaVar.getFieldId());
            insuranceAcctDetailImportFieldDTO.setSalaryItemName(formulaVar.getName());
            welfareList.add(insuranceAcctDetailImportFieldDTO);

        }

        welfareList.add(new InsuranceAcctDetailImportFieldDTO("socialSum","社保合计", false));
        welfareList.add(new InsuranceAcctDetailImportFieldDTO("fundSum","公积金合计",false));
        welfareList.add(new InsuranceAcctDetailImportFieldDTO("otherSum","其他福利合计", false));
        welfareList.add(new InsuranceAcctDetailImportFieldDTO("total","合计", false));

        // 缓存勾选
        String cacheKey = user.getUID() + SalaryItemConstant.SI_ACCOUNT_IMPORT_FIELD_SIGN;
        String cacheValue = (String) Util_DataCache.getObjVal(cacheKey);
        List<String> checkFields = JsonUtil.parseList(cacheValue, String.class) == null ? new ArrayList<>() : JsonUtil.parseList(cacheValue, String.class);
        welfareList.stream().forEach(field -> {
            if (checkFields.contains(field.getFieldId())) {
                field.setChecked(true);
            }
        });
        return welfareList;
    }

    /**
     * 获取福利台账的补差-福利类项目
     */
    public List<InsuranceAcctDetailImportFieldDTO> balanceWelfareList() {

        List<InsuranceAcctDetailImportFieldDTO> welfareList = welfareList();
        welfareList = welfareList.stream().filter(f -> !f.getSalaryItemName().contains("合计")).collect(Collectors.toList());

        List<ICategoryPO> noUseICategoryList= getICategoryMapper().listAll().stream().filter(f -> f.getIsUse() == 0).collect(Collectors.toList());
        if (noUseICategoryList.size() > 0) {
            List<String> noUseNameList = noUseICategoryList.stream().map(ICategoryPO::getInsuranceName).collect(Collectors.toList());
            welfareList = welfareList.stream().filter(f -> !noUseNameList.contains(f.getSalaryItemName().substring(0, f.getSalaryItemName().length() - 2))).collect(Collectors.toList());

        }

        // 缓存勾选
        String cacheKey = user.getUID() + SalaryItemConstant.SI_ACCOUNT_BALANCE_IMPORT_FIELD_SIGN;
        String cacheValue = (String) Util_DataCache.getObjVal(cacheKey);
        List<String> checkFields = JsonUtil.parseList(cacheValue, String.class) == null ? new ArrayList<>() : JsonUtil.parseList(cacheValue, String.class);
        welfareList.stream().forEach(field -> {
            if (checkFields.contains(field.getFieldId())) {
                field.setChecked(true);
            }
        });

        return welfareList;
    }

    public Object mock(SalaryFormulaMockParam param) {
        return getSalaryFormulaService(user).mock(param);
    }
}
