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

import cn.iocoder.yudao.module.llm.dal.dataobject.prompttemplatesapplications.PromptTemplatesApplicationsDO;
import cn.iocoder.yudao.module.llm.dal.dataobject.prompttemplatestags.PromptTemplatesTagsDO;
import cn.iocoder.yudao.module.llm.dal.mysql.prompttemplatesapplications.PromptTemplatesApplicationsMapper;
import cn.iocoder.yudao.module.llm.dal.mysql.prompttemplatestags.PromptTemplatesTagsMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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 cn.iocoder.yudao.module.llm.controller.admin.prompttemplates.vo.*;
import cn.iocoder.yudao.module.llm.dal.dataobject.prompttemplates.PromptTemplatesDO;
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.prompttemplates.PromptTemplatesMapper;

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

/**
 * Prompt 模板表，用于记录每个模板的信息 Service 实现类
 *
 * @author 华大大模型
 */
@Service
@Validated
public class PromptTemplatesServiceImpl implements PromptTemplatesService {

    @Resource
    private PromptTemplatesMapper promptTemplatesMapper;
    @Resource
    private PromptTemplatesTagsMapper promptTemplatesTagsMapper;
    @Resource
    private PromptTemplatesApplicationsMapper promptTemplatesApplicationsMapper;

    @Override
    public Long createPromptTemplates(PromptTemplatesSaveReqVO createReqVO) {
        this.isNameDuplicate(createReqVO.getName());
        // 插入
        PromptTemplatesDO promptTemplates = BeanUtils.toBean(createReqVO, PromptTemplatesDO.class);
        promptTemplates.setTemplateType(2);
        promptTemplatesMapper.insert(promptTemplates);
        List<String> tagIds = createReqVO.getTagIds();
        if(tagIds!=null && !tagIds.isEmpty()) {
            List<PromptTemplatesTagsDO> tagDOList = tagIds.stream()
                    .map(p->PromptTemplatesTagsDO.builder()
                            .tagId(Long.valueOf(p))
                            .promptTemplateId(promptTemplates.getId())
                            .build())
                    .collect(Collectors.toList());
            this.promptTemplatesTagsMapper.insertBatch(tagDOList, 1);
        }
        List<String> applicationIds = createReqVO.getApplicationIds();
        if(applicationIds!=null && !applicationIds.isEmpty()) {
            List<PromptTemplatesApplicationsDO> applicationDOList = applicationIds.stream()
                    .map(p->PromptTemplatesApplicationsDO.builder()
                            .applicationId(Long.valueOf(p))
                            .promptTemplateId(promptTemplates.getId())
                            .build())
                    .collect(Collectors.toList());
            this.promptTemplatesApplicationsMapper.insertBatch(applicationDOList, 1);
        }
        // 返回
        return promptTemplates.getId();
    }

    @Override
    public void updatePromptTemplates(PromptTemplatesSaveReqVO updateReqVO) {
        // 校验存在
        validatePromptTemplatesExists(updateReqVO.getId());
        // 更新
        PromptTemplatesDO updateObj = BeanUtils.toBean(updateReqVO, PromptTemplatesDO.class);
        promptTemplatesMapper.updateById(updateObj);
        Map<String, Object> deleteCondition = new HashMap<>(1);
        deleteCondition.put("prompt_template_id", updateReqVO.getId());
        this.promptTemplatesTagsMapper.deleteByMap(deleteCondition);
        List<String> tagIds = updateReqVO.getTagIds();
        if(tagIds!=null && !tagIds.isEmpty()) {
            List<PromptTemplatesTagsDO> tagDOList = tagIds.stream()
                    .map(p->PromptTemplatesTagsDO.builder()
                            .tagId(Long.valueOf(p))
                            .promptTemplateId(updateReqVO.getId())
                            .build())
                    .collect(Collectors.toList());
            this.promptTemplatesTagsMapper.insertBatch(tagDOList, 1);
        }
        this.promptTemplatesApplicationsMapper.deleteByMap(deleteCondition);
        List<String> applicationIds = updateReqVO.getApplicationIds();
        if(applicationIds!=null && !applicationIds.isEmpty()) {
            List<PromptTemplatesApplicationsDO> applicationDOList = applicationIds.stream()
                    .map(p->PromptTemplatesApplicationsDO.builder()
                            .applicationId(Long.valueOf(p))
                            .promptTemplateId(updateReqVO.getId())
                            .build())
                    .collect(Collectors.toList());
            this.promptTemplatesApplicationsMapper.insertBatch(applicationDOList, 1);
        }
    }

