package com.easyproject.system.service.chatAI.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.coze.openapi.client.bots.PublishBotReq;
import com.coze.openapi.client.bots.PublishBotResp;
import com.coze.openapi.client.bots.UpdateBotReq;
import com.coze.openapi.client.bots.UpdateBotResp;
import com.coze.openapi.client.bots.model.BotKnowledge;
import com.coze.openapi.client.bots.model.BotOnboardingInfo;
import com.coze.openapi.client.bots.model.BotPromptInfo;
import com.coze.openapi.client.common.pagination.PageResp;
import com.coze.openapi.client.dataset.ListDatasetReq;
import com.coze.openapi.client.dataset.model.Dataset;
import com.coze.openapi.client.files.UploadFileReq;
import com.coze.openapi.client.files.UploadFileResp;
import com.coze.openapi.service.service.CozeAPI;
import com.easyproject.common.config.ProjectConfig;
import com.easyproject.common.constant.Constants;
import com.easyproject.common.core.domain.AjaxResult;
import com.easyproject.common.utils.StringUtils;
import com.easyproject.common.utils.coze.ChatAiForCozeUtils;
import com.easyproject.common.utils.file.FileUtils;
import com.easyproject.service.domain.coze.CozeBotSet;
import com.easyproject.service.domain.coze.CozeTokenSet;
import com.easyproject.service.domain.coze.CozeWorkspacesSet;
import com.easyproject.service.mapper.coze.CozeBotSetMapper;
import com.easyproject.service.mapper.coze.CozeWorkspacesSetMapper;
import com.easyproject.service.service.ICozeJwtService;
import com.easyproject.system.domain.vo.KnowledgeListVo;
import com.easyproject.system.domain.vo.botInfo.BotInfo;
import com.easyproject.system.domain.vo.botInfo.DataInfo;
import com.easyproject.system.domain.vo.botInfo.Knowledge;
import com.easyproject.system.domain.vo.botInfo.KnowledgeInfo;
import com.easyproject.system.service.chatAI.IChatBotService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 方法说明: 智能体信息
 *
 * @param
 * @author java-101
 * @return
 * @date 2025-04-07 19:53:18
 */
@Slf4j
@Service
public class ChatBotServiceImpl implements IChatBotService {

    @Resource
    private CozeWorkspacesSetMapper cozeWorkspacesSetMapper;
    @Resource
    private CozeBotSetMapper cozeBotSetMapper;
    @Resource
    private ICozeJwtService cozeJwtService;

