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

import cn.iocoder.yudao.module.llm.dal.dataobject.dataset.DatasetDO;
import cn.iocoder.yudao.module.llm.dal.dataobject.modelassessstoplist.ModelAssessStoplistDO;
import cn.iocoder.yudao.module.llm.dal.dataobject.modelassesstaskmanual.ModelAssessDimensionDO;
import cn.iocoder.yudao.module.llm.dal.dataobject.modelassesstaskmanual.ModelAssessTaskDimensionDO;
import cn.iocoder.yudao.module.llm.dal.dataobject.modelservice.ModelServiceDO;
import cn.iocoder.yudao.module.llm.dal.mysql.dataset.DatasetMapper;
import cn.iocoder.yudao.module.llm.dal.mysql.modelassesstaskmanual.ModelAssessDimensionMapper;
import cn.iocoder.yudao.module.llm.dal.mysql.modelassesstaskmanual.ModelAssessTaskDimensionMapper;
import cn.iocoder.yudao.module.llm.dal.mysql.modelservice.ModelServiceMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import cn.iocoder.yudao.module.llm.controller.admin.modelassesstaskmanual.vo.*;
import cn.iocoder.yudao.module.llm.dal.dataobject.modelassesstaskmanual.ModelAssessTaskManualDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.llm.dal.mysql.modelassesstaskmanual.ModelAssessTaskManualMapper;

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 ModelAssessTaskManualServiceImpl implements ModelAssessTaskManualService {

    @Resource
    private ModelAssessTaskManualMapper modelAssessTaskManualMapper;
    @Resource
    private ModelAssessTaskDimensionMapper modelAssessTaskDimensionMapper;
    @Resource
    private ModelServiceMapper modelServiceMapper;
    @Resource
    private DatasetMapper datasetMapper;
    @Resource
    private ModelAssessDimensionMapper modelAssessDimensionMapper;

    @Override
    public Long createModelAssessTaskManual(ModelAssessTaskManualSaveReqVO createReqVO) {
        // 插入
        ModelAssessTaskManualDO modelAssessTaskManual = BeanUtils.toBean(createReqVO, ModelAssessTaskManualDO.class);
        modelAssessTaskManualMapper.insert(modelAssessTaskManual);
        List<ModelAssessTaskDimensionSaveReqVO> dimensions = createReqVO.getDimensions();
        if (!CollectionUtils.isEmpty(dimensions)){
            dimensions.stream().forEach(dimension -> {
                dimension.setTaskId(modelAssessTaskManual.getId());
                ModelAssessTaskDimensionDO modelAssessTaskDimensionDO = BeanUtils.toBean(dimension,ModelAssessTaskDimensionDO.class);
                modelAssessTaskDimensionMapper.insert(modelAssessTaskDimensionDO);
            });
        }
        // 返回
        return modelAssessTaskManual.getId();
    }

    @Override
    public void updateModelAssessTaskManual(ModelAssessTaskManualSaveReqVO updateReqVO) {
        // 校验存在
        validateModelAssessTaskManualExists(updateReqVO.getId());
        // 更新
        ModelAssessTaskManualDO updateObj = BeanUtils.toBean(updateReqVO, ModelAssessTaskManualDO.class);
        List<ModelAssessTaskDimensionSaveReqVO> dimensions = updateReqVO.getDimensions();
        if (!CollectionUtils.isEmpty(dimensions)) {
            List<Long> dimensionsIds = dimensions.stream()
                    .filter(dimension -> dimension.getId() != null)
                    .map(dimension -> dimension.getId()).collect(Collectors.toList());
            LambdaQueryWrapper<ModelAssessTaskDimensionDO> wrapper = new LambdaQueryWrapper<ModelAssessTaskDimensionDO>()
                    .eq(ModelAssessTaskDimensionDO::getTaskId, updateReqVO.getId());
            if (!CollectionUtils.isEmpty(dimensionsIds)) {
                wrapper.notIn(ModelAssessTaskDimensionDO::getId, dimensionsIds);
            }
            modelAssessTaskDimensionMapper.delete(wrapper);
            dimensions.stream().forEach(dimension -> {
                ModelAssessTaskDimensionDO modelAssessTaskDimensionDO = BeanUtils.toBean(dimension, ModelAssessTaskDimensionDO.class);
                modelAssessTaskDimensionMapper.insertOrUpdate(modelAssessTaskDimensionDO);
            });
        }

        modelAssessTaskManualMapper.updateById(updateObj);
    }

    @Override
    public void deleteModelAssessTaskManual(Long id) {
        // 校验存在
        validateModelAssessTaskManualExists(id);
        LambdaUpdateWrapper<ModelAssessTaskManualDO> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(ModelAssessTaskManualDO::getId, id);
        wrapper.set(ModelAssessTaskManualDO::getDeleted,true);
        // 删除
        modelAssessTaskManualMapper.update(null, wrapper);
    }

    private void validateModelAssessTaskManualExists(Long id) {
        if (modelAssessTaskManualMapper.selectById(id) == null) {
            throw exception(MODEL_ASSESS_TASK_MANUAL_NOT_EXISTS);
        }
    }

    @Override
    public ModelAssessTaskManualRespVO getModelAssessTaskManual(Long id) {
        ModelAssessTaskManualDO modelAssessTaskManual = modelAssessTaskManualMapper.selectById(id);
        ModelAssessTaskManualRespVO result = BeanUtils.toBean(modelAssessTaskManual, ModelAssessTaskManualRespVO.class);
        List<ModelAssessTaskDimensionDO> modelAssessTaskDimensionDOS = modelAssessTaskDimensionMapper.selectList(new LambdaQueryWrapper<ModelAssessTaskDimensionDO>()
                .eq(ModelAssessTaskDimensionDO::getTaskId, id)
                .eq(ModelAssessTaskDimensionDO::getDeleted, false));
        List<ModelAssessTaskDimensionRespVO> modelAssessTaskDimensionRespVOS = BeanUtils.toBean(modelAssessTaskDimensionDOS, ModelAssessTaskDimensionRespVO.class);
        // 提取id
        List<Long> dimensionIds = modelAssessTaskDimensionDOS.stream().map(ModelAssessTaskDimensionDO::getDimensionId).collect(Collectors.toList());
        // 查询模型评估维度 将维度名称返回
        if (!CollectionUtils.isEmpty(dimensionIds)){
            List<ModelAssessDimensionDO> modelAssessDimensionDOS = modelAssessDimensionMapper.selectList(new LambdaQueryWrapper<ModelAssessDimensionDO>()
                    .in(ModelAssessDimensionDO::getId, dimensionIds));
            Map<Long, ModelAssessDimensionDO> longModelDimesionDOMap = cn.iocoder.yudao.framework.common.util.collection.
                    CollectionUtils.convertMap(modelAssessDimensionDOS, ModelAssessDimensionDO::getId);
            modelAssessTaskDimensionRespVOS.stream().forEach(
                    modelAssessTaskDimensionRespVO -> {
                        ModelAssessDimensionDO modelAssessDimensionDO = longModelDimesionDOMap.get(modelAssessTaskDimensionRespVO.getDimensionId());
                        if (modelAssessDimensionDO != null){
                            modelAssessTaskDimensionRespVO.setDimensionName(modelAssessDimensionDO.getDimension());
                        }
                    }
            );
        }
        result.setDimensions(modelAssessTaskDimensionRespVOS);
        ModelServiceDO modelServiceDO = modelServiceMapper.selectById(modelAssessTaskManual.getModelService());
        if (modelServiceDO != null){
            result.setModelServiceName(modelServiceDO.getServiceName());
        }
        DatasetDO datasetDO = datasetMapper.selectById(modelAssessTaskManual.getDataset());
        if (datasetDO != null){
            result.setDatasetName(datasetDO.getDatasetName());
        }
        return result;
    }

    @Override
    public PageResult<ModelAssessTaskManualRespVO> getModelAssessTaskManualPage1(ModelAssessTaskManualPageReqVO pageReqVO) {
        PageResult<ModelAssessTaskManualDO> modelAssessTaskManualDOPageResult = modelAssessTaskManualMapper.selectPage(pageReqVO);
        PageResult<ModelAssessTaskManualRespVO> result = BeanUtils.toBean(modelAssessTaskManualDOPageResult, ModelAssessTaskManualRespVO.class);
        if (CollectionUtils.isNotEmpty(result.getList())){
            List<Long> serviceIds =  modelAssessTaskManualDOPageResult.getList().stream().map(ModelAssessTaskManualDO::getModelService).collect(Collectors.toList());
            LambdaQueryWrapper<ModelServiceDO> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(ModelServiceDO::getId,serviceIds);
            List<ModelServiceDO> modelServiceDOS = modelServiceMapper.selectList(wrapper);
            Map<Long, ModelServiceDO> longModelServiceDOMap = cn.iocoder.yudao.framework.common.util.collection.
                    CollectionUtils.convertMap(modelServiceDOS, ModelServiceDO::getId);
            result.getList().stream().forEach(modelAssessTaskManualRespVO -> {
                ModelServiceDO modelServiceDO = longModelServiceDOMap.get(modelAssessTaskManualRespVO.getModelService());
                if(modelServiceDO != null){
                    modelAssessTaskManualRespVO.setModelServiceName(modelServiceDO.getServiceName());
                }
            });
        }
        return result;
    }
    @Override
    public PageResult<ModelAssessTaskManualDO> getModelAssessTaskManualPage(ModelAssessTaskManualPageReqVO pageReqVO) {
        return modelAssessTaskManualMapper.selectPage(pageReqVO);
    }

}