package com.sundot.airport.system.service.impl;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.sundot.airport.common.core.domain.entity.SysDictData;
import com.sundot.airport.common.enums.BasePerformanceIndicatorRewardPunishmentTypeTypeEnum;
import com.sundot.airport.common.exception.ServiceException;
import com.sundot.airport.common.utils.DateUtils;
import com.sundot.airport.system.domain.BasePerformanceIndicatorCategory;
import com.sundot.airport.system.service.IBasePerformanceIndicatorCategoryService;
import com.sundot.airport.system.service.ISysDictDataService;
import com.sundot.airport.system.utils.CodeGeneratorUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.sundot.airport.system.mapper.BasePerformanceIndicatorMapper;
import com.sundot.airport.system.domain.BasePerformanceIndicator;
import com.sundot.airport.system.service.IBasePerformanceIndicatorService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 考核指标Service业务层处理
 *
 * @author ruoyi
 * @date 2026-04-28
 */
@Service
public class BasePerformanceIndicatorServiceImpl implements IBasePerformanceIndicatorService {
    @Autowired
    private BasePerformanceIndicatorMapper basePerformanceIndicatorMapper;
    @Autowired
    private IBasePerformanceIndicatorCategoryService basePerformanceIndicatorCategoryService;
    @Autowired
    private ISysDictDataService sysDictDataService;
    @Autowired
    private CodeGeneratorUtil codeGeneratorUtil;

    /**
     * 查询考核指标
     *
     * @param id 考核指标主键
     * @return 考核指标
     */
    @Override
    public BasePerformanceIndicator selectBasePerformanceIndicatorById(Long id) {
        return basePerformanceIndicatorMapper.selectBasePerformanceIndicatorById(id);
    }

    /**
     * 查询考核指标列表
     *
     * @param basePerformanceIndicator 考核指标
     * @return 考核指标
     */
    @Override
    public List<BasePerformanceIndicator> selectBasePerformanceIndicatorList(BasePerformanceIndicator basePerformanceIndicator) {
        return basePerformanceIndicatorMapper.selectBasePerformanceIndicatorList(basePerformanceIndicator);
    }

    /**
     * 查询考核指标列表（严格）
     *
     * @param basePerformanceIndicator 考核指标
     * @return 考核指标
     */
    @Override
    public List<BasePerformanceIndicator> selectBasePerformanceIndicatorStrictList(BasePerformanceIndicator basePerformanceIndicator) {
        return basePerformanceIndicatorMapper.selectBasePerformanceIndicatorStrictList(basePerformanceIndicator);
    }

