package com.emoon.openplatform.controller;


import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import com.emoon.common.core.domain.R;
import com.emoon.common.core.utils.StringUtils;
import com.emoon.openplatform.domain.ModelDo;
import com.emoon.openplatform.domain.RagDo;
import com.emoon.openplatform.domain.SysProjectDo;
import com.emoon.openplatform.domain.SysPromptDo;

import com.emoon.openplatform.mapper.ModelMapper;
import com.emoon.openplatform.mapper.RagMapper;
import com.emoon.openplatform.mapper.SysProjectMapper;
import com.emoon.openplatform.mapper.SysPromptMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.emoon.openplatform.domain.dto.resp.CheckResp;
import com.emoon.openplatform.enums.SystemEnum;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;

/**
 * @author destiny
 * @description:
 * @date 2025/9/23 17:44
 */
@Slf4j
@RestController
@RequestMapping("/check")
@CrossOrigin(origins = "*")
@RequiredArgsConstructor
public class CheckController {


    private final ModelMapper modelMapper;

    private final SysProjectMapper sysProjectMapper;

    private final RagMapper ragMapper;

    private final SysPromptMapper sysPromptMapper;




    /**
     * 获取获取短令牌接口
     *
     * @param information 业务系统通过前 10 步处理后的加密字符串
     *                    e.g.
     *                    eyJlbmNyeXB0ZWRCYXNlNjQiOiJQMzkwRExhQkN0c2xoSEpvXC9rU3pCS1NnWXY3aWFCQUFQMHFZS2F2ZHdIS3JCem4zRU
     *                    tDaWw3YjNyWTI5eXBINmFrZ2MxaVdqaktsc0FjeXFcLzlIUGI2cnNFYk9yZ0xVMDNJVytmUDU4MVU1KzJ0XC9GXC96YXJM
     *                    dVBMZk11REZvNmlYc3NVbkQ3ckpOOEZpaUFcLzBMb0FFbEJveWE0alRjWEk3YjF3XC9GV1orTXdXWVwvK3BZUG0yTWw3Wl
     *                    Q2XC9SRGdleU55UndFZTNXOTBxb0tpdTJNcmo4K0tiOFArY2RXd0lNaVpIb0xEZHVEc2tqXC85aWsrRFRZSXZTcnB3K0N5
     *                    d1ZxR0VCU1dKV0F1M2crdnQ4QUNER1wvSUM3RWJnNHZEc3JNWVUyZkV2UG9Xd2grMjlPNzU5Z1VRMDFPU2l4eE5Kb1Q1OE
     *                    Q1VVJCSkFlNFRzaTJTN0k1SGc5cG0yK3c0Y0M4MXZpMnZyOEk4Qng1UVhSa2RDaXl5Z2orajY5a1h1QXVmZm5hZWd0VHh2
     *                    ZjNURkVKeSszS1g3XC9NNGphVDhLVExZbGpickhCeGdzUHk4UVJjNmJTK0lNOXJ1b2NhblFoeHpTU0Z3K0NQRERVNlJ3RE
     *                    lYajM0RGRnPT0iLCJzbUlWIjoiMTIzNDU2Nzg5MTQ3ODUyMyIsInB1YmxpY0tleSI6InRISlpwOW1KUVBKNENKQXUxOUY2
     *                    dmhJVmExY3laaFA4In0=
     * @return
     */

    private String base64UrlDecode(String information) {
        String result = information.replace('-', '+').replace('_', '/');
        int padding = result.length() % 4;
        if (padding != 0) {
            result += "====".substring(0, 4 - padding);
        }
        return Base64.decodeStr(result, StandardCharsets.UTF_8);
    }

