package com.xjrsoft.module.evaluate.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.xjrsoft.common.enums.EvaluateTypeEnum;
import com.xjrsoft.common.exception.MyException;
import com.xjrsoft.module.evaluate.dto.*;
import com.xjrsoft.module.evaluate.entity.*;
import com.xjrsoft.module.evaluate.mapper.*;
import com.xjrsoft.module.evaluate.service.IEvaluateManageService;
import com.xjrsoft.module.evaluate.vo.*;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* @title: 评价管理
* @Author dzx
* @Date: 2024-01-16
* @Version 1.0
*/
@Service
@AllArgsConstructor
public class EvaluateManageServiceImpl extends MPJBaseServiceImpl<EvaluateManageMapper, EvaluateManage> implements IEvaluateManageService {
    private final EvaluateManageMapper evaluateManageMapper;

    private final EvaluateObjectMapper evaluateObjectMapper;
    private final EvaluateExecuterMapper evaluateExecuterMapper;
    private final EvaluateItemMapper evaluateItemMapper;
    private final EvaluateManageItemMapper evaluateManageItemMapper;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(EvaluateManage evaluateManage) {
        evaluateManage.setStatus(-1);
        evaluateManageMapper.insert(evaluateManage);

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(EvaluateManage evaluateManage) {
        //TODO 修改分两种情况，一种是还没有发布的修改，一种是已经发布的修改，已发布的修改只能修改结束时间。
        evaluateManageMapper.updateById(evaluateManage);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(List<Long> ids) {
        evaluateManageMapper.deleteBatchIds(ids);
        evaluateObjectMapper.delete(Wrappers.lambdaQuery(EvaluateObject.class).in(EvaluateObject::getEvaluateManageId, ids));
        evaluateExecuterMapper.delete(Wrappers.lambdaQuery(EvaluateExecuter.class).in(EvaluateExecuter::getEvaluateManageId, ids));
        return true;
    }

    @Override
    public Page<EvaluateManagePageVo> getPage(Page<EvaluateManagePageDto> page, EvaluateManagePageDto dto) {
        return evaluateManageMapper.getPage(page, dto);
    }

    @Override
    @Transactional
    public Boolean release(Long id) {
        EvaluateManage evaluateManage = evaluateManageMapper.selectById(id);
        if(evaluateManage == null){
            throw new MyException("未查询到数据，请检查传入的id是否正确");
        }
//        evaluateManageItemMapper.cloneItems(evaluateManage.getEvaluateTemplateId(), evaluateManage.getId(), StpUtil.getLoginIdAsLong());

        Long count = evaluateManageItemMapper.selectCount(
                new QueryWrapper<EvaluateManageItem>().lambda()
                        .eq(EvaluateManageItem::getEvaluateManageId, id)
        );

        if(count <= 0){
            //查询模板中的评价项
            List<EvaluateItem> evaluateItemList = evaluateItemMapper.selectList(
                    new QueryWrapper<EvaluateItem>().lambda()
                            .eq(EvaluateItem::getEvaluateTemplateId, evaluateManage.getEvaluateTemplateId())
            );
            //克隆一份，存到评价管理下面，可以采用sql语句
            for (EvaluateItem evaluateItem : evaluateItemList) {
                EvaluateManageItem manageItem = BeanUtil.toBean(evaluateItem, EvaluateManageItem.class);
                manageItem.setId(null);
                manageItem.setEvaluateManageId(evaluateManage.getId());
                manageItem.setEvaluateItemId(evaluateItem.getId());
                manageItem.setCreateDate(new Date());
                manageItem.setCreateUserId(StpUtil.getLoginIdAsLong());
                evaluateManageItemMapper.insert(manageItem);
            }
        }

        //添加评价提交记录
        evaluateManageMapper.insertEvaluateSubmitRecord(id);

        //将评价管理状态改为进行中
        evaluateManage.setStatus(1);
        evaluateManage.setModifyDate(new Date());
        evaluateManage.setModifyUserId(StpUtil.getLoginIdAsLong());

        evaluateManageMapper.updateById(evaluateManage);
        return true;
    }

    public Page<MobileIndexPageVo> getMobileIndexPage(Page<EvaluateWritePageDto> page, MobileIndexPageDto dto) {
        Page<MobileIndexPageVo> mobileIndexPage = evaluateManageMapper.getMobileIndexPage(page, dto);
        return mobileIndexPage;
    }

    @Override
    public Page<MobileResultPageVo> getMobileResultPage(Page<EvaluateWritePageDto> page, MobileResultPageDto dto){
        Page<MobileResultPageVo> mobileResultPage = evaluateManageMapper.getMobileResultPage(page, dto);
        if(mobileResultPage.getRecords() != null){
            //获取已经评价记录的评价总分
            //评价提交记录的id集合
            List<String> submitRecordIdList = new ArrayList<>();
            for (MobileResultPageVo mobileResultPageVo : mobileResultPage.getRecords()) {
                if(mobileResultPageVo.getEvaluateStatus() == 2){
                    submitRecordIdList.add(mobileResultPageVo.getEvaluateSubmitRecordId());
                }
            }
            if(submitRecordIdList.size() > 0){
                //获取当前用户，当前评价管理下的所有已评对象的总分（学生评价班主任）或者是综合指数（教官评价班级）
                List<EvaluateManageScoreVo> evaluateManageScoreVoList = evaluateManageMapper.getScoreList(new EvaluateManageScoreDto(){{
                    setSubmitRecordIdList(submitRecordIdList);
                }});

                if(evaluateManageScoreVoList.size() > 0){
                    Map<String, EvaluateManageScoreVo> scoreBySubmitRecordId = evaluateManageScoreVoList.stream()
                            .collect(Collectors.toMap(EvaluateManageScoreVo::getSubmitRecordId, Function.identity()));

                    //将对应的分数给到对应的记录
                    for (MobileResultPageVo mobileResultPageVo : mobileResultPage.getRecords()) {
                        //评价类型是学生评价班主任
                        if(mobileResultPageVo.getEvaluateType().equals(EvaluateTypeEnum.STUDENT_EVALUATE_HEAD_TEACHER.getCode()) && scoreBySubmitRecordId.get(mobileResultPageVo.getEvaluateSubmitRecordId()) != null){
                            mobileResultPageVo.setTotalScore((double)scoreBySubmitRecordId.get(mobileResultPageVo.getEvaluateSubmitRecordId()).getTotalScore());
                            mobileResultPageVo.setItemCount(scoreBySubmitRecordId.get(mobileResultPageVo.getEvaluateSubmitRecordId()).getItemCount());
                        }

                        //评价类型是教官评级班级
                        if(mobileResultPageVo.getEvaluateType().equals(EvaluateTypeEnum.DRILLMASTER_EVALUATE_CLASS.getCode()) && scoreBySubmitRecordId.get(mobileResultPageVo.getEvaluateSubmitRecordId()) != null){
                            ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
                            String zonghezhishu = "totalScore/itemCount";
                            int totalScore = scoreBySubmitRecordId.get(mobileResultPageVo.getEvaluateSubmitRecordId()).getTotalScore();
                            int itemCount = scoreBySubmitRecordId.get(mobileResultPageVo.getEvaluateSubmitRecordId()).getItemCount();
                            double res = 0;
                            String newStr1 = zonghezhishu.replace("totalScore", ""+totalScore);
                            String newStr2 = newStr1.replace("itemCount", ""+itemCount);
                            try{
                                res = Double.parseDouble(engine.eval(newStr2).toString());
                            }catch (ScriptException s){

                            }
                            // 创建一个DecimalFormat对象，指定小数位数为两位
                            DecimalFormat decimalFormat = new DecimalFormat("#.00");
                            // 格式化double值为字符串
                            String formattedNumber = decimalFormat.format(res);
                            mobileResultPageVo.setTotalScore(Double.valueOf(formattedNumber));
                            mobileResultPageVo.setItemCount(scoreBySubmitRecordId.get(mobileResultPageVo.getEvaluateSubmitRecordId()).getItemCount());
                        }
                    }
                }
            }
        }
        return mobileResultPage;
    }

    @Override
    public List<DrillEvaluateClassListVo> getDrillEvaluateClassList(DrillEvaluateClassListDto dto) {
        dto.setLoginUserId(StpUtil.getLoginIdAsLong());
        dto.setTodayDate(LocalDate.now().toString());
        return evaluateManageMapper.getDrillEvaluateClassList(dto);
    }

    @Override
    public EvaluateWriteVo getWriteInfo(Long id) {
        return evaluateManageMapper.getWriteInfo(id);
    }

    @Override
    public List<EvaluateManageItemVo> getItemList(Long id) {
        return evaluateManageMapper.getItemList(id);
    }

    @Override
    public List<EvaluateManageItemVo> getResultList(ResultListDto dto) {
        return evaluateManageMapper.getResultList(dto);
    }

}
