package com.changhu.module.assessmentCriteria.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.lang.func.LambdaUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.changhu.common.db.enums.EnterprisesUnitType;
import com.changhu.common.exception.MessageException;
import com.changhu.common.pojo.vo.SelectNodeVo;
import com.changhu.common.utils.SnowFlakeIdUtil;
import com.changhu.module.assessmentCriteria.mapper.CkProjectMapper;
import com.changhu.module.assessmentCriteria.pojo.entity.*;
import com.changhu.module.assessmentCriteria.pojo.params.*;
import com.changhu.module.assessmentCriteria.pojo.queryParams.CkProjectPagerQueryParams;
import com.changhu.module.assessmentCriteria.pojo.vo.AssessmentCriteriaRuleVo;
import com.changhu.module.assessmentCriteria.pojo.vo.CkProjectDetailTableVo;
import com.changhu.module.assessmentCriteria.pojo.vo.CkProjectPagerVo;
import com.changhu.module.assessmentCriteria.service.AssessmentCriteriaService;
import com.changhu.support.mybatisplus.pojo.entity.BaseEntity;
import com.changhu.support.mybatisplus.pojo.params.PageParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 20252
 * @createTime 2024/11/6 上午10:08
 * @desc AssessmentCriteriaServiceImpl...
 */
@Service
public class AssessmentCriteriaServiceImpl implements AssessmentCriteriaService {

    @Autowired
    private CkProjectMapper ckProjectMapper;

    @Override
    public List<SelectNodeVo<Long>> assessmentCriteriaListByType(EnterprisesUnitType type) {
        return Db.lambdaQuery(CkProject.class).eq(CkProject::getType, type).list()
                .stream()
                .map(e -> SelectNodeVo.<Long>builder()
                        .value(e.getSnowFlakeId())
                        .label(e.getName())
                        .extData(Dict.create()
                                .set(LambdaUtil.getFieldName(CkProject::getRemark), e.getRemark())
                                .set(LambdaUtil.getFieldName(CkProject::getTotalScore), e.getTotalScore())
                                .set(LambdaUtil.getFieldName(CkProject::getType), e.getType())
                                .set(LambdaUtil.getFieldName(CkProject::getCreateTime), e.getCreateTime())
                        )
                        .build())
                .toList();
    }

    @Override
    public List<AssessmentCriteriaRuleVo> assessmentCriteriaRulesByCkProjectId(Long ckProjectId) {
        //根据考核项目拿到考核分组
        List<AssessmentCriteriaRuleVo> groupList = Db.lambdaQuery(CkGroup.class)
                .eq(CkGroup::getCkProjectId, ckProjectId)
                .orderByAsc(BaseEntity::getCreateTime)
                .list()
                .stream()
                .map(e -> {
                    AssessmentCriteriaRuleVo assessmentCriteriaRuleVo = new AssessmentCriteriaRuleVo();
                    assessmentCriteriaRuleVo.setSnowFlakeId(e.getSnowFlakeId());
                    assessmentCriteriaRuleVo.setName(e.getName());
                    assessmentCriteriaRuleVo.setTotalScore(e.getTotalScore());
                    assessmentCriteriaRuleVo.setRemark(e.getRemark());
                    return assessmentCriteriaRuleVo;
                }).toList();
        if (groupList.isEmpty()) {
            throw new MessageException("该考核项目内暂未制定规则");
        }
        //根据考核分组拿到考核项
        List<AssessmentCriteriaRuleVo.Item> itemList = Db.lambdaQuery(CkItem.class)
                .in(CkItem::getCkGroupId, groupList.stream().map(AssessmentCriteriaRuleVo::getSnowFlakeId).toList())
                .orderByAsc(BaseEntity::getCreateTime)
                .list()
                .stream()
                .map(e -> {
                    AssessmentCriteriaRuleVo.Item item = new AssessmentCriteriaRuleVo.Item();
                    item.setSnowFlakeId(e.getSnowFlakeId());
                    item.setCkGroupId(e.getCkGroupId());
                    item.setName(e.getName());
                    item.setType(e.getType());
                    item.setRemark(e.getRemark());
                    return item;
                }).toList();
        if (itemList.isEmpty()) {
            throw new MessageException("该考核项目内未制定考核项");
        }
        //根据考核项拿到考核标准
        List<AssessmentCriteriaRuleVo.Standard> standardList = Db.lambdaQuery(CkStandard.class)
                .in(CkStandard::getCkItemId, itemList.stream().map(AssessmentCriteriaRuleVo.Item::getSnowFlakeId).toList())
                .orderByAsc(BaseEntity::getCreateTime)
                .list().stream()
                .map(e -> {
                    AssessmentCriteriaRuleVo.Standard standard = new AssessmentCriteriaRuleVo.Standard();
                    standard.setSnowFlakeId(e.getSnowFlakeId());
                    standard.setCkItemId(e.getCkItemId());
                    standard.setName(e.getName());
                    standard.setDeductionPoints(e.getDeductionPoints());
                    return standard;
                }).toList();
        if (standardList.isEmpty()) {
            throw new MessageException("该考核项目内未制定考核标准");
        }
        //先将考核标准塞到考核项内
        Map<Long, List<AssessmentCriteriaRuleVo.Standard>> standardMap = standardList.stream().collect(Collectors.groupingBy(AssessmentCriteriaRuleVo.Standard::getCkItemId));
        itemList.forEach(e -> e.setStandardList(standardMap.get(e.getSnowFlakeId())));
        //将考核项塞到考核分组内
        Map<Long, List<AssessmentCriteriaRuleVo.Item>> itemMap = itemList.stream().collect(Collectors.groupingBy(AssessmentCriteriaRuleVo.Item::getCkGroupId));
        groupList.forEach(e -> e.setItemList(itemMap.get(e.getSnowFlakeId())));

        return groupList;
    }

