package cn.iocoder.yudao.module.llm.service.modelassesstaskmanual;

import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.llm.controller.admin.dataset.vo.DatasetAnswerRespVO;
import cn.iocoder.yudao.module.llm.controller.admin.dataset.vo.DatasetQuestionPageReqVO;
import cn.iocoder.yudao.module.llm.controller.admin.modelassesstaskmanual.manualAnnoVo.ManualModelAnnoRespVO;
import cn.iocoder.yudao.module.llm.controller.admin.modelassesstaskmanual.manualAnnoVo.ManualModelAnswerPageReqVO;
import cn.iocoder.yudao.module.llm.controller.admin.modelassesstaskmanual.manualAnnoVo.ManualModelAnswerSaveReqVO;
import cn.iocoder.yudao.module.llm.controller.admin.modelassesstaskmanual.vo.LabelInformationVO;
import cn.iocoder.yudao.module.llm.controller.admin.modelassesstaskmanual.vo.ManualAssessmentPageRespVO;
import cn.iocoder.yudao.module.llm.controller.admin.modelassesstaskmanual.vo.ModelAssessTaskDimensionRespVO;
import cn.iocoder.yudao.module.llm.controller.admin.modelassesstaskmanual.vo.ModelAssessTaskManualPageReqVO;
import cn.iocoder.yudao.module.llm.controller.admin.modelassesstaskmanual.vo.ModelAssessTaskManualRespVO;
import cn.iocoder.yudao.module.llm.dal.dataobject.dataset.DatasetAnswerDO;
import cn.iocoder.yudao.module.llm.dal.dataobject.dataset.DatasetQuestionDO;
import cn.iocoder.yudao.module.llm.dal.dataobject.modelassesstaskmanual.ManualModelAnnoDO;
import cn.iocoder.yudao.module.llm.dal.dataobject.modelassesstaskmanual.ManualModelAnswerDO;
import cn.iocoder.yudao.module.llm.dal.dataobject.modelservice.ModelServiceDO;
import cn.iocoder.yudao.module.llm.dal.mysql.dataset.DatasetAnswerMapper;
import cn.iocoder.yudao.module.llm.dal.mysql.dataset.DatasetQuestionMapper;
import cn.iocoder.yudao.module.llm.dal.mysql.modelassesstaskmanual.*;
import cn.iocoder.yudao.module.llm.service.dataset.DatasetQuestionService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springdoc.core.GenericResponseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;


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

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.llm.enums.ErrorCodeConstants.*;

/**
 * 模型评估人工标注 模型回答 Service 实现类
 *
 * @author 华大大模型
 */
@Service
@Validated
public class ManualModelAnswerServiceImpl implements ManualModelAnswerService {

    @Resource
    private ManualModelAnswerMapper manualModelAnswerMapper;
    @Resource
    private ModelAssessTaskManualService modelAssessTaskManualService;
    @Resource
    private ManualModelAnnoMapper manualModelAnnoMapper;
    @Resource
    private ModelAssessTaskDimensionMapper modelAssessTaskDimensionMapper;
    @Resource
    private ModelAssessTaskManualMapper modelAssessTaskManualMapper;
    @Resource
    private DatasetQuestionService datasetQuestionService;
    @Resource
    private DatasetQuestionMapper datasetQuestionMapper;
    @Resource
    private DatasetAnswerMapper datasetAnswerMapper;

    /**
     * 分页进行查询
     * @param pageReqVO
     * @return
     */
    @Override
    public PageResult<ManualAssessmentPageRespVO> getManualAssessment(ManualModelAnswerPageReqVO pageReqVO) {
        ModelAssessTaskManualRespVO modelAssessTaskManual = modelAssessTaskManualService.getModelAssessTaskManual(pageReqVO.getManalTaskId());
        PageResult<ManualAssessmentPageRespVO> result = new PageResult<>();
        PageResult<ManualModelAnswerDO> modelAnswerDOPageResult = manualModelAnswerMapper.selectPage(pageReqVO);
        List<ManualAssessmentPageRespVO> res = new ArrayList<>();
        if(!CollectionUtils.isAnyEmpty(modelAnswerDOPageResult.getList())){
            modelAnswerDOPageResult.getList().forEach(modelAnswerDO -> {
                ManualAssessmentPageRespVO resp = BeanUtils.toBean(modelAssessTaskManual, ManualAssessmentPageRespVO.class);
                DatasetQuestionDO datasetQuestionDO = datasetQuestionMapper.selectById(modelAnswerDO.getQuestionId());

                if (datasetQuestionDO==null){
                    throw exception(QUESTION_NOT_EXISTS);
                }

                List<DatasetAnswerDO> datasetAnswerDOS = datasetAnswerMapper.selectList(new LambdaQueryWrapper<>(DatasetAnswerDO.class).eq(DatasetAnswerDO::getQuestionId, modelAnswerDO.getQuestionId()));
                String question = datasetQuestionDO.getQuestion();
                if (StringUtils.isBlank(question)){
                    throw exception(QUESTION_NOT_EXISTS);
                }
                resp.setQuestion(question);
                resp.setSystem(datasetQuestionDO.getSystem());
                resp.setAnswers(BeanUtils.toBean(datasetAnswerDOS, DatasetAnswerRespVO.class));
                resp.setModelAnswer(modelAnswerDO.getModelAnswer());
                resp.setId(modelAnswerDO.getId());
                resp.setStatus(modelAnswerDO.getStatus());
                resp.setManalTaskId(modelAnswerDO.getManalTaskId());
                if (!CollectionUtils.isAnyEmpty(modelAnswerDO.getReqRespVos())){
                    resp.setReqRespVos(modelAnswerDO.getReqRespVos());
                }else {
                    if (!CollectionUtils.isAnyEmpty(modelAssessTaskManual.getDimensions())){
                        List<HashMap<String, Object>> map = new ArrayList<>();
                        HashMap<String, Object> report = new HashMap<>();
                        modelAssessTaskManual.getDimensions().forEach(dimension -> {
                            HashMap<String, Object> map1 = new HashMap<>();
                            map1.put("label", dimension.getDimensionName());
                            map1.put("score", 0);
                            map.add(map1);
                            report.put(dimension.getDimensionName(),0);
                        });
                        resp.setReqRespVos(map);
                    }
                }
                res.add(resp);
            });
        }
        result.setList(res);
        result.setTotal(modelAnswerDOPageResult.getTotal());
        return result;
    }