    /**
     * 方法说明: 获取智能体配置
     *
     * @param
     * @return
     * @author java-101
     * @date 2025-04-07 19:55:45
     */
    @Override
    public AjaxResult getChatBotConfig() {

        //查询有效空间
        CozeWorkspacesSet workspacesSet = cozeWorkspacesSetMapper.selectOne(Wrappers.<CozeWorkspacesSet>lambdaQuery().eq(CozeWorkspacesSet::getStatus, 1).orderByDesc(CozeWorkspacesSet::getId).last("limit 1"));
        if (ObjectUtil.isEmpty(workspacesSet)) {
            return AjaxResult.error("查询空间信息错误，请稍后重试");
        }

        //查询机器人ID（智能体ID）
        CozeBotSet botSet = cozeBotSetMapper.selectOne(Wrappers.<CozeBotSet>lambdaQuery().eq(CozeBotSet::getStatus, 1).eq(CozeBotSet::getSpaceId, workspacesSet.getSpacesId()).orderByDesc(CozeBotSet::getId).last("limit 1"));
        if (ObjectUtil.isEmpty(botSet)) {
            return AjaxResult.error("查询智能体信息错误，请稍后重试");
        }

        // 查询系统token 使用JWT方式获取token（永久授权）
        CozeTokenSet tokenSet = cozeJwtService.getCozeTokenSetForToken();
        if (ObjectUtil.isEmpty(tokenSet)) {
            return AjaxResult.error("系统错误，请稍后重试");
        }

        //查询所有知识库
        String spaceID = workspacesSet.getSpacesId();
        ListDatasetReq req = ListDatasetReq.builder().spaceID(spaceID).pageSize(300).pageNum(1).build();
        CozeAPI coze = ChatAiForCozeUtils.getCozeClient(tokenSet.getPersonToken()); //初始化客户端
        PageResp<Dataset> datasets = coze.datasets().list(req);// 使用迭代器自动获取下一页
        List<KnowledgeListVo> voList = new ArrayList<>();//所有知识库列表
        KnowledgeListVo knowladgeVo = null;
        for (Dataset item : datasets.getItems()) {
            knowladgeVo = BeanUtil.copyProperties(item, KnowledgeListVo.class);
            knowladgeVo.setDocCount(item.getFileList().size());
            voList.add(knowladgeVo);
        }

        String url = ChatAiForCozeUtils.getBotInfoUrl();
        // 定义请求参数
        Map<String, Object> params = new HashMap<>();
        params.put("bot_id", botSet.getBotId());

        // 发送 POST 请求
        HttpResponse response = HttpRequest.get(url)
                .header("Authorization", "Bearer " + tokenSet.getPersonToken())
                .header("Content-Type", "application/json")
                .header("Agw-Js-Conv", "str")
                .form(params)
                .execute();

        String result = response.body();
        BotInfo vo = null;
        if (ObjectUtil.isNotEmpty(result)) {
            vo = JSONUtil.toBean(result, BotInfo.class);
        }

        if (ObjectUtil.isNotEmpty(vo) && vo.getCode() == 0 && ObjectUtil.isNotEmpty(vo.getData())) {
            DataInfo resultVo = vo.getData();
            //获取智能体中的知识库信息
            List<KnowledgeInfo> knowledge_infos = resultVo.getKnowledge().getKnowledge_infos();
            if (ObjectUtil.isNotEmpty(knowledge_infos) && ObjectUtil.isNotEmpty(voList)) {
                //遍历知识库列表，匹配知识库ID，设置知识库信息图标、描述
                for (KnowledgeInfo item : knowledge_infos) {
                    //使用jdk8筛选器
                    KnowledgeListVo knowledgeVo = voList.stream().filter(voItem -> voItem.getDatasetID().equals(item.getId())).findFirst().orElse(null);
                    item.setDescription(knowledgeVo.getDescription());
                    item.setIconURL(knowledgeVo.getIconURL());
                    item.setFormatType(knowledgeVo.getFormatType());
                }
            }

            List<KnowledgeInfo> unknowledge_infos = filterUnknownKnowledge(knowledge_infos, voList);

            Knowledge knowledge = new Knowledge();
            knowledge.setKnowledge_infos(knowledge_infos);
            knowledge.setUnknowledge_infos(unknowledge_infos);

            resultVo.setKnowledge(knowledge);
            return AjaxResult.success(resultVo);
        } else {
            return AjaxResult.error("系统错误，请稍后重试");
        }
    }

    public List<KnowledgeInfo> filterUnknownKnowledge(List<KnowledgeInfo> knowledge_infos, List<KnowledgeListVo> voList) {
        List<KnowledgeInfo> unknowledge_infos = new ArrayList<>();
        for (KnowledgeListVo vo : voList) {
            boolean found = false;
            for (KnowledgeInfo info : knowledge_infos) {
                if (vo.getDatasetID().equals(info.getId())) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                KnowledgeInfo newInfo =new KnowledgeInfo();
                newInfo.setId(vo.getDatasetID());
                newInfo.setName(vo.getName());
                newInfo.setDescription(vo.getDescription());
                newInfo.setIconURL(vo.getIconURL());
                newInfo.setFormatType(vo.getFormatType());
                unknowledge_infos.add(newInfo);
            }
        }
        return unknowledge_infos;
    }

