package com.engine.salary.report.wrapper;

import com.alibaba.fastjson.JSON;
import com.cloudstore.eccom.pc.table.WeaTableColumn;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.entity.salaryitem.po.SalaryItemPO;
import com.engine.salary.enums.salaryitem.SalaryDataTypeEnum;
import com.engine.salary.report.entity.dto.SalaryStatisticsItemFormDTO;
import com.engine.salary.report.entity.param.SalaryStatisticsItemSaveParam;
import com.engine.salary.report.entity.po.SalaryStatisticsItemPO;
import com.engine.salary.report.enums.SalaryStatisticsItemStringRuleEnum;
import com.engine.salary.report.enums.UnitTypeEnum;
import com.engine.salary.report.service.SalaryStatisticsItemService;
import com.engine.salary.report.service.impl.SalaryStatisticsItemServiceImpl;
import com.engine.salary.service.SalaryItemService;
import com.engine.salary.service.impl.SalaryItemServiceImpl;
import com.engine.salary.util.SalaryAssert;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import org.apache.commons.lang3.StringUtils;
import weaver.hrm.User;

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

/**
 * 薪酬报表统计项目
 * <p>Copyright: Copyright (c) 2022</p>
 * <p>Company: 泛微软件</p>
 *
 * @author qiantao
 * @version 1.0
 **/
public class SalaryStatisticsItemWrapper extends Service {

    private SalaryStatisticsItemService getSalaryStatisticsItemService(User user) {
        return ServiceUtil.getService(SalaryStatisticsItemServiceImpl.class, user);
    }

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

    /**
     * 获取自定义统计项目表单
     *
     * @param id
     * @return
     */
    public SalaryStatisticsItemFormDTO getForm(Long id) {
        Map<String, Object> weaForm = new HashMap<>();
        Map<String, Object> ruleData = new HashMap<>();
        if (Objects.nonNull(id)) {
            SalaryStatisticsItemPO salaryStatisticsItem = getSalaryStatisticsItemService(user).getById(id);
            SalaryAssert.notNull(salaryStatisticsItem, SalaryI18nUtil.getI18nLabel(152591, "统计项目不存在"));
            String itemValue = salaryStatisticsItem.getItemValue();
            if (StringUtils.isNotBlank(itemValue)) {
                List<SalaryItemPO> salaryItems = getSalaryItemService(user).listAll();
                Map<String, SalaryItemPO> itemsMap = SalaryEntityUtil.convert2Map(salaryItems, k -> k.getId().toString());
                List<Map<String, String>> welfareItems = new ArrayList<>();
                Arrays.stream(itemValue.split(",")).forEach(value -> {
                    Map<String, String> welfareItem = new HashMap<>();
                    welfareItem.put("id", value);
                    welfareItem.put("name", itemsMap.get(value).getName());
                    welfareItem.put("dataType", itemsMap.get(value).getDataType());
                    welfareItems.add(welfareItem);
                });
                Map<String, Object> map = new HashMap<>();
                //版本变更，由多选变成单选
                map.put("itemValue", welfareItems.get(0));
                map.put("itemName", salaryStatisticsItem.getItemName());
                weaForm.put("data", map);
                ruleData = buildRule(SalaryDataTypeEnum.parseByValue(welfareItems.get(0).get("dataType")), salaryStatisticsItem);
            }
        } else {
            ruleData = buildRule(null, null);
        }

        return SalaryStatisticsItemFormDTO.builder()
                .id(id)
                .baseForm(weaForm)
                .ruleData(ruleData)
                .build();
    }

    public SalaryStatisticsItemFormDTO changeTab(Long itemId) {
        SalaryItemPO po = getSalaryItemService(user).getById(itemId);
        Map<String, Object> ruleData = buildRule(SalaryDataTypeEnum.parseByValue(po.getDataType()), null);
        return SalaryStatisticsItemFormDTO.builder().ruleData(ruleData).build();

    }

    public Map<String, Object> buildRule(SalaryDataTypeEnum dataType, SalaryStatisticsItemPO salaryStatisticsItem) {
        Map<String, Object> weaTable;
        if (dataType == null || dataType == SalaryDataTypeEnum.NUMBER) {
            weaTable = buildNumberRule(salaryStatisticsItem);
        } else {
            weaTable = buildStringRule(salaryStatisticsItem);
        }
        return weaTable;
    }