    @Override
    public Page<CkProjectPagerVo> ckProjectPagerVoPager(PageParams<CkProjectPagerQueryParams, CkProjectPagerVo> queryParams) {
        return ckProjectMapper.pager(queryParams.getPage(), queryParams.getParams());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveOrUpdateCkProject(CkProjectSaveOrUpdateParams params) {
        boolean b = Db.saveOrUpdate(BeanUtil.copyProperties(params, CkProject.class));
        if (!b) {
            throw new MessageException();
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteCkProjectById(Long ckProjectId) {
        boolean b = Db.removeById(ckProjectId, CkProject.class);
        if (!b) {
            throw new MessageException();
        }
    }

    @Override
    public List<CkProjectDetailTableVo> ckProjectDetail(Long ckProjectId) {
        return ckProjectMapper.ckProjectDetail(ckProjectId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveOrUpdateCkGroup(CkGroupSaveOrUpdateParams params) {
        boolean b = Db.saveOrUpdate(BeanUtil.copyProperties(params, CkGroup.class));
        if (!b) {
            throw new MessageException();
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveOrUpdateCkItem(CkItemSaveOrUpdateParams params) {
        boolean b = Db.saveOrUpdate(BeanUtil.copyProperties(params, CkItem.class));
        if (!b) {
            throw new MessageException();
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveOrUpdateCkStandard(CkStandardSaveOrUpdateParams params) {
        boolean b = Db.saveOrUpdate(BeanUtil.copyProperties(params, CkStandard.class));
        if (!b) {
            throw new MessageException();
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void submitAssessmentRecord(AssessmentRecordParams params) {
        CkAssessmentRecord ckAssessmentRecord = CkAssessmentRecord.builder()
                .snowFlakeId(SnowFlakeIdUtil.snowflakeId())
                .enterprisesUnitId(params.getEnterprisesUnitId())
                .ckProjectId(params.getCkProjectId())
                .assessmentUserSignature(params.getAssessmentUserSignature())
                .byAssessmentEnterprisesUnitUserSignature(params.getByAssessmentEnterprisesUnitUserSignature())
                .remark(params.getRemark())
                .build();
        //保存考核记录
        boolean save = Db.save(ckAssessmentRecord);
        if (!save) {
            throw new MessageException();
        }
        List<AssessmentRecordParams.RecordDetailParams> assessmentRecordDetails = params.getAssessmentRecordDetails();
        if (CollUtil.isEmpty(assessmentRecordDetails)) {
            return;
        }
        //保存考核明细
        boolean b = Db.saveBatch(assessmentRecordDetails.stream()
                .map(e -> CkAssessmentRecordDetails.builder()
                        .ckAssessmentRecordId(ckAssessmentRecord.getSnowFlakeId())
                        .ckProjectId(ckAssessmentRecord.getCkProjectId())
                        .ckGroupId(e.getCkGroupId())
                        .ckItemId(e.getCkItemId())
                        .ckStandardId(e.getCkStandardId())
                        .build())
                .toList());
        if (!b) {
            throw new MessageException();
        }
    }
}