    /**
     * 方法说明: 编辑智能体-名称、描述、图标
     *
     * @param
     * @return
     * @author java-101
     * @date 2025-04-08 22:57:03
     */
    @Override
    public AjaxResult updateBotName(DataInfo dto) {
        if (ObjectUtil.isEmpty(dto.getBot_id()) || ObjectUtil.isEmpty(dto.getName()) || ObjectUtil.isEmpty(dto.getDescription()) || ObjectUtil.isEmpty(dto.getIcon_url())) {
            return AjaxResult.error("参数错误");
        }
        // 查询系统token 使用JWT方式获取token（永久授权）
        CozeTokenSet tokenSet = cozeJwtService.getCozeTokenSetForToken();
        if (ObjectUtil.isEmpty(tokenSet)) {
            return AjaxResult.error("系统错误，请稍后重试");
        }

        //初始化客户端
        CozeAPI coze = ChatAiForCozeUtils.getCozeClient(tokenSet.getPersonToken());

        //上传图标到coze平台
        String icon_file_id = null;
        if (!dto.getIcon_url().contains("https://")) {//说明要修改图片
            // 本地资源路径
            String localPath = ProjectConfig.getProfile();
            //图标的绝对路径
            String iconFilePath = localPath + StringUtils.substringAfter(dto.getIcon_url(), Constants.RESOURCE_PREFIX);
            UploadFileResp imageInfo = coze.files().upload(UploadFileReq.of(iconFilePath));
            if (ObjectUtil.isEmpty(imageInfo)) {
                return AjaxResult.error("添加失败，图标上传失败");
            }
            icon_file_id = imageInfo.getFileInfo().getID();
            //删除本地图片
            FileUtils.deleteFile(iconFilePath);
        }

        //修改智能体基本信息
        UpdateBotReq updateReq = UpdateBotReq.builder().botID(dto.getBot_id()).name(dto.getName()).description(dto.getDescription()).iconFileID(icon_file_id).build();
        UpdateBotResp updateResp = coze.bots().update(updateReq);
        if (ObjectUtil.isNotEmpty(updateResp) && ObjectUtil.isNotEmpty(updateResp.getLogID())) {
            //发布智能体
            PublishBotReq publishReq = PublishBotReq.builder().botID(dto.getBot_id()).connectorIDs(Arrays.asList("1024")).build();//智能体发布为 Agent as API
            PublishBotResp publisResp = coze.bots().publish(publishReq);
            if(ObjectUtil.isNotEmpty(publisResp) && ObjectUtil.isNotEmpty(publisResp.getLogID())){
                return AjaxResult.success("编辑成功");
            }else {
                return AjaxResult.error("编辑失败");
            }
        } else {
            return AjaxResult.error("编辑失败");
        }
    }

    /**
     * 方法说明: 保存人设与回复逻辑
     * @param
     * @return
     * @author java-101
     * @date 2025-04-09 13:46:53
     */
    @Override
    public AjaxResult updatePrompt(DataInfo dto) {
        if (ObjectUtil.isEmpty(dto.getBot_id()) || ObjectUtil.isEmpty(dto.getPrompt_info().getPrompt())) {
            return AjaxResult.error("参数错误");
        }
        // 查询系统token 使用JWT方式获取token（永久授权）
        CozeTokenSet tokenSet = cozeJwtService.getCozeTokenSetForToken();
        if (ObjectUtil.isEmpty(tokenSet)) {
            return AjaxResult.error("系统错误，请稍后重试");
        }

        //初始化客户端
        CozeAPI coze = ChatAiForCozeUtils.getCozeClient(tokenSet.getPersonToken());

        //修改智能体基本信息
        BotPromptInfo botPromptInfo = new BotPromptInfo();
        botPromptInfo.setPrompt(dto.getPrompt_info().getPrompt());
        UpdateBotReq updateReq = UpdateBotReq.builder().botID(dto.getBot_id()).promptInfo(botPromptInfo).build();
        UpdateBotResp updateResp = coze.bots().update(updateReq);
        if (ObjectUtil.isNotEmpty(updateResp) && ObjectUtil.isNotEmpty(updateResp.getLogID())) {
            //发布智能体
            PublishBotReq publishReq = PublishBotReq.builder().botID(dto.getBot_id()).connectorIDs(Arrays.asList("1024")).build();//智能体发布为 Agent as API
            PublishBotResp publisResp = coze.bots().publish(publishReq);
            if(ObjectUtil.isNotEmpty(publisResp) && ObjectUtil.isNotEmpty(publisResp.getLogID())){
                return AjaxResult.success("保存成功");
            }else {
                return AjaxResult.error("保存失败");
            }
        } else {
            return AjaxResult.error("保存失败");
        }
    }