    /**
     * 检查方法（接收model、ragId、mcpId、publicKey、prompt参数）
     *
     * @param model 模型名称
     * @param ragId RAG知识库ID
     * @param mcpId MCP Agent配置ID
     * @param publicKey 公钥
     * @param prompt Prompt ID
     * @return 检查结果
     */
    @PostMapping("/check")
    public R<CheckResp> check(@RequestParam(required = false) String model,
                              @RequestParam(required = false) String ragId,
                              @RequestParam(required = false) String mcpId,
                              @RequestParam(required = false) String publicKey,
                              @RequestParam(required = false) String prompt) {
        // 输出输入参数
        log.info("========== Check接口输入参数 ==========");
        log.info("model: {}", model);
        log.info("ragId: {}", ragId);
        log.info("mcpId: {}", mcpId);
        log.info("publicKey: {}", publicKey);
        log.info("prompt: {}", prompt);
        log.info("========================================");
        CheckResp checkResp = CheckResp.builder().build();
        // 使用model查询think-model表，返回对应id值、model_in_type、model_out_type和model_url
        Long thinkModelId = null;
        String modelInType = null;
        String modelOutType = null;
        String modelUrl = null;
        if (StringUtils.isNotBlank(model)) {
            // 构建查询条件
            LambdaQueryWrapper<ModelDo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ModelDo::getModel, model);

            // 查询think-model表
            List<ModelDo> modelList = modelMapper.selectList(queryWrapper);

            if (CollUtil.isEmpty(modelList)) {
                // 模型不存在，直接返回错误
                return R.fail(SystemEnum.MODEL_NOT_EXISTS.getCode(), SystemEnum.MODEL_NOT_EXISTS.getMessage());
            }

            // 返回第一个匹配的id、model_in_type、model_out_type和model_url
            ModelDo modelDo = modelList.get(0);
            thinkModelId = modelDo.getId();
            modelInType = modelDo.getModelInType();
            modelOutType = modelDo.getModelOutType();
            modelUrl = modelDo.getModelUrl();
        }