    /**
     * 字符取值规则
     *
     * @param salaryStatisticsItem 统计项
     * @return
     */
    private Map<String, Object> buildStringRule(SalaryStatisticsItemPO salaryStatisticsItem) {
        Map<String, Object> weaTable = new HashMap<>();

        List<WeaTableColumn> list = new ArrayList<>();
        WeaTableColumn ruleName = new WeaTableColumn("20%", SalaryI18nUtil.getI18nLabel(157532, "字符取值规则"), "ruleName");
        list.add(ruleName);
        weaTable.put("columns", list);

        List<Map<String, Object>> result = new ArrayList<>();
        if (salaryStatisticsItem == null) {
            for (SalaryStatisticsItemStringRuleEnum ruleEnum : SalaryStatisticsItemStringRuleEnum.values()) {
                Map<String, Object> rule = new HashMap<>();
                rule.put("id", ruleEnum.getValue());
                rule.put("ruleName", ruleEnum.getDefaultLabel());
                rule.put("totalValue", 0);
                result.add(rule);
            }
        } else {
            for (SalaryStatisticsItemStringRuleEnum ruleEnum : SalaryStatisticsItemStringRuleEnum.values()) {
                Map<String, Object> rule = new HashMap<>();
                switch (ruleEnum) {
                    case LAST:
                        rule = JSON.parseObject(salaryStatisticsItem.getLastRule(), HashMap.class);
                        break;
                    case OLD:
                        rule = JSON.parseObject(salaryStatisticsItem.getOldRule(), HashMap.class);
                        break;
                    case FREQUENT:
                        rule = JSON.parseObject(salaryStatisticsItem.getFrequentRule(), HashMap.class);
                        break;
                    case TILE:
                        rule = JSON.parseObject(salaryStatisticsItem.getTileRule(), HashMap.class);
                        break;
                    default:
                        break;
                }
                if (rule == null) {
                    rule = new HashMap<>();
                }
                rule.put("id", ruleEnum.getValue());
                rule.put("ruleName", ruleEnum.getDefaultLabel());
                rule.put("totalValue", Optional.ofNullable(rule.get("totalValue")).orElse(0));
                result.add(rule);
            }
        }
        weaTable.put("data", result);

        return weaTable;
    }

