package com.cool.modules.dailyreport.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.cool.modules.aiconfig.entity.AiApiConfigEntity;
import com.cool.modules.aiconfig.entity.AiModelEntity;
import com.cool.modules.aiconfig.entity.AiTemplateEntity;
import com.cool.modules.aiconfig.service.AiApiConfigService;
import com.cool.modules.aiconfig.service.AiModelService;
import com.cool.modules.aiconfig.service.AiTemplateService;
import com.cool.modules.dailyreport.service.DailyReportAiService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * 日报AI格式化服务实现
 * 支持调用通义千问等大模型API进行日报内容格式化
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DailyReportAiServiceImpl implements DailyReportAiService {

    private final AiTemplateService aiTemplateService;
    private final AiModelService aiModelService;
    private final AiApiConfigService aiApiConfigService;

    // 默认日报模板标识
    private static final String DEFAULT_TEMPLATE_KEY = "daily_report_format";

    @Override
    public String formatDailyReport(String originalText, String templateKey) {
        return formatDailyReport(originalText, templateKey, null);
    }

    @Override
    public String formatDailyReport(String originalText, String templateKey, String reportDate) {
        log.info("【日报AI格式化】开始格式化, templateKey: {}, reportDate: {}, 原文长度: {} 字符",
                templateKey, reportDate, originalText != null ? originalText.length() : 0);

        try {
            // 验证输入
            if (originalText == null || originalText.trim().isEmpty()) {
                log.error("【日报AI格式化】输入内容为空");
                throw new RuntimeException("输入内容不能为空");
            }

            // 查询模板
            AiTemplateEntity template = aiTemplateService.getByTemplateKey(templateKey);
            if (template == null) {
                log.error("【日报AI格式化】模板不存在: {}", templateKey);
                throw new RuntimeException("日报模板未配置，请联系管理员");
            }

            log.info("【日报AI格式化】找到模板: {}, modelId: {}", template.getTemplateName(), template.getModelId());

            // 查询AI模型配置
            AiModelEntity model = null;
            if (template.getModelId() != null) {
                model = aiModelService.getById(template.getModelId());
            }

            if (model == null) {
                log.warn("【日报AI格式化】模板未关联AI模型，使用默认模型");
                // 尝试获取第一个可用模型
                model = aiModelService.getEnabledModels().stream().findFirst().orElse(null);
            }

            if (model == null) {
                log.error("【日报AI格式化】没有可用的AI模型");
                throw new RuntimeException("AI模型未配置，请联系管理员");
            }

            log.info("【日报AI格式化】使用AI模型: {}", model.getModelName());

            // 构建完整提示词（包含日期）
            String fullPrompt = buildPrompt(template.getPromptContent(), originalText, reportDate);

            // 调用AI模型生成内容
            String formattedContent = callAiModel(model, fullPrompt);

            log.info("【日报AI格式化】格式化成功, 结果长度: {} 字符", formattedContent.length());
            return formattedContent;

        } catch (Exception e) {
            log.error("【日报AI格式化】格式化失败", e);
            throw new RuntimeException("AI格式化失败: " + e.getMessage());
        }
    }

    @Override
    public String formatDailyReportWithDefaultTemplate(String originalText) {
        log.info("【日报AI格式化】使用默认模板格式化");
        return formatDailyReport(originalText, DEFAULT_TEMPLATE_KEY);
    }

    @Override
    public boolean isAiServiceAvailable() {
        try {
            // 检查是否有可用的模板和模型
            AiTemplateEntity template = aiTemplateService.getByTemplateKey(DEFAULT_TEMPLATE_KEY);
            if (template == null) {
                log.warn("【日报AI格式化】默认模板不存在");
                return false;
            }

            java.util.List<AiModelEntity> models = aiModelService.getEnabledModels();
            if (models == null || models.isEmpty()) {
                log.warn("【日报AI格式化】没有启用的AI模型");
                return false;
            }

            return true;

        } catch (Exception e) {
            log.error("【日报AI格式化】检查AI服务可用性失败", e);
            return false;
        }
    }

    @Override
    public String generateAdvice(String templateKey, String content) {
        log.info("【AI建议】开始生成建议, templateKey: {}, 聚合内容长度: {}", templateKey,
                content != null ? content.length() : 0);
        try {
            if (content == null || content.trim().isEmpty()) {
                log.error("【AI建议】输入内容为空");
                throw new RuntimeException("输入内容不能为空");
            }

            AiTemplateEntity template = aiTemplateService.getByTemplateKey(templateKey);
            if (template == null) {
                log.error("【AI建议】模板不存在: {}", templateKey);
                throw new RuntimeException("AI建议模板未配置，请联系管理员: " + templateKey);
            }

            AiModelEntity model = null;
            if (template.getModelId() != null) {
                model = aiModelService.getById(template.getModelId());
            }
            if (model == null) {
                model = aiModelService.getEnabledModels().stream().findFirst().orElse(null);
            }
            if (model == null) {
                log.error("【AI建议】没有可用的AI模型");
                throw new RuntimeException("AI模型未配置，请联系管理员");
            }

            String prompt = buildAdvicePrompt(template.getPromptContent(), content);
            String result = callAiModel(model, prompt);
            log.info("【AI建议】生成成功, 长度: {}", result != null ? result.length() : 0);
            return result;
        } catch (Exception e) {
            log.error("【AI建议】生成失败", e);
            throw new RuntimeException("AI建议生成失败: " + e.getMessage());
        }
    }

    private String buildAdvicePrompt(String templateContent, String content) {
        if (templateContent == null) {
            templateContent = "";
        }
        String prompt = templateContent
                .replace("{content}", content == null ? "" : content)
                .replace("{{content}}", content == null ? "" : content);
        return prompt;
    }

    /**
     * 构建完整提示词
     *
     * @param templateContent 模板内容
     * @param originalText    用户原始文字
     * @param reportDate      日报日期（可选）
     * @return 完整提示词
     */
    private String buildPrompt(String templateContent, String originalText, String reportDate) {
        log.info("【日报AI格式化】构建提示词, reportDate: {}", reportDate);

        // 支持多种占位符格式
        String prompt = templateContent
                .replace("{original_text}", originalText)
                .replace("{{original_text}}", originalText)
                .replace("{content}", originalText)
                .replace("{{content}}", originalText);

        // 如果提供了日期，替换日期占位符
        if (reportDate != null && !reportDate.isEmpty()) {
            prompt = prompt
                    .replace("{date}", reportDate)
                    .replace("{{date}}", reportDate)
                    .replace("{report_date}", reportDate)
                    .replace("{{report_date}}", reportDate);
        } else {
            // 如果没有提供日期，使用当前日期
            String today = java.time.LocalDate.now().toString();
            prompt = prompt
                    .replace("{date}", today)
                    .replace("{{date}}", today)
                    .replace("{report_date}", today)
                    .replace("{{report_date}}", today);
        }

        log.info("【日报AI格式化】提示词构建完成, 长度: {} 字符", prompt.length());
        return prompt;
    }

    /**
     * 调用AI模型生成内容
     *
     * @param model  AI模型配置
     * @param prompt 提示词
     * @return AI生成的内容
     */
    private String callAiModel(AiModelEntity model, String prompt) {
        log.info("【日报AI格式化】调用AI模型, model: {}, modelKey: {}", model.getModelName(), model.getModelKey());

        try {
            // 获取API配置
            AiApiConfigEntity apiConfig = aiApiConfigService.getByModelId(model.getId());
            if (apiConfig == null) {
                log.error("【日报AI格式化】模型未配置API接口, modelId: {}", model.getId());
                throw new RuntimeException("AI模型接口未配置，请联系管理员");
            }

            log.info("【日报AI格式化】使用API配置, apiUrl: {}", apiConfig.getApiUrl());

            // 构建请求体（通义千问格式）
            JSONObject requestBody = new JSONObject();
            requestBody.set("model", model.getModelKey());

            JSONObject input = new JSONObject();
            JSONArray messages = new JSONArray();
            JSONObject message = new JSONObject();
            message.set("role", "user");
            message.set("content", prompt);
            messages.add(message);
            input.set("messages", messages);
            requestBody.set("input", input);

            // 设置参数
            JSONObject parameters = new JSONObject();
            parameters.set("max_tokens", 2000);
            requestBody.set("parameters", parameters);

            log.info("【日报AI格式化】请求体: {}", requestBody.toString());

            // 构建HTTP请求
            HttpRequest request = HttpRequest.post(apiConfig.getApiUrl())
                .timeout(apiConfig.getTimeout() * 1000)
                .header("Content-Type", "application/json");

            // 设置请求头
            if (StrUtil.isNotEmpty(apiConfig.getRequestHeaders())) {
                JSONObject headers = JSONUtil.parseObj(apiConfig.getRequestHeaders());
                for (Map.Entry<String, Object> entry : headers.entrySet()) {
                    request.header(entry.getKey(), String.valueOf(entry.getValue()));
                }
            }

            // 设置API密钥
            if (StrUtil.isNotEmpty(apiConfig.getApiKey()) && StrUtil.isNotEmpty(apiConfig.getApiKeyName())) {
                String apiKeyValue = apiConfig.getApiKey();
                // 如果API密钥名称是Authorization且密钥不以Bearer开头，自动添加Bearer前缀
                if ("Authorization".equalsIgnoreCase(apiConfig.getApiKeyName())
                    && !apiKeyValue.toLowerCase().startsWith("bearer ")) {
                    apiKeyValue = "Bearer " + apiKeyValue;
                }
                request.header(apiConfig.getApiKeyName(), apiKeyValue);
            }

            // 发送请求（适当放宽超时时间）
            request.body(requestBody.toString()).timeout(120000);
            HttpResponse response = request.execute();
            String responseBody = response.body();

            log.info("【日报AI格式化】API响应, statusCode: {}, body: {}",
                response.getStatus(), responseBody);

            // 检查响应状态
            if (!response.isOk()) {
                log.error("【日报AI格式化】API调用失败, statusCode: {}, body: {}",
                    response.getStatus(), responseBody);
                throw new RuntimeException("AI API调用失败，状态码: " + response.getStatus());
            }

            // 解析响应
            JSONObject result = JSONUtil.parseObj(responseBody);

            // 通义千问响应格式：output.choices[0].message.content
            String content = result.getByPath("output.text", String.class);
            if (StrUtil.isEmpty(content)) {
                // 尝试另一种路径
                content = result.getByPath("output.choices[0].message.content", String.class);
            }

            if (StrUtil.isEmpty(content)) {
                log.error("【日报AI格式化】响应中未找到生成内容, response: {}", responseBody);
                throw new RuntimeException("AI生成内容为空");
            }

            log.info("【日报AI格式化】AI生成成功, 内容长度: {} 字符", content.length());
            return content;

        } catch (Exception e) {
            log.error("【日报AI格式化】调用AI API失败", e);

            // 降级策略：返回格式化的提示信息
            log.warn("【日报AI格式化】使用降级策略，返回原文");
            return "## AI格式化服务暂时不可用\n\n原始内容：\n\n" +
                   extractOriginalText(prompt);
        }
    }

    /**
     * 从提示词中提取原始文本
     */
    private String extractOriginalText(String prompt) {
        // 尝试提取 {original_text} 后的内容
        if (prompt.contains("用户输入：")) {
            int start = prompt.indexOf("用户输入：") + 5;
            return prompt.substring(start).trim();
        }
        return prompt;
    }
}