        // 根据publicKey查询sys_project表
        List<SysProjectDo> sysProjectList = null;
        if (StringUtils.isNotBlank(publicKey)) {
            // 构建查询条件
            LambdaQueryWrapper<SysProjectDo> sysProjectQueryWrapper = new LambdaQueryWrapper<>();
            sysProjectQueryWrapper.eq(SysProjectDo::getPublicKey, publicKey);

            // 查询sys_project表（emoon_ai_plus数据库）
            sysProjectList = sysProjectMapper.selectList(sysProjectQueryWrapper);

            log.info("根据publicKey查询sys_project表，找到{}条记录",
                     sysProjectList != null ? sysProjectList.size() : 0);

            // 验证：如果查不到数据，返回错误
            if (CollUtil.isEmpty(sysProjectList)) {
                return R.fail(SystemEnum.PROJECT_NOT_EXISTS.getCode(), SystemEnum.PROJECT_NOT_EXISTS.getMessage());
            }

            // 获取第一个项目（通常publicKey是唯一的，但如果有多个，取第一个）
            SysProjectDo sysProject = sysProjectList.get(0);

            // 验证：判断thinkModelId是否存在于model_ids中
            if (thinkModelId != null) {
                List<String> modelIds = sysProject.getModelIds();
                String thinkModelIdStr = thinkModelId.toString();
                log.info("权限验证 - thinkModelId: {}, thinkModelIdStr: '{}', modelIds: {}, modelIds为空: {}, modelIds大小: {}",
                         thinkModelId, thinkModelIdStr, modelIds,
                         CollUtil.isEmpty(modelIds),
                         modelIds != null ? modelIds.size() : 0);

                if (CollUtil.isEmpty(modelIds)) {
                    log.warn("模型权限验证失败 - modelIds为空或null");
                    return R.fail(SystemEnum.PROJECT_NO_MODEL_PERMISSION.getCode(),
                                 SystemEnum.PROJECT_NO_MODEL_PERMISSION.getMessage());
                }

                boolean contains = CollUtil.contains(modelIds, thinkModelIdStr);
                log.info("CollUtil.contains(modelIds, '{}') 结果: {}", thinkModelIdStr, contains);

                if (!contains) {
                    log.warn("模型权限验证失败 - thinkModelId: '{}' 不在 modelIds: {} 中", thinkModelIdStr, modelIds);
                    return R.fail(SystemEnum.PROJECT_NO_MODEL_PERMISSION.getCode(),
                                 SystemEnum.PROJECT_NO_MODEL_PERMISSION.getMessage());
                }
                log.info("模型权限验证通过 - thinkModelId: {}", thinkModelIdStr);
            }

            // 验证：判断ragId是否存在于rag_ids中
            if (StringUtils.isNotBlank(ragId)) {
                List<String> ragIds = sysProject.getRagIds();
                log.info("RAG权限验证 - ragId: '{}', ragIds: {}, ragIds为空: {}, ragIds大小: {}",
                         ragId, ragIds,
                         CollUtil.isEmpty(ragIds),
                         ragIds != null ? ragIds.size() : 0);

                if (CollUtil.isEmpty(ragIds)) {
                    log.warn("RAG权限验证失败 - ragIds为空或null");
                    return R.fail(SystemEnum.PROJECT_NO_RAG_PERMISSION.getCode(),
                                 SystemEnum.PROJECT_NO_RAG_PERMISSION.getMessage());
                }

                boolean contains = CollUtil.contains(ragIds, ragId);
                log.info("CollUtil.contains(ragIds, '{}') 结果: {}", ragId, contains);

                if (!contains) {
                    log.warn("RAG权限验证失败 - ragId: '{}' 不在 ragIds: {} 中", ragId, ragIds);
                    return R.fail(SystemEnum.PROJECT_NO_RAG_PERMISSION.getCode(),
                                 SystemEnum.PROJECT_NO_RAG_PERMISSION.getMessage());
                }
                log.info("RAG权限验证通过 - ragId: {}", ragId);

                // 根据ragId查询think_rag表，获取ragid字段
                try {
                    LambdaQueryWrapper<RagDo> ragQueryWrapper = new LambdaQueryWrapper<>();
                    ragQueryWrapper.eq(RagDo::getId, Integer.parseInt(ragId));

                    RagDo ragDo = ragMapper.selectOne(ragQueryWrapper);
                    if (ragDo != null && StringUtils.isNotBlank(ragDo.getRagId())) {
                        // 将查询到的ragid设置到checkResp中
                        checkResp.setRagId(ragDo.getRagId());
                        log.info("查询think_rag表成功 - id: {}, ragid: {}", ragId, ragDo.getRagId());
                    } else {
                        log.warn("查询think_rag表未找到数据或ragid为空 - id: {}", ragId);
                    }
                } catch (NumberFormatException e) {
                    log.warn("ragId格式错误，无法转换为整数 - ragId: {}", ragId);
                } catch (Exception e) {
                    log.error("查询think_rag表失败 - ragId: {}", ragId, e);
                }
            }

            // 验证：判断mcpId是否存在于agent_ids中
            if (StringUtils.isNotBlank(mcpId)) {
                List<String> agentIds = sysProject.getAgentIds();
                log.info("MCP权限验证 - mcpId: '{}', agentIds: {}, agentIds为空: {}, agentIds大小: {}",
                         mcpId, agentIds,
                         CollUtil.isEmpty(agentIds),
                         agentIds != null ? agentIds.size() : 0);

                if (CollUtil.isEmpty(agentIds)) {
                    log.warn("MCP权限验证失败 - agentIds为空或null");
                    return R.fail(SystemEnum.PROJECT_NO_AGENT_PERMISSION.getCode(),
                                 SystemEnum.PROJECT_NO_AGENT_PERMISSION.getMessage());
                }

                boolean contains = CollUtil.contains(agentIds, mcpId);
                log.info("CollUtil.contains(agentIds, '{}') 结果: {}", mcpId, contains);

                if (!contains) {
                    log.warn("MCP权限验证失败 - mcpId: '{}' 不在 agentIds: {} 中", mcpId, agentIds);
                    return R.fail(SystemEnum.PROJECT_NO_AGENT_PERMISSION.getCode(),
                                 SystemEnum.PROJECT_NO_AGENT_PERMISSION.getMessage());
                }
                log.info("MCP权限验证通过 - mcpId: {}", mcpId);
            }
        }