    /**
     * 方法说明: 保存 开场白文案、预设问题
     * @param
     * @return
     * @author java-101
     * @date 2025-04-09 15:09:43
     */
    @Override
    public AjaxResult updateOnboarding(DataInfo dto) {
        if (ObjectUtil.isEmpty(dto.getBot_id())) {
            return AjaxResult.error("参数错误");
        }
        // 查询系统token 使用JWT方式获取token（永久授权）
        CozeTokenSet tokenSet = cozeJwtService.getCozeTokenSetForToken();
        if (ObjectUtil.isEmpty(tokenSet)) {
            return AjaxResult.error("系统错误，请稍后重试");
        }

        //初始化客户端
        CozeAPI coze = ChatAiForCozeUtils.getCozeClient(tokenSet.getPersonToken());

        //修改智能体基本信息
        BotOnboardingInfo botPromptInfo = new BotOnboardingInfo();
        botPromptInfo.setPrologue(dto.getOnboarding_info().getPrologue());//开场白
        botPromptInfo.setSuggestedQuestions(dto.getOnboarding_info().getSuggested_questions());//预设问题 ["333","怎样的问题你能更好地解答？","2112"]

        UpdateBotReq updateReq = UpdateBotReq.builder().botID(dto.getBot_id()).onboardingInfo(botPromptInfo).build();
        UpdateBotResp updateResp = coze.bots().update(updateReq);
        if (ObjectUtil.isNotEmpty(updateResp) && ObjectUtil.isNotEmpty(updateResp.getLogID())) {
            //发布智能体
            PublishBotReq publishReq = PublishBotReq.builder().botID(dto.getBot_id()).connectorIDs(Arrays.asList("1024")).build();//智能体发布为 Agent as API
            PublishBotResp publisResp = coze.bots().publish(publishReq);
            if(ObjectUtil.isNotEmpty(publisResp) && ObjectUtil.isNotEmpty(publisResp.getLogID())){
                return AjaxResult.success("保存成功");
            }else {
                return AjaxResult.error("保存失败");
            }
        } else {
            return AjaxResult.error("保存失败");
        }
    }

    /**
     * 方法说明: 智能体设置知识库-绑定的知识库
     * @param
     * @return
     * @author java-101
     * @date 2025-04-09 15:38:23
     */
    @Override
    public AjaxResult bindKnowledge(DataInfo dto) {
        if (ObjectUtil.isEmpty(dto.getBot_id())) {
            return AjaxResult.error("参数错误");
        }
        // 查询系统token 使用JWT方式获取token（永久授权）
        CozeTokenSet tokenSet = cozeJwtService.getCozeTokenSetForToken();
        if (ObjectUtil.isEmpty(tokenSet)) {
            return AjaxResult.error("系统错误，请稍后重试");
        }

        //初始化客户端
        CozeAPI coze = ChatAiForCozeUtils.getCozeClient(tokenSet.getPersonToken());

        //修改智能体基本信息
        List<String> dataset_ids = null;
        if(ObjectUtil.isNotEmpty(dto.getKnowledge().getKnowledge_infos())){
            dataset_ids = dto.getKnowledge().getKnowledge_infos().stream().map(item -> item.getId()).collect(Collectors.toList());
        }
        BotKnowledge knowledge = new BotKnowledge();//知识库
        knowledge.setDatasetIDs(dataset_ids);
        knowledge.setAutoCall(true);
        knowledge.setSearchStrategy(0);

        UpdateBotReq updateReq = UpdateBotReq.builder().botID(dto.getBot_id()).knowledge(knowledge).build();
        UpdateBotResp updateResp = coze.bots().update(updateReq);
        if (ObjectUtil.isNotEmpty(updateResp) && ObjectUtil.isNotEmpty(updateResp.getLogID())) {
            //发布智能体
            PublishBotReq publishReq = PublishBotReq.builder().botID(dto.getBot_id()).connectorIDs(Arrays.asList("1024")).build();//智能体发布为 Agent as API
            PublishBotResp publisResp = coze.bots().publish(publishReq);
            if(ObjectUtil.isNotEmpty(publisResp) && ObjectUtil.isNotEmpty(publisResp.getLogID())){
                return AjaxResult.success("保存成功");
            }else {
                return AjaxResult.error("保存失败");
            }
        } else {
            return AjaxResult.error("保存失败");
        }
    }


}