    /**
     * 数值取值规则
     *
     * @param salaryStatisticsItem 统计项
     * @return
     */
    private Map<String, Object> buildNumberRule(SalaryStatisticsItemPO salaryStatisticsItem) {
        Map<String, Object> weaTable = new HashMap<>();
        List<WeaTableColumn> list = new ArrayList<>();
        WeaTableColumn ruleName = new WeaTableColumn("20%", SalaryI18nUtil.getI18nLabel(157532, "统计规则"), "ruleName");
        WeaTableColumn ratio = new WeaTableColumn("10%", SalaryI18nUtil.getI18nLabel(162990, "占比"), "ratio");
        WeaTableColumn m2m = new WeaTableColumn("10%", SalaryI18nUtil.getI18nLabel(157533, "环比"), "m2m");
        WeaTableColumn m2mLimit = new WeaTableColumn("25%", SalaryI18nUtil.getI18nLabel(157536, "环比增幅正常区间设置"), "m2mLimit");
        WeaTableColumn y2y = new WeaTableColumn("10%", SalaryI18nUtil.getI18nLabel(162991, "同比"), "y2y");
        WeaTableColumn y2yLimit = new WeaTableColumn("25%", SalaryI18nUtil.getI18nLabel(162992, "同比增幅正常区间设置"), "y2yLimit");
        list.add(ruleName);
        list.add(ratio);
        list.add(m2m);
        list.add(m2mLimit);
        list.add(y2y);
        list.add(y2yLimit);
        weaTable.put("columns", list);

        List<Map<String, Object>> result = new ArrayList<>();
        List<String> ruleList = Arrays.asList("count", "sum", "avg", "max", "min", "median");
        List<String> ruleNameList = Arrays.asList(
                SalaryI18nUtil.getI18nLabel(157268, "计数"),
                SalaryI18nUtil.getI18nLabel(157266, "求和"),
                SalaryI18nUtil.getI18nLabel(100132, "平均值"),
                SalaryI18nUtil.getI18nLabel(163001, "最大值"),
                SalaryI18nUtil.getI18nLabel(163002, "最小值"),
                SalaryI18nUtil.getI18nLabel(163003, "中位数"));
        if (salaryStatisticsItem == null) {
            for (int i = 0; i < ruleList.size(); i++) {
                Map<String, Object> rule = new HashMap<>();
                rule.put("id", ruleList.get(i));
                rule.put("ruleName", ruleNameList.get(i));
                rule.put("totalValue", 0);
                rule.put("ratioValue", 0);
                rule.put("m2mValue", 0);
                rule.put("m2mUpperLimit", "");
                rule.put("m2mLowerLimit", "");
                rule.put("y2yValue", 0);
                rule.put("y2yUpperLimit", "");
                rule.put("y2yLowerLimit", "");
                result.add(rule);
            }
        } else {
            for (int i = 0; i < ruleList.size(); i++) {
                Map<String, Object> rule = new HashMap<>();
                switch (ruleList.get(i)) {
                    case "count":
                        rule = JSON.parseObject(salaryStatisticsItem.getCountRule(), HashMap.class);
                        break;
                    case "sum":
                        rule = JSON.parseObject(salaryStatisticsItem.getSumRule(), HashMap.class);
                        break;
                    case "avg":
                        rule = JSON.parseObject(salaryStatisticsItem.getAvgRule(), HashMap.class);
                        break;
                    case "max":
                        rule = JSON.parseObject(salaryStatisticsItem.getMaxRule(), HashMap.class);
                        break;
                    case "min":
                        rule = JSON.parseObject(salaryStatisticsItem.getMinRule(), HashMap.class);
                        break;
                    case "median":
                        rule = JSON.parseObject(salaryStatisticsItem.getMedianRule(), HashMap.class);
                        break;
                    default:
                        break;
                }
                if (rule == null) {
                    rule = new HashMap<>();
                }
                rule.put("id", ruleList.get(i));
                rule.put("ruleName", ruleNameList.get(i));
                rule.put("totalValue", Optional.ofNullable(rule.get("totalValue")).orElse(0));
                rule.put("ratioValue", Optional.ofNullable(rule.get("ratioValue")).orElse(0));
                rule.put("m2mValue", Optional.ofNullable(rule.get("m2mValue")).orElse(0));
                rule.put("m2mUpperLimit", Optional.ofNullable(rule.get("m2mUpperLimit")).orElse(""));
                rule.put("m2mLowerLimit", Optional.ofNullable(rule.get("m2mLowerLimit")).orElse(""));
                rule.put("y2yValue", Optional.ofNullable(rule.get("y2yValue")).orElse(0));
                rule.put("y2yUpperLimit", Optional.ofNullable(rule.get("y2yUpperLimit")).orElse(""));
                rule.put("y2yLowerLimit", Optional.ofNullable(rule.get("y2yLowerLimit")).orElse(""));
                result.add(rule);
            }
        }
        weaTable.put("data", result);
        return weaTable;
    }

    /**
     * 获取自定义统计项目列表
     *
     * @param statisticsReportId
     * @return
     */
    public List<Map<String, Object>> list(Long statisticsReportId) {
        List<SalaryStatisticsItemPO> salaryStatisticsItemList = getSalaryStatisticsItemService(user).listByStatisticsReportId(statisticsReportId);
        salaryStatisticsItemList = salaryStatisticsItemList.stream().sorted(Comparator.comparing(SalaryStatisticsItemPO::getIndexValue)).collect(Collectors.toList());
        List<Map<String, Object>> result = new ArrayList<>();
        salaryStatisticsItemList.forEach(po -> {
            Map<String, Object> rule = new HashMap<>();
            rule.put("id", po.getId().toString());
            rule.put("itemName", po.getItemName());
            rule.put("unitType", po.getUnitType() == null ? UnitTypeEnum.YUAN.getValue() : po.getUnitType());
            rule.put("itemValue", po.getItemValue());
            rule.put("countRule", po.getCountRule());
            rule.put("sumRule", po.getSumRule());
            rule.put("avgRule", po.getAvgRule());
            rule.put("maxRule", po.getMaxRule());
            rule.put("minRule", po.getMinRule());
            rule.put("medianRule", po.getMedianRule());
            rule.put("indexValue", po.getIndexValue());
            result.add(rule);
        });
        return result;
    }

    /**
     * 删除自定义统计项目
     *
     * @param ids
     * @return
     */
    public String delete(Collection<Long> ids) {
        return getSalaryStatisticsItemService(user).delete(ids);
    }

    /**
     * 保存自定义统计项目
     *
     * @param saveParam
     * @return
     */
    public String save(SalaryStatisticsItemSaveParam saveParam) {
        return getSalaryStatisticsItemService(user).save(saveParam);
    }

}