    /**
     * 新增考核指标
     *
     * @param basePerformanceIndicator 考核指标
     * @return 结果
     */
    @Override
    public int insertBasePerformanceIndicator(BasePerformanceIndicator basePerformanceIndicator) {
        // 一级分类+二级分类
        BasePerformanceIndicatorCategory categoryQueryParam = new BasePerformanceIndicatorCategory();
        List<BasePerformanceIndicatorCategory> categoryList = basePerformanceIndicatorCategoryService.selectBasePerformanceIndicatorCategoryListTree(categoryQueryParam);
        if (ObjUtil.isNotNull(basePerformanceIndicator.getCategoryCodeOne())) {
            BasePerformanceIndicatorCategory categoryOne = categoryList.stream().filter(category -> StrUtil.equals(category.getCode(), basePerformanceIndicator.getCategoryCodeOne())).findFirst().orElse(null);
            if (ObjUtil.isNotNull(categoryOne)) {
                basePerformanceIndicator.setCategoryNameOne(categoryOne.getName());
                if (ObjUtil.isNotNull(basePerformanceIndicator.getCategoryCode()) && CollUtil.isNotEmpty(categoryOne.getChildren())) {
                    List<BasePerformanceIndicatorCategory> children = (List<BasePerformanceIndicatorCategory>) categoryOne.getChildren();
                    BasePerformanceIndicatorCategory categoryTwo = children.stream().filter(category -> StrUtil.equals(category.getCode(), basePerformanceIndicator.getCategoryCode())).findFirst().orElse(null);
                    if (ObjUtil.isNotNull(categoryTwo)) {
                        basePerformanceIndicator.setCategoryName(categoryTwo.getCode());
                    } else {
                        basePerformanceIndicator.setCategoryName(null);
                    }
                }
            } else {
                basePerformanceIndicator.setCategoryNameOne(null);
            }
        }
        // 判断奖罚类型
        if (ObjUtil.isNull(basePerformanceIndicator.getScore())) {
            basePerformanceIndicator.setRewardPunishmentType(BasePerformanceIndicatorRewardPunishmentTypeTypeEnum.OTHER.getCode());
        } else if (basePerformanceIndicator.getScore().compareTo(BigDecimal.ZERO) > 0) {
            basePerformanceIndicator.setRewardPunishmentType(BasePerformanceIndicatorRewardPunishmentTypeTypeEnum.REWARD.getCode());
        } else if (basePerformanceIndicator.getScore().compareTo(BigDecimal.ZERO) < 0) {
            basePerformanceIndicator.setRewardPunishmentType(BasePerformanceIndicatorRewardPunishmentTypeTypeEnum.PUNISHMENT.getCode());
        } else {
            basePerformanceIndicator.setRewardPunishmentType(BasePerformanceIndicatorRewardPunishmentTypeTypeEnum.OTHER.getCode());
        }
        BasePerformanceIndicator query = new BasePerformanceIndicator();
        query.setCategoryCode(basePerformanceIndicator.getCategoryCode());
        query.setName(basePerformanceIndicator.getName());
        List<BasePerformanceIndicator> existingList = basePerformanceIndicatorMapper.selectBasePerformanceIndicatorList(query);
        if (CollUtil.isNotEmpty(existingList)) {
            basePerformanceIndicator.setUpdateTime(DateUtils.getNowDate());
            basePerformanceIndicator.setId(existingList.get(0).getId());
            return basePerformanceIndicatorMapper.updateBasePerformanceIndicator(basePerformanceIndicator);
        } else {
            basePerformanceIndicator.setCreateTime(DateUtils.getNowDate());
            basePerformanceIndicator.setCode(codeGeneratorUtil.getNextCodeGenerator());
            return basePerformanceIndicatorMapper.insertBasePerformanceIndicator(basePerformanceIndicator);
        }
    }

    /**
     * 修改考核指标
     *
     * @param basePerformanceIndicator 考核指标
     * @return 结果
     */
    @Override
    public int updateBasePerformanceIndicator(BasePerformanceIndicator basePerformanceIndicator) {
        basePerformanceIndicator.setUpdateTime(DateUtils.getNowDate());
        // 一级分类+二级分类
        BasePerformanceIndicatorCategory categoryQueryParam = new BasePerformanceIndicatorCategory();
        List<BasePerformanceIndicatorCategory> categoryList = basePerformanceIndicatorCategoryService.selectBasePerformanceIndicatorCategoryListTree(categoryQueryParam);
        if (ObjUtil.isNotNull(basePerformanceIndicator.getCategoryCodeOne())) {
            BasePerformanceIndicatorCategory categoryOne = categoryList.stream().filter(category -> StrUtil.equals(category.getCode(), basePerformanceIndicator.getCategoryCodeOne())).findFirst().orElse(null);
            if (ObjUtil.isNotNull(categoryOne)) {
                basePerformanceIndicator.setCategoryNameOne(categoryOne.getName());
                if (ObjUtil.isNotNull(basePerformanceIndicator.getCategoryCode()) && CollUtil.isNotEmpty(categoryOne.getChildren())) {
                    List<BasePerformanceIndicatorCategory> children = (List<BasePerformanceIndicatorCategory>) categoryOne.getChildren();
                    BasePerformanceIndicatorCategory categoryTwo = children.stream().filter(category -> StrUtil.equals(category.getCode(), basePerformanceIndicator.getCategoryCode())).findFirst().orElse(null);
                    if (ObjUtil.isNotNull(categoryTwo)) {
                        basePerformanceIndicator.setCategoryName(categoryTwo.getCode());
                    } else {
                        basePerformanceIndicator.setCategoryName(null);
                    }
                }
            } else {
                basePerformanceIndicator.setCategoryNameOne(null);
            }
        }
        // 判断奖罚类型
        if (ObjUtil.isNull(basePerformanceIndicator.getScore())) {
            basePerformanceIndicator.setRewardPunishmentType(BasePerformanceIndicatorRewardPunishmentTypeTypeEnum.OTHER.getCode());
        } else if (basePerformanceIndicator.getScore().compareTo(BigDecimal.ZERO) > 0) {
            basePerformanceIndicator.setRewardPunishmentType(BasePerformanceIndicatorRewardPunishmentTypeTypeEnum.REWARD.getCode());
        } else if (basePerformanceIndicator.getScore().compareTo(BigDecimal.ZERO) < 0) {
            basePerformanceIndicator.setRewardPunishmentType(BasePerformanceIndicatorRewardPunishmentTypeTypeEnum.PUNISHMENT.getCode());
        } else {
            basePerformanceIndicator.setRewardPunishmentType(BasePerformanceIndicatorRewardPunishmentTypeTypeEnum.OTHER.getCode());
        }
        return basePerformanceIndicatorMapper.updateBasePerformanceIndicator(basePerformanceIndicator);
    }

