package com.engine.salary.report.service.impl;

import com.alibaba.fastjson.JSON;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.entity.hrm.dto.EmployeeInfoExpandDTO;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.mapper.report.SalaryStatisticsDimensionMapper;
import com.engine.salary.report.common.constant.SalaryStatisticsDimensionConstant;
import com.engine.salary.report.entity.param.SalaryStatisticsDimensionQueryParam;
import com.engine.salary.report.entity.param.SalaryStatisticsDimensionSaveParam;
import com.engine.salary.report.entity.po.SalaryStatisticsDimensionPO;
import com.engine.salary.report.entity.po.SalaryStatisticsReportPO;
import com.engine.salary.report.enums.SalaryStatisticsDimensionTypeEnum;
import com.engine.salary.report.service.SalaryStatisticsDimensionService;
import com.engine.salary.report.service.SalaryStatisticsReportService;
import com.engine.salary.service.SalaryEmployeeService;
import com.engine.salary.service.impl.SalaryEmployeeServiceImpl;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.db.MapperProxyFactory;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.SalaryPageUtil;
import com.google.common.collect.Lists;
import com.engine.salary.util.db.IdGenerator;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.BeanUtils;
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 SalaryStatisticsDimensionServiceImpl extends Service implements SalaryStatisticsDimensionService {

    private SalaryStatisticsDimensionMapper getSalaryStatisticsDimensionMapper() {
        return MapperProxyFactory.getProxy(SalaryStatisticsDimensionMapper.class);
    }

    private SalaryStatisticsReportService salaryStatisticsReportService(User user) {
        return ServiceUtil.getService(SalaryStatisticsReportServiceImpl.class, user);
    }

    private SalaryEmployeeService getSalaryEmployeeService(User user) {
        return ServiceUtil.getService(SalaryEmployeeServiceImpl.class, user);
    }

    /**
     * 初始化默认维度
     */
    @Override
    public void init(Long currentEmployeeId) {
        List<SalaryStatisticsDimensionPO> defaultList = getSalaryStatisticsDimensionMapper().listSome(SalaryStatisticsDimensionPO.builder().isDefault(NumberUtils.INTEGER_ONE).build());

        if (CollectionUtils.isEmpty(defaultList)) {
            List<String> defaultDimensionNames = Arrays.asList(
                    SalaryI18nUtil.getI18nLabel(87614, "薪资所属月"),
                    SalaryI18nUtil.getI18nLabel(86184, "个税扣缴义务人"),
//                    SalaryI18nUtil.getI18nLabel(145212, "收入所得类型"),
                    SalaryI18nUtil.getI18nLabel(107369, "分部"),
                    SalaryI18nUtil.getI18nLabel(86185, "部门"),
//                    SalaryI18nUtil.getI18nLabel(90633, "岗位"),
//                    SalaryI18nUtil.getI18nLabel(98623, "职级"),
//                    SalaryI18nUtil.getI18nLabel(109332, "人事状态"),
//                    SalaryI18nUtil.getI18nLabel(151914, "人员类型"),
                    SalaryI18nUtil.getI18nLabel(100133, "人员"),
                    SalaryI18nUtil.getI18nLabel(157163, "年度"),
                    SalaryI18nUtil.getI18nLabel(173199, "半年度"),
                    SalaryI18nUtil.getI18nLabel(157162, "季度")
            );
            List<String> defaultDimensionCodes = Arrays.asList(
                    SalaryStatisticsDimensionConstant.DM_SALARY_MONTH,
                    SalaryStatisticsDimensionConstant.DM_TAX_AGENT,
//                    SalaryStatisticsDimensionConstant.DM_INCOME_CATEGORY,
                    SalaryStatisticsDimensionConstant.DM_SUB_COMPANY,
                    SalaryStatisticsDimensionConstant.DM_DEPARTMENT,
//                    SalaryStatisticsDimensionConstant.DM_POSITION,
//                    SalaryStatisticsDimensionConstant.DM_GRADE,
//                    SalaryStatisticsDimensionConstant.DM_HRM_STATUS,
//                    SalaryStatisticsDimensionConstant.DM_EMPLOYEE_TYPE,
                    SalaryStatisticsDimensionConstant.DM_EMPLOYEE,
                    SalaryStatisticsDimensionConstant.DM_YEAR,
                    SalaryStatisticsDimensionConstant.DM_HALF_YEAR,
                    SalaryStatisticsDimensionConstant.DM_QUARTER
            );

            List<SalaryStatisticsDimensionPO> dimensionDefaultNews = Lists.newArrayList();
            Date now = new Date();
            for (String dm : defaultDimensionNames) {
                dimensionDefaultNews.add(SalaryStatisticsDimensionPO.builder()
                        .id(IdGenerator.generate())
                        .dimName(dm)
                        .dimType(SalaryStatisticsDimensionTypeEnum.QUALITATIVE.getValue())
                        .setting("")
                        .remark(dm)
                        .isDefault(NumberUtils.INTEGER_ONE)
                        .dimCode(defaultDimensionCodes.get(defaultDimensionNames.indexOf(dm)))
                        .createTime(now)
                        .creator(currentEmployeeId)
                        .updateTime(now)
                        .deleteType(0)
                        .tenantKey("")
                        .build());
            }
            dimensionDefaultNews.forEach(getSalaryStatisticsDimensionMapper()::insertIgnoreNull);
        }
    }

    @Override
    public SalaryStatisticsDimensionPO getById(Long id) {
        return getSalaryStatisticsDimensionMapper().getById(id);
    }

    @Override
    public List<SalaryStatisticsDimensionPO> listAll() {
        return getSalaryStatisticsDimensionMapper().listAll();
    }

    @Override
    public PageInfo<SalaryStatisticsDimensionPO> listPage(SalaryStatisticsDimensionQueryParam queryParam) {

        // 查询
        List<SalaryStatisticsDimensionPO> salaryStatisticsDimensionPOS = getSalaryStatisticsDimensionMapper().listSome(SalaryStatisticsDimensionPO.builder().dimName(queryParam.getDimName()).build());
        // 分页参数
        PageInfo<SalaryStatisticsDimensionPO> page = SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(), salaryStatisticsDimensionPOS, SalaryStatisticsDimensionPO.class);

        return page;
    }

    /**
     * 根据名称模糊查询
     *
     * @param fieldName
     * @return
     */
    private List<SalaryStatisticsDimensionPO> listByName(String fieldName) {
        return getSalaryStatisticsDimensionMapper().listSome(SalaryStatisticsDimensionPO.builder().dimName(fieldName).build());
    }

    @Override
    public String save(SalaryStatisticsDimensionSaveParam saveParam) {
        SalaryStatisticsDimensionSaveParam.checkParam(saveParam);

        String setting = "";
        String dimCode = "";
        if (SalaryStatisticsDimensionTypeEnum.QUALITATIVE.equals(saveParam.getDimType())) {
            setting = JSON.toJSONString(saveParam.getSetting4Qualitative());
            dimCode = saveParam.getSetting4Qualitative().getId();
        } else if (SalaryStatisticsDimensionTypeEnum.RATION_GROUP_SPACING.equals(saveParam.getDimType())) {
            setting = JSON.toJSONString(saveParam.getSetting4RationGroupSpacing());
            dimCode = saveParam.getDimCode();
        } else if (SalaryStatisticsDimensionTypeEnum.RATION_GROUP_INDIVIDUAL.equals(saveParam.getDimType())) {
            setting = JSON.toJSONString(saveParam.getSetting4RationGroupIndividual());
            dimCode = saveParam.getDimCode();
        }
        Date now = new Date();
        if (saveParam.getId() != null) {
            SalaryStatisticsDimensionPO po = this.getById(saveParam.getId());
            if (po == null) {
                throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(161300, "统计维度不存在"));
            }
            List<SalaryStatisticsDimensionPO> list = listByName(saveParam.getDimName());
            boolean nameExist = list.stream().anyMatch(e -> !Objects.equals(e.getId(), saveParam.getId()));
            if (nameExist) {
                throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98080, "名称不允许重复"));
            }
            SalaryStatisticsDimensionPO poNew = new SalaryStatisticsDimensionPO();
            BeanUtils.copyProperties(po, poNew);
            poNew.setDimName(saveParam.getDimName());
            poNew.setDimType(saveParam.getDimType().getValue());
            poNew.setDimCode(dimCode);
            poNew.setSetting(setting);
            poNew.setRemark(saveParam.getRemark());
            this.getSalaryStatisticsDimensionMapper().updateIgnoreNull(poNew);
        } else {
            List<SalaryStatisticsDimensionPO> list = listByName(saveParam.getDimName());
            if (CollectionUtils.isNotEmpty(list)) {
                throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98080, "名称不允许重复"));
            }
            Long id = IdGenerator.generate();
            SalaryStatisticsDimensionPO poNew = SalaryStatisticsDimensionPO.builder()
                    .id(id)
                    .dimName(saveParam.getDimName())
                    .dimType(saveParam.getDimType().getValue())
                    .dimCode(dimCode)
                    .setting(setting)
                    .remark(saveParam.getRemark())
                    .createTime(now)
                    .creator((long) user.getUID())
                    .updateTime(now)
                    .deleteType(0)
                    .tenantKey("")
                    .build();
            this.getSalaryStatisticsDimensionMapper().insertIgnoreNull(poNew);
        }
        return StringUtils.EMPTY;
    }

    @Override
    public void saveExpandFieldSettings(EmployeeInfoExpandDTO saveParam) {
        getSalaryEmployeeService(user).saveEmployeeExpandFieldSettings(saveParam);
    }

    @Override
    public EmployeeInfoExpandDTO getExpandFieldSettings(String module) {
        return getSalaryEmployeeService(user).getExpandFieldSettings(module);
    }

    @Override
    public Map<String, Object> delete(Collection<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(84026, "参数错误"));
        }
        int total = ids.size();
        List<SalaryStatisticsDimensionPO> list = getSalaryStatisticsDimensionMapper().listSome(SalaryStatisticsDimensionPO.builder().ids(ids).build());
        boolean isDefault = list.stream().anyMatch(s -> NumberUtils.INTEGER_ONE.equals(s.getIsDefault()));
        if (CollectionUtils.isEmpty(list) || isDefault) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(84026, "默认统计维度不可删除！"));
        }

        // 被薪酬报表引用
        List<SalaryStatisticsReportPO> salaryStatisticsReports = salaryStatisticsReportService(user).listAll();
        if (CollectionUtils.isNotEmpty(salaryStatisticsReports)) {
            list = list.stream()
                    .filter(dim -> salaryStatisticsReports.stream().noneMatch(rp -> StringUtils.isNotEmpty(rp.getDimension()) && Arrays.asList(rp.getDimension().split(",")).contains(dim.getId().toString())))
                    .collect(Collectors.toList());
        }

        int success = list.size();
        if (success > 0) {
            List<Long> deleteIds = list.stream().map(SalaryStatisticsDimensionPO::getId).collect(Collectors.toList());
            getSalaryStatisticsDimensionMapper().batDelete(deleteIds);
        }

        Map<String, Object> resultMap = new HashMap<>(2);
        String resultMsg = SalaryI18nUtil.getI18nLabel(94620, "操作成功");
        String resultType = "success";
        // 单个设为定薪提示
        if (total > 1) {
            resultMsg = SalaryI18nUtil.getI18nLabel(134807, "成功条数") + ": " + (success) + "; "
                    + SalaryI18nUtil.getI18nLabel(134808, "失败条数") + ": " + (total - success)
                    + ((total - success) > 0 ? ", " + SalaryI18nUtil.getI18nLabel(176149, "被薪资统计报表引用的不能删除") : "");
            if ((total - success) > 0) {
                resultType = "info";
            }
        } else if (total == 1 && success < 1) {
            resultMsg = SalaryI18nUtil.getI18nLabel(176149, "被薪资统计报表引用的不能删除");
            throw new SalaryRunTimeException(resultMsg);
//            resultType = "info";
        }
        resultMap.put("type", resultType);
        resultMap.put("msg", resultMsg);
        return resultMap;
    }

    @Override
    public List<SalaryStatisticsDimensionPO> listAllDefaultDimension() {
        return getSalaryStatisticsDimensionMapper().listSome(SalaryStatisticsDimensionPO.builder().isDefault(NumberUtils.INTEGER_ONE).build());
    }
}