    @Override
    public List<String> queryTheEvaluationType( ManualModelAnswerPageReqVO pageReqVO) {
        LambdaQueryWrapper<ManualModelAnswerDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ManualModelAnswerDO::getManalTaskId,pageReqVO.getManalTaskId())
                .eq(ManualModelAnswerDO::getStatus,2)
                .isNotNull(ManualModelAnswerDO::getReqRespVos);
        List<ManualModelAnswerDO> manualModelAnswerDOS = manualModelAnswerMapper.selectList(wrapper);
        if (ObjectUtil.isAllEmpty(manualModelAnswerDOS)){
            return null;
        }
        List<LabelInformationVO> bean = BeanUtils.toBean(manualModelAnswerDOS.get(0).getReqRespVos(), LabelInformationVO.class);
        List<String> collect = bean.stream().map(LabelInformationVO::getLabel).collect(Collectors.toList());
        return collect;
    }

    /**
     * 模型回答人工标注
     * @param reqRespVo
     */
    @Override
    public void annoManualModelAnswer(List<ManualModelAnswerSaveReqVO>  reqRespVo) {
        List<ManualModelAnswerDO> modelAnswerDOS = BeanUtils.toBean(reqRespVo, ManualModelAnswerDO.class);
        if (!CollectionUtils.isAnyEmpty(modelAnswerDOS)) {
            modelAnswerDOS.forEach(modelAnswerDO -> {
                modelAnswerDO.setStatus(2);
                manualModelAnswerMapper.updateById(modelAnswerDO);

            });
            // 标注进度修改
            LambdaQueryWrapper<ManualModelAnswerDO> wrapper = new LambdaQueryWrapper<ManualModelAnswerDO>()
                    .eq(ManualModelAnswerDO::getManalTaskId, reqRespVo.get(0).getManalTaskId());
            Long sumCount = manualModelAnswerMapper.selectCount(wrapper);
            wrapper.eq(ManualModelAnswerDO::getStatus, 2);
            Long annoCount = manualModelAnswerMapper.selectCount(wrapper);
            double ratio = sumCount == 0 ? 0 : ((double) annoCount / sumCount) * 100;
            Integer formattedRatio = ratio == 0 ? 0 : (int) ratio;
            Integer status = formattedRatio == 100 ? 4 : 2;
            modelAssessTaskManualMapper.updateStatus(reqRespVo.get(0).getManalTaskId(), formattedRatio, status);

        }

    }

    @Override
    public Long createManualModelAnswer(ManualModelAnswerSaveReqVO createReqVO) {
        // 插入
        ManualModelAnswerDO manualModelAnswer = BeanUtils.toBean(createReqVO, ManualModelAnswerDO.class);
        manualModelAnswerMapper.insert(manualModelAnswer);
        // 返回
        return manualModelAnswer.getId();
    }

    @Override
    public void updateManualModelAnswer(ManualModelAnswerSaveReqVO updateReqVO) {
        // 校验存在
        validateManualModelAnswerExists(updateReqVO.getId());
        // 更新
        ManualModelAnswerDO updateObj = BeanUtils.toBean(updateReqVO, ManualModelAnswerDO.class);
        manualModelAnswerMapper.updateById(updateObj);
    }

    @Override
    public void deleteManualModelAnswer(Long id) {
        // 校验存在
        validateManualModelAnswerExists(id);
        // 删除
        manualModelAnswerMapper.deleteById(id);
    }

    private void validateManualModelAnswerExists(Long id) {
        if (manualModelAnswerMapper.selectById(id) == null) {
            throw exception(MANUAL_MODEL_ANSWER_NOT_EXISTS);
        }
    }

    @Override
    public ManualModelAnswerDO getManualModelAnswer(Long id) {
        return manualModelAnswerMapper.selectById(id);
    }

    @Override
    public PageResult<ManualModelAnswerDO> getManualModelAnswerPage(ManualModelAnswerPageReqVO pageReqVO) {
        return manualModelAnswerMapper.selectPage(pageReqVO);
    }


}