    /**
     * 批量删除考核指标
     *
     * @param ids 需要删除的考核指标主键
     * @return 结果
     */
    @Override
    public int deleteBasePerformanceIndicatorByIds(Long[] ids) {
        return basePerformanceIndicatorMapper.deleteBasePerformanceIndicatorByIds(ids);
    }

    /**
     * 删除考核指标信息
     *
     * @param id 考核指标主键
     * @return 结果
     */
    @Override
    public int deleteBasePerformanceIndicatorById(Long id) {
        return basePerformanceIndicatorMapper.deleteBasePerformanceIndicatorById(id);
    }

    /**
     * 导入考核指标列表
     *
     * @param list            数据列表
     * @param isUpdateSupport 是否更新支持，如果已存在，则进行更新数据
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String importData(List<BasePerformanceIndicator> list, boolean isUpdateSupport) {
        if (CollUtil.isEmpty(list)) {
            throw new ServiceException("导入考核指标数据不能为空！");
        }

        SysDictData leaveTypeQueryParam = new SysDictData();
        leaveTypeQueryParam.setDictType("base_performance_indicator_leave_type");
        List<SysDictData> leaveTypeList = sysDictDataService.selectDictDataList(leaveTypeQueryParam);
        Map<String, String> leaveTypeMap = leaveTypeList.stream().collect(Collectors.toMap(SysDictData::getDictLabel, SysDictData::getDictValue));

        BasePerformanceIndicatorCategory categoryQueryParam = new BasePerformanceIndicatorCategory();
        List<BasePerformanceIndicatorCategory> categoryList = basePerformanceIndicatorCategoryService.selectBasePerformanceIndicatorCategoryListTree(categoryQueryParam);

        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        for (BasePerformanceIndicator data : list) {
            // 判断奖罚类型
            if (ObjUtil.isNull(data.getScore())) {
                data.setRewardPunishmentType(BasePerformanceIndicatorRewardPunishmentTypeTypeEnum.OTHER.getCode());
            } else if (data.getScore().compareTo(BigDecimal.ZERO) > 0) {
                data.setRewardPunishmentType(BasePerformanceIndicatorRewardPunishmentTypeTypeEnum.REWARD.getCode());
            } else if (data.getScore().compareTo(BigDecimal.ZERO) < 0) {
                data.setRewardPunishmentType(BasePerformanceIndicatorRewardPunishmentTypeTypeEnum.PUNISHMENT.getCode());
            } else {
                data.setRewardPunishmentType(BasePerformanceIndicatorRewardPunishmentTypeTypeEnum.OTHER.getCode());
            }
            // 根据名称填充ID字段
            fillIdsByName(data, categoryList, leaveTypeMap);
            try {
                if (ObjUtil.isNull(data.getCategoryCode()) || ObjUtil.isNull(data.getCategoryName()) || ObjUtil.isNull(data.getCategoryCodeOne()) || ObjUtil.isNull(data.getCategoryNameOne())) {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、所属分类不能为空");
                    continue;
                }

                // 查询是否已存在（根据【所属一级分类编码+所属二级分类编码+指标名称】唯一）
                BasePerformanceIndicator queryParam = new BasePerformanceIndicator();
                queryParam.setCategoryCodeOne(data.getCategoryCodeOne());
                queryParam.setCategoryCode(data.getCategoryCode());
                queryParam.setName(data.getName());
                List<BasePerformanceIndicator> existingList = basePerformanceIndicatorMapper.selectBasePerformanceIndicatorStrictList(queryParam);

                if (CollUtil.isEmpty(existingList)) {
                    // 新增
                    data.setCode(codeGeneratorUtil.getNextCodeGenerator());
                    data.setCreateTime(DateUtils.getNowDate());
                    basePerformanceIndicatorMapper.insertBasePerformanceIndicator(data);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、所属一级分类名称【" + data.getCategoryNameOne() + "】、所属二级分类名称【" + data.getCategoryName() + "】、指标名称【" + data.getName() + "】导入成功");
                } else if (isUpdateSupport) {
                    // 更新
                    BasePerformanceIndicator old = existingList.get(0);
                    data.setId(old.getId());
                    data.setUpdateTime(DateUtils.getNowDate());
                    basePerformanceIndicatorMapper.updateBasePerformanceIndicator(data);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、所属一级分类名称【" + data.getCategoryNameOne() + "】、所属二级分类名称【" + data.getCategoryName() + "】、指标名称【" + data.getName() + "】更新成功");
                } else {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、所属一级分类名称【" + data.getCategoryNameOne() + "】、所属二级分类名称【" + data.getCategoryName() + "】、指标名称【" + data.getName() + "】已存在");
                }
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、所属一级分类名称【" + data.getCategoryNameOne() + "】、所属二级分类名称【" + data.getCategoryName() + "】、指标名称【" + data.getName() + "】导入失败：";
                failureMsg.append(msg + e.getMessage());
            }
        }

        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 根据名称填充ID字段
     *
     * @param data 考核指标数据
     */
    private void fillIdsByName(BasePerformanceIndicator data, List<BasePerformanceIndicatorCategory> categoryList, Map<String, String> leaveTypeMap) {
        // 一级分类+二级分类
        if (ObjUtil.isNotNull(data.getCategoryNameOne())) {
            BasePerformanceIndicatorCategory categoryOne = categoryList.stream().filter(category -> StrUtil.equals(category.getName(), data.getCategoryNameOne())).findFirst().orElse(null);
            if (ObjUtil.isNotNull(categoryOne)) {
                data.setCategoryCodeOne(categoryOne.getCode());
                if (ObjUtil.isNotNull(data.getCategoryName()) && CollUtil.isNotEmpty(categoryOne.getChildren())) {
                    List<BasePerformanceIndicatorCategory> children = (List<BasePerformanceIndicatorCategory>) categoryOne.getChildren();
                    BasePerformanceIndicatorCategory categoryTwo = children.stream().filter(category -> StrUtil.equals(category.getName(), data.getCategoryName())).findFirst().orElse(null);
                    if (ObjUtil.isNotNull(categoryTwo)) {
                        data.setCategoryCode(categoryTwo.getCode());
                    }
                }
            }
        }

        // 事/病假
        if (ObjUtil.isNotNull(data.getLeaveTypeDesc())) {
            data.setLeaveType(leaveTypeMap.get(data.getLeaveTypeDesc()));
        }
    }

    /**
     * 查询考核指标列表
     *
     * @param categoryCodeList 所属二级分类编码列表
     * @return 考核指标集合
     */
    @Override
    public List<BasePerformanceIndicator> selectBasePerformanceIndicatorListByCategoryCodeList(List<String> categoryCodeList) {
        if (CollUtil.isEmpty(categoryCodeList)) {
            return Collections.emptyList();
        }
        return basePerformanceIndicatorMapper.selectBasePerformanceIndicatorListByCategoryCodeList(categoryCodeList);
    }
}
