package com.erp.ai.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.erp.ai.dto.*;
import com.erp.ai.entity.AIConversation;
import com.erp.ai.entity.AIMessage;
import com.erp.ai.repository.AIConversationMapper;
import com.erp.ai.repository.AIMessageMapper;
import com.erp.ai.service.AIAssistantService;
import com.erp.ai.service.AIChatService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import com.erp.common.core.model.PageResponse;

/**
 * AI助手服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AIAssistantServiceImpl implements AIAssistantService {

    private final AIChatService aiChatService;
    private final AIConversationMapper conversationMapper;
    private final AIMessageMapper messageMapper;

    @Value("${ai.system-prompt.base:你是一个专业的ERP系统AI助手，专门帮助用户处理企业资源管理相关的问题。}")
    private String baseSystemPrompt;

    @Value("${ai.default-service:openai}")
    private String defaultService;

    private static final int HISTORY_LIMIT = 10;

    @Override
    @Transactional
    public AIChatResponse chat(Long userId, AIChatRequest request) {
        // 获取或创建对话
        AIConversation conversation;
        if (request.getConversationId() != null) {
            conversation = conversationMapper.selectById(request.getConversationId());
            if (conversation == null || !conversation.getUserId().equals(userId)) {
                throw new RuntimeException("对话不存在或无权访问");
            }
        } else {
            // 创建新对话
            String title = request.getMessage().length() > 50
                    ? request.getMessage().substring(0, 50) + "..."
                    : request.getMessage();
            conversation = AIConversation.builder()
                    .userId(userId)
                    .title(title)
                    .model(defaultService)
                    .service(defaultService)
                    .status("active")
                    .messageCount(0)
                    .totalTokens(0L)
                    .build();
            conversationMapper.insert(conversation);
        }

        // 构建消息列表
        List<MessageDTO> messages = buildMessages(request.getMessage(), request.getContext(), conversation);

        // 调用AI服务
        Map<String, Object> aiResult = aiChatService.chat(messages, new HashMap<>());

        if (!Boolean.TRUE.equals(aiResult.get("success"))) {
            throw new RuntimeException("AI服务暂时不可用: " + aiResult.getOrDefault("error", "未知错误"));
        }

        String aiResponse = (String) aiResult.get("content");
        Integer tokensUsed = ((Number) aiResult.getOrDefault("tokens", 0)).intValue();

        // 保存用户消息
        AIMessage userMessage = AIMessage.builder()
                .conversationId(conversation.getId())
                .role("user")
                .content(request.getMessage())
                .tokens(estimateTokens(request.getMessage()))
                .build();
        messageMapper.insert(userMessage);

        // 保存AI响应
        AIMessage aiMessage = AIMessage.builder()
                .conversationId(conversation.getId())
                .role("assistant")
                .content(aiResponse)
                .tokens(estimateTokens(aiResponse))
                .build();
        messageMapper.insert(aiMessage);

        // 更新对话统计
        conversation.setMessageCount(conversation.getMessageCount() + 2);
        conversation.setTotalTokens(conversation.getTotalTokens() + userMessage.getTokens() + aiMessage.getTokens());
        conversation.setLastMessageAt(LocalDateTime.now());
        conversationMapper.updateById(conversation);

        return AIChatResponse.builder()
                .conversationId(conversation.getId())
                .response(aiResponse)
                .messageId(aiMessage.getId())
                .tokensUsed(userMessage.getTokens() + aiMessage.getTokens())
                .service((String) aiResult.getOrDefault("service", defaultService))
                .model(conversation.getModel())
                .build();
    }

    private List<MessageDTO> buildMessages(String message, Map<String, Object> context, AIConversation conversation) {
        List<MessageDTO> messages = new ArrayList<>();

        // 系统提示词
        String systemPrompt = getSystemPrompt(context);
        messages.add(MessageDTO.builder().role("system").content(systemPrompt).build());

        // 添加上下文消息
        if (context != null && context.containsKey("history")) {
            List<MessageDTO> contextHistory = (List<MessageDTO>) context.get("history");
            if (contextHistory != null) {
                messages.addAll(contextHistory);
            }
        }

        // 添加历史消息（最近N条）
        LambdaQueryWrapper<AIMessage> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AIMessage::getConversationId, conversation.getId())
               .orderByDesc(AIMessage::getCreatedAt)
               .last("LIMIT " + HISTORY_LIMIT);
        List<AIMessage> historyMessages = messageMapper.selectList(wrapper);
        Collections.reverse(historyMessages);

        for (AIMessage history : historyMessages) {
            messages.add(MessageDTO.builder()
                    .role(history.getRole())
                    .content(history.getContent())
                    .build());
        }

        // 添加当前消息
        messages.add(MessageDTO.builder().role("user").content(message).build());

        return messages;
    }

    private String getSystemPrompt(Map<String, Object> context) {
        StringBuilder prompt = new StringBuilder(baseSystemPrompt);

        if (context != null && context.containsKey("module")) {
            String module = (String) context.get("module");
            switch (module) {
                case "goods":
                    prompt.append("你现在正在处理商品管理模块的问题。");
                    break;
                case "orders":
                    prompt.append("你现在正在处理订单管理模块的问题。");
                    break;
                case "purchase":
                    prompt.append("你现在正在处理采购管理模块的问题。");
                    break;
                case "inventory":
                    prompt.append("你现在正在处理库存管理模块的问题。");
                    break;
                case "finance":
                    prompt.append("你现在正在处理财务管理模块的问题。");
                    break;
            }
        }

        prompt.append("\n\n请用专业、准确、简洁的语言回答用户的问题。如果涉及具体操作，请提供清晰的步骤说明。");
        return prompt.toString();
    }

    @Override
    public Map<String, Object> executeTask(Long userId, String task, Map<String, Object> parameters) {
        Map<String, Object> result;

        switch (task) {
            case "data_analysis":
                result = analyzeData(parameters);
                break;
            case "report_generation":
                result = generateReport(parameters);
                break;
            case "prediction":
                result = makePrediction(parameters);
                break;
            case "recommendation":
                result = provideRecommendation(parameters);
                break;
            case "document_summary":
                result = summarizeDocument(parameters);
                break;
            default:
                result = Map.of(
                    "success", false,
                    "error", "不支持的任务类型: " + task
                );
        }

        return result;
    }

    private Map<String, Object> analyzeData(Map<String, Object> parameters) {
        String type = (String) parameters.getOrDefault("type", "sales");
        String period = (String) parameters.getOrDefault("period", "month");

        Map<String, Object> analysis = new LinkedHashMap<>();
        analysis.put("type", type);
        analysis.put("period", period);
        analysis.put("summary", "根据" + period + "数据，发现以下趋势：");
        analysis.put("insights", Arrays.asList(
            "销售额增长15%",
            "最畅销商品：商品A",
            "客户复购率：45%",
            "库存周转率：2.5次"
        ));
        analysis.put("recommendations", Arrays.asList(
            "增加商品A的库存",
            "优化营销策略提高复购率",
            "关注库存周转率提升"
        ));

        return Map.of(
            "success", true,
            "analysis", analysis,
            "generatedAt", LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
        );
    }

    private Map<String, Object> generateReport(Map<String, Object> parameters) {
        String reportType = (String) parameters.getOrDefault("report_type", "sales");
        String startDate = (String) parameters.getOrDefault("start_date",
                LocalDateTime.now().minusMonths(1).format(DateTimeFormatter.ISO_LOCAL_DATE));
        String endDate = (String) parameters.getOrDefault("end_date",
                LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE));

        Map<String, Object> report = new LinkedHashMap<>();
        report.put("type", reportType);
        report.put("period", startDate + " 至 " + endDate);
        report.put("title", reportType.substring(0, 1).toUpperCase() + reportType.substring(1) + "分析报告");
        report.put("sections", Map.of(
            "executive_summary", "报告摘要内容...",
            "data_analysis", "数据分析内容...",
            "key_findings", "主要发现...",
            "recommendations", "建议措施..."
        ));
        report.put("metrics", Map.of(
            "total_sales", "¥125,000",
            "order_count", 156,
            "average_order_value", "¥801",
            "growth_rate", "15%"
        ));

        return Map.of(
            "success", true,
            "report", report,
            "downloadUrl", "/api/reports/download/" + UUID.randomUUID().toString().substring(0, 8),
            "generatedAt", LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
        );
    }

    private Map<String, Object> makePrediction(Map<String, Object> parameters) {
        String target = (String) parameters.getOrDefault("target", "sales");
        int periods = ((Number) parameters.getOrDefault("periods", 3)).intValue();

        List<Map<String, Object>> predictions = new ArrayList<>();
        double current = 100000;

        Random random = new Random();
        for (int i = 1; i <= periods; i++) {
            double growth = (random.nextInt(11) + 5) / 100.0; // 5-15%增长
            double predicted = current * (1 + growth);

            predictions.add(Map.of(
                "period", "第" + i + "期",
                "value", String.format("%.2f", predicted),
                "growth", String.format("%.1f", growth * 100) + "%",
                "confidence", (random.nextInt(26) + 70) + "%"
            ));

            current = predicted;
        }

        return Map.of(
            "success", true,
            "target", target,
            "predictions", predictions,
            "notes", "基于历史数据的趋势预测，实际结果可能因市场变化而有所不同。"
        );
    }

    private Map<String, Object> provideRecommendation(Map<String, Object> parameters) {
        String area = (String) parameters.getOrDefault("area", "inventory");

        Map<String, List<String>> recommendationsMap = Map.of(
            "inventory", Arrays.asList(
                "优化库存水平，减少积压",
                "建立安全库存机制",
                "实施ABC分类管理",
                "定期盘点，确保账实相符"
            ),
            "sales", Arrays.asList(
                "加强客户关系管理",
                "优化产品定价策略",
                "拓展销售渠道",
                "提升客户服务质量"
            ),
            "purchase", Arrays.asList(
                "建立供应商评估体系",
                "优化采购审批流程",
                "实施集中采购降低成本",
                "加强采购合同管理"
            ),
            "finance", Arrays.asList(
                "加强现金流管理",
                "优化成本控制",
                "完善财务报告体系",
                "加强预算执行监控"
            )
        );

        List<String> areaRecommendations = recommendationsMap.getOrDefault(area, recommendationsMap.get("inventory"));

        return Map.of(
            "success", true,
            "area", area,
            "recommendations", areaRecommendations,
            "priority", "根据当前业务状况，建议优先实施前两项。"
        );
    }

    private Map<String, Object> summarizeDocument(Map<String, Object> parameters) {
        String content = (String) parameters.get("content");
        int maxLength = ((Number) parameters.getOrDefault("max_length", 200)).intValue();

        if (content == null || content.isEmpty()) {
            return Map.of(
                "success", false,
                "error", "文档内容不能为空"
            );
        }

        // 简单摘要算法
        String[] sentences = content.split("[。！？.!?]");
        List<String> validSentences = Arrays.stream(sentences)
                .filter(s -> s.trim().length() > 10)
                .limit(3)
                .collect(Collectors.toList());

        StringBuilder summary = new StringBuilder();
        for (String sentence : validSentences) {
            if (summary.length() + sentence.length() < maxLength) {
                summary.append(sentence.trim()).append("。");
            }
        }

        if (summary.length() == 0) {
            summary.append(content, 0, Math.min(maxLength, content.length())).append("...");
        }

        List<String> keywords = extractKeywords(content);

        return Map.of(
            "success", true,
            "originalLength", content.length(),
            "summaryLength", summary.length(),
            "summary", summary.toString(),
            "keywords", keywords,
            "compressionRate", String.format("%.1f%%", (1 - (double) summary.length() / content.length()) * 100)
        );
    }

    private List<String> extractKeywords(String content) {
        // 简单关键词提取
        String[] words = content.split("\\s+");
        Map<String, Integer> wordCount = new HashMap<>();
        for (String word : words) {
            wordCount.merge(word, 1, Integer::sum);
        }

        List<String> sortedWords = wordCount.entrySet().stream()
                .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
                .map(Map.Entry::getKey)
                .limit(10)
                .collect(Collectors.toList());

        // 过滤常见词
        Set<String> commonWords = Set.of("的", "了", "在", "是", "和", "与", "或", "等", "这个", "那个");
        return sortedWords.stream()
                .filter(w -> !commonWords.contains(w))
                .limit(5)
                .collect(Collectors.toList());
    }

    @Override
    public PageResponse<AIConversation> getConversations(Long userId, String status, String keyword, Integer page, Integer limit) {
        int offset = (page - 1) * limit;

        LambdaQueryWrapper<AIConversation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AIConversation::getUserId, userId)
               .eq(status != null, AIConversation::getStatus, status)
               .like(keyword != null, AIConversation::getTitle, keyword)
               .orderByDesc(AIConversation::getLastMessageAt);

        List<AIConversation> conversations = conversationMapper.selectList(wrapper);
        long total = conversationMapper.countUserConversations(userId);

        // 分页
        int fromIndex = offset;
        int toIndex = Math.min(offset + limit, conversations.size());
        if (fromIndex < conversations.size()) {
            conversations = conversations.subList(fromIndex, toIndex);
        } else {
            conversations = Collections.emptyList();
        }

        return PageResponse.<AIConversation>builder()
                .list(conversations)
                .total(total)
                .page((long) page)
                .totalPages((long) Math.ceil((double) total / limit))
                .pageSize((long) limit)
                .build();
    }

    @Override
    public AIConversation getConversation(Long userId, Long id) {
        AIConversation conversation = conversationMapper.selectById(id);
        if (conversation == null || !conversation.getUserId().equals(userId)) {
            throw new RuntimeException("对话不存在或无权访问");
        }

        // 加载消息列表
        List<AIMessage> messages = messageMapper.selectByConversationId(id);
        // Note: conversation does not have messages field, messages loaded separately if needed

        return conversation;
    }

    @Override
    @Transactional
    public void deleteConversation(Long userId, Long id) {
        AIConversation conversation = conversationMapper.selectById(id);
        if (conversation == null || !conversation.getUserId().equals(userId)) {
            throw new RuntimeException("对话不存在或无权访问");
        }

        // 删除消息
        messageMapper.deleteByConversationId(id);

        // 删除对话
        conversationMapper.deleteById(id);
    }

    @Override
    @Transactional
    public void clearConversation(Long userId, Long id) {
        AIConversation conversation = conversationMapper.selectById(id);
        if (conversation == null || !conversation.getUserId().equals(userId)) {
            throw new RuntimeException("对话不存在或无权访问");
        }

        // 删除消息
        messageMapper.deleteByConversationId(id);

        // 重置统计
        conversation.setMessageCount(0);
        conversation.setTotalTokens(0L);
        conversation.setLastMessageAt(null);
        conversationMapper.updateById(conversation);
    }

    @Override
    public List<Map<String, Object>> getCapabilities() {
        return Arrays.asList(
            Map.of(
                "id", "chat",
                "name", "智能对话",
                "description", "回答ERP系统相关问题，提供操作指导",
                "examples", Arrays.asList("如何创建采购单？", "查看商品库存", "订单处理流程")
            ),
            Map.of(
                "id", "data_analysis",
                "name", "数据分析",
                "description", "分析销售、库存、财务等数据",
                "examples", Arrays.asList("分析本月销售趋势", "库存周转率分析", "客户购买行为分析")
            ),
            Map.of(
                "id", "report_generation",
                "name", "报告生成",
                "description", "自动生成各类业务报告",
                "examples", Arrays.asList("生成销售日报", "制作库存月报", "财务季度分析报告")
            ),
            Map.of(
                "id", "prediction",
                "name", "趋势预测",
                "description", "基于历史数据预测未来趋势",
                "examples", Arrays.asList("预测下月销售额", "库存需求预测", "客户增长预测")
            ),
            Map.of(
                "id", "recommendation",
                "name", "智能建议",
                "description", "提供业务优化建议",
                "examples", Arrays.asList("库存优化建议", "销售策略建议", "成本控制建议")
            ),
            Map.of(
                "id", "document_summary",
                "name", "文档摘要",
                "description", "自动提取文档关键信息",
                "examples", Arrays.asList("合同摘要", "会议纪要整理", "报告要点提取")
            )
        );
    }

    @Override
    public Map<String, Object> getUsageStatistics(Long userId) {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime todayStart = now.toLocalDate().atStartOfDay();
        LocalDateTime todayEnd = todayStart.plusDays(1);
        LocalDateTime monthStart = now.withDayOfMonth(1).toLocalDate().atStartOfDay();
        LocalDateTime monthEnd = monthStart.plusMonths(1);

        // 今日统计
        long todayConversations = conversationMapper.selectCount(
            new LambdaQueryWrapper<AIConversation>()
                .eq(AIConversation::getUserId, userId)
                .ge(AIConversation::getCreatedAt, todayStart)
                .lt(AIConversation::getCreatedAt, todayEnd)
        );
        long todayMessages = messageMapper.countUserMessagesBetween(userId, todayStart, todayEnd);
        long todayTokens = messageMapper.sumUserTokensBetween(userId, todayStart, todayEnd);

        // 月度统计
        long monthConversations = conversationMapper.selectCount(
            new LambdaQueryWrapper<AIConversation>()
                .eq(AIConversation::getUserId, userId)
                .ge(AIConversation::getCreatedAt, monthStart)
                .lt(AIConversation::getCreatedAt, monthEnd)
        );
        long monthMessages = messageMapper.countUserMessagesBetween(userId, monthStart, monthEnd);
        long monthTokens = messageMapper.sumUserTokensBetween(userId, monthStart, monthEnd);

        // 总体统计
        long totalConversations = conversationMapper.countUserConversations(userId);
        long totalMessages = messageMapper.selectCount(
            new LambdaQueryWrapper<AIMessage>()
                .exists("SELECT 1 FROM ai_conversations c WHERE c.id = ai_messages.conversation_id AND c.user_id = " + userId)
        );
        long totalTokens = messageMapper.sumUserTokensBetween(userId,
            LocalDateTime.of(2000, 1, 1, 0, 0), now);

        Map<String, Object> today = new LinkedHashMap<>();
        today.put("conversations", todayConversations);
        today.put("messages", todayMessages);
        today.put("tokens", todayTokens);

        Map<String, Object> month = new LinkedHashMap<>();
        month.put("conversations", monthConversations);
        month.put("messages", monthMessages);
        month.put("tokens", monthTokens);

        Map<String, Object> total = new LinkedHashMap<>();
        total.put("conversations", totalConversations);
        total.put("messages", totalMessages);
        total.put("tokens", totalTokens);

        return Map.of(
            "today", today,
            "month", month,
            "total", total
        );
    }

    private int estimateTokens(String text) {
        int chineseChars = (int) text.chars().filter(c -> c >= 0x4E00 && c <= 0x9FA5).count();
        int otherChars = text.length() - chineseChars * 3;
        return Math.max(1, (int) Math.ceil(chineseChars / 1.5 + otherChars / 4.0));
    }
}