        // 返回查询结果
        checkResp.setModelId(thinkModelId);
        checkResp.setModelInType(modelInType);
        checkResp.setModelOutType(modelOutType);
        checkResp.setModelUrl(modelUrl);
        // ragId 已在查询think_rag表时设置，如果没有查询到则使用原始值
        if (StringUtils.isBlank(checkResp.getRagId())) {
        checkResp.setRagId(ragId);
        }
        checkResp.setSysProjectList(sysProjectList);

        // 根据prompt id和project_id查询sys_prompt表
        if (StringUtils.isNotBlank(prompt) && sysProjectList != null && !sysProjectList.isEmpty()) {
            try {
                // 获取第一个项目的id作为project_id
                SysProjectDo firstProject = sysProjectList.get(0);
                Integer projectId = firstProject.getId();
                
                Integer promptId = Integer.parseInt(prompt);

                // 构建查询条件：id = prompt 且 project_id = projectId
                LambdaQueryWrapper<SysPromptDo> promptQueryWrapper = new LambdaQueryWrapper<>();
                promptQueryWrapper.eq(SysPromptDo::getId, promptId)
                                 .eq(SysPromptDo::getProjectId, projectId);

                SysPromptDo sysPrompt = sysPromptMapper.selectOne(promptQueryWrapper);
                if (sysPrompt != null) {
                    checkResp.setSysPrompt(sysPrompt);
                    log.info("查询sys_prompt表成功 - prompt id: {}, project_id: {}, prompt内容长度: {}",
                            promptId, projectId, sysPrompt.getPrompt() != null ? sysPrompt.getPrompt().length() : 0);
                } else {
                    log.warn("查询sys_prompt表未找到数据 - prompt id: {}, project_id: {}", promptId, projectId);
                }
            } catch (NumberFormatException e) {
                log.warn("prompt格式错误，无法转换为整数 - prompt: {}", prompt);
            } catch (Exception e) {
                log.error("查询sys_prompt表失败 - prompt: {}", prompt, e);
            }
        }

        // 权限验证完成后，打印所有参数
        log.info("========== Check权限验证完成，所有参数 ==========");
        log.info("输入参数:");
        log.info("  - model: {}", model);
        log.info("  - ragId: {}", ragId);
        log.info("  - mcpId: {}", mcpId);
        log.info("  - publicKey: {}", publicKey);
        log.info("  - prompt: {}", prompt);
        log.info("查询结果:");
        log.info("  - thinkModelId: {}", thinkModelId);
        log.info("  - modelInType: {}", modelInType);
        log.info("  - modelOutType: {}", modelOutType);
        log.info("  - modelUrl: {}", modelUrl);
        log.info("CheckResp对象内容:");
        log.info("  - modelId: {}", checkResp.getModelId());
        log.info("  - modelInType: {}", checkResp.getModelInType());
        log.info("  - modelOutType: {}", checkResp.getModelOutType());
        log.info("  - modelUrl: {}", checkResp.getModelUrl());
        log.info("  - ragId: {}", checkResp.getRagId());
        log.info("  - sysProjectList: {}", checkResp.getSysProjectList() != null ?
                 "共" + checkResp.getSysProjectList().size() + "条记录" : "null");
        log.info("  - sysPrompt: {}", checkResp.getSysPrompt() != null ?
                 "id=" + checkResp.getSysPrompt().getId() + ", prompt长度=" +
                 (checkResp.getSysPrompt().getPrompt() != null ? checkResp.getSysPrompt().getPrompt().length() : 0) : "null");
        if (checkResp.getSysProjectList() != null && !checkResp.getSysProjectList().isEmpty()) {
            SysProjectDo firstProject = checkResp.getSysProjectList().get(0);
            log.info("  - 第一个项目信息:");
            log.info("    * id: {}", firstProject.getId());
            log.info("    * publicKey: {}", firstProject.getPublicKey());
            log.info("    * modelIds: {}", firstProject.getModelIds());
            log.info("    * ragIds: {}", firstProject.getRagIds());
            log.info("    * agentIds: {}", firstProject.getAgentIds());
        }
        log.info("================================================");

        return R.ok(checkResp);
    }


}