    @Override
    public void deletePromptTemplates(Long id) {
        // 校验存在
        validatePromptTemplatesExists(id);
        // 删除
        promptTemplatesMapper.deleteById(id);
        Map<String, Object> condition = new HashMap<>(1);
        condition.put("prompt_template_id", id);
        this.promptTemplatesTagsMapper.deleteByMap(condition);
        this.promptTemplatesApplicationsMapper.deleteByMap(condition);
    }

    private void validatePromptTemplatesExists(Long id) {
        if (promptTemplatesMapper.selectById(id) == null) {
            throw exception(PROMPT_TEMPLATES_NOT_EXISTS);
        }
    }

    private void isNameDuplicate(String name) {
        List<PromptTemplatesDO> templateDOList = this.promptTemplatesMapper.selectList("name", name);
        if(templateDOList!=null && templateDOList.size()>0) {
            throw exception(PROMPT_TEMPLATES_EXISTS);
        }
    }

    @Override
    public PromptTemplatesRespVO getPromptTemplates(Long id) {
        PromptTemplatesDO templatesDO = this.promptTemplatesMapper.selectById(id);
        if(templatesDO == null) {
            return null;
        }
        PromptTemplatesRespVO promptTemplates = BeanUtils.toBean(templatesDO, PromptTemplatesRespVO.class);
        List<PromptTemplatesTagsDO> tagDOList = this.promptTemplatesTagsMapper
                .selectList("prompt_template_id", id);
        if(tagDOList!=null && !tagDOList.isEmpty()) {
            List<String> tagIds = tagDOList.stream()
                    .map(p->p.getId().toString())
                    .collect(Collectors.toList());
            promptTemplates.setTagIds(tagIds);
        }
        List<PromptTemplatesApplicationsDO> applicationDOList = this.promptTemplatesApplicationsMapper
                .selectList("prompt_template_id", id);
        if(applicationDOList!=null && !applicationDOList.isEmpty()) {
            List<String> applicationIds = applicationDOList.stream()
                    .map(p->p.getId().toString())
                    .collect(Collectors.toList());
            promptTemplates.setApplicationIds(applicationIds);
        }
        return promptTemplates;
    }

    @Override
    public PageResult<PromptTemplatesRespVO> getPromptTemplatesPage(PromptTemplatesPageReqVO pageReqVO) {
        PageResult<PromptTemplatesDO> pageDoList = this.promptTemplatesMapper.selectPage(pageReqVO);
        PageResult<PromptTemplatesRespVO> pageRespList = BeanUtils.toBean(pageDoList, PromptTemplatesRespVO.class);
        List<PromptTemplatesRespVO> templatesRespList = pageRespList.getList();
        for(PromptTemplatesRespVO respVO : templatesRespList) {
            // TODO 使用量查询暂时设置为0
            respVO.setUsedCount(0);
            Long applicationCount = this.promptTemplatesApplicationsMapper.selectCount(
                    new QueryWrapper<PromptTemplatesApplicationsDO>()
                            .eq("prompt_template_id", respVO.getId()));
            respVO.setApplicationCount(Integer.valueOf(applicationCount.toString()));
        }
        return pageRespList;
    }

}
