package com.ruoyi.oa.controller;

import java.util.*;

import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.oa.domain.bo.OaAiChatBo;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;

import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.oa.domain.vo.SysOaAiConversationVo;
import com.ruoyi.oa.domain.vo.SysOaAiMessageVo;
import com.ruoyi.oa.domain.bo.SysOaAiConversationBo;
import com.ruoyi.oa.domain.bo.SysOaAiMessageBo;
import com.ruoyi.oa.service.ISysOaAiConversationService;
import com.ruoyi.oa.service.ISysOaAiMessageService;
import com.ruoyi.oa.service.ISysOaAiConfigService;
import com.ruoyi.oa.service.IAiDataQueryService;
import com.ruoyi.oa.utils.AiServiceUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import lombok.extern.slf4j.Slf4j;

/**
 * AI对话管理
 *
 * @author ruoyi
 * @date 2024-12-19
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/oa/ai")
@Slf4j
public class SysOaAiController extends BaseController {

    private final ISysOaAiConversationService conversationService;
    private final ISysOaAiMessageService messageService;
    private final ISysOaAiConfigService configService;
    private final AiServiceUtil aiServiceUtil;
    private final IAiDataQueryService aiDataQueryService;

    /**
     * 查询AI对话历史列表
     */
    @GetMapping("/conversation/list")
    public TableDataInfo<SysOaAiConversationVo> list(SysOaAiConversationBo bo, PageQuery pageQuery) {
        bo.setUserId(LoginHelper.getUserId());
        return conversationService.queryPageList(bo, pageQuery);
    }

    /**
     * 查询我的AI对话历史列表
     */
    @GetMapping("/conversation/my-list")
    public R<List<SysOaAiConversationVo>> myConversations() {
        List<SysOaAiConversationVo> list = conversationService.queryByUserId(LoginHelper.getUserId());
        return R.ok(list);
    }

    /**
     * 获取AI对话历史详细信息
     *
     * @param conversationId 主键
     */
    @GetMapping("/conversation/{conversationId}")
    public R<SysOaAiConversationVo> getConversationInfo(@NotNull(message = "主键不能为空") @PathVariable Long conversationId) {
        return R.ok(conversationService.queryById(conversationId));
    }

    /**
     * 新增AI对话历史
     */
    @Log(title = "AI对话历史", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/conversation")
    public R<Void> addConversation(@Validated(AddGroup.class) @RequestBody SysOaAiConversationBo bo) {
        bo.setUserId(LoginHelper.getUserId());
        return toAjax(conversationService.insertByBo(bo));
    }

    /**
     * 修改AI对话历史
     */
    @Log(title = "AI对话历史", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping("/conversation")
    public R<Void> editConversation(@Validated(EditGroup.class) @RequestBody SysOaAiConversationBo bo) {
        return toAjax(conversationService.updateByBo(bo));
    }

    /**
     * 删除AI对话历史
     *
     * @param conversationIds 主键串
     */
    @Log(title = "AI对话历史", businessType = BusinessType.DELETE)
    @DeleteMapping("/conversation/{conversationIds}")
    public R<Void> removeConversation(@NotEmpty(message = "主键不能为空")
                                      @PathVariable Long[] conversationIds) {
        return toAjax(conversationService.deleteWithValidByIds(Arrays.asList(conversationIds), true));
    }

    /**
     * 查询AI对话详情列表
     */
    @GetMapping("/message/list")
    public TableDataInfo<SysOaAiMessageVo> messageList(SysOaAiMessageBo bo, PageQuery pageQuery) {
        return messageService.queryPageList(bo, pageQuery);
    }

    /**
     * 根据对话ID查询消息列表
     */
    @GetMapping("/message/conversation/{conversationId}")
    public R<List<SysOaAiMessageVo>> getMessagesByConversation(@PathVariable Long conversationId) {
        List<SysOaAiMessageVo> messages = messageService.queryByConversationId(conversationId);
        return R.ok(messages);
    }

    /**
     * 查询对话详情（包含所有消息）
     */
    @GetMapping("/conversation/{conversationId}/messages")
    public R<List<SysOaAiMessageVo>> getConversationMessages(@PathVariable Long conversationId) {
        List<SysOaAiMessageVo> messages = messageService.queryByConversationId(conversationId);
        return R.ok(messages);
    }

    /**
     * 获取AI对话详情详细信息
     *
     * @param messageId 主键
     */
    @GetMapping("/message/{messageId}")
    public R<SysOaAiMessageVo> getMessageInfo(@NotNull(message = "主键不能为空") @PathVariable Long messageId) {
        return R.ok(messageService.queryById(messageId));
    }

    /**
     * 新增AI对话详情
     */
    @Log(title = "AI对话详情", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/message")
    public R<Void> addMessage(@Validated(AddGroup.class) @RequestBody SysOaAiMessageBo bo) {
        return toAjax(messageService.insertByBo(bo));
    }

    /**
     * 修改AI对话详情
     */
    @Log(title = "AI对话详情", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping("/message")
    public R<Void> editMessage(@Validated(EditGroup.class) @RequestBody SysOaAiMessageBo bo) {
        return toAjax(messageService.updateByBo(bo));
    }

    /**
     * 删除AI对话详情
     *
     * @param messageIds 主键串
     */
    @Log(title = "AI对话详情", businessType = BusinessType.DELETE)
    @DeleteMapping("/message/{messageIds}")
    public R<Void> removeMessage(@NotEmpty(message = "主键不能为空")
                                 @PathVariable Long[] messageIds) {
        return toAjax(messageService.deleteWithValidByIds(Arrays.asList(messageIds), true));
    }

    /**
     * 创建新对话
     */
    @PostMapping("/conversation/create")
    public R<Map<String, Object>> createConversation(@RequestBody SysOaAiConversationBo bo) {
        bo.setUserId(LoginHelper.getUserId());
        boolean success = conversationService.insertByBo(bo);
        
        if (success) {
            // 获取刚创建的对话ID
            Map<String, Object> result = new HashMap<>();
            result.put("conversationId", bo.getConversationId());
            result.put("conversationTitle", bo.getConversationTitle());
            result.put("modelName", bo.getModelName());
            
            return R.ok(result);
        } else {
            return R.fail("创建对话失败");
        }
    }

    /**
     * 结束对话
     */
    @PostMapping("/conversation/{conversationId}/end")
    public R<Void> endConversation(@PathVariable Long conversationId) {
        // 清除对话缓存
        aiServiceUtil.clearConversationCache(conversationId);
        return toAjax(conversationService.endConversation(conversationId));
    }

    /**
     * 清除对话缓存
     */
    @DeleteMapping("/conversation/{conversationId}/cache")
    public R<Void> clearConversationCache(@PathVariable Long conversationId) {
        aiServiceUtil.clearConversationCache(conversationId);
        return R.ok("缓存已清除");
    }

    /**
     * 清除AI配置缓存
     */
    @DeleteMapping("/cache/config")
    public R<Void> clearAiConfigCache() {
        aiServiceUtil.clearAiConfigCache();
        return R.ok("AI配置缓存已清除");
    }

    /**
     * 发送消息给AI
     */
    @PostMapping("/chat")
    public R<Map<String, Object>> chat(@RequestBody OaAiChatBo bo) {
        try {
            // 1. 保存用户消息
            messageService.addUserMessage(bo.getConversationId(), bo.getMessage());
            
            // 2. 获取对话历史（优先从Redis缓存获取）
            List<SysOaAiMessageVo> conversationHistory = aiServiceUtil.getCachedConversationHistory(bo.getConversationId());
            if (conversationHistory == null) {
                // 缓存中没有，从数据库获取
                conversationHistory = messageService.queryByConversationId(bo.getConversationId());
                // 缓存对话历史
                aiServiceUtil.cacheConversationHistory(bo.getConversationId(), conversationHistory);
            }
            
            // 3. 调用AI服务获取回复（传递对话历史）
            String aiResponse = callAiServiceWithHistory(bo.getMessage(), conversationHistory);
            
            // 4. 保存AI回复
            messageService.addAiMessage(bo. getConversationId(), aiResponse, 0, java.math.BigDecimal.ZERO);
            
            // 5. 更新对话历史缓存
            List<SysOaAiMessageVo> updatedHistory = messageService.queryByConversationId(bo.getConversationId());
            aiServiceUtil.cacheConversationHistory(bo.getConversationId(), updatedHistory);
            
            Map<String, Object> result = new HashMap<>();
            result.put("conversationId", bo.getConversationId());
            result.put("response", aiResponse);
            
            return R.ok(result);
        } catch (Exception e) {
            return R.fail("AI服务调用失败: " + e.getMessage());
        }
    }

    /**
     * 调用AI服务（带对话历史）
     */
    private String callAiServiceWithHistory(String message, List<SysOaAiMessageVo> conversationHistory) {
        return aiServiceUtil.callDeepSeekWithHistory(message, conversationHistory);
    }

    /**
     * 调用AI服务（单次对话）
     */
    private String callAiService(String message) {
        return aiServiceUtil.callDeepSeek(message);
    }

    /**
     * AI数据查询接口
     * 根据用户自然语言描述查询数据库数据
     */
    @PostMapping("/data-query")
    public R<com.ruoyi.oa.domain.vo.DynamicDataVo> queryDataByAi(@Validated @RequestBody com.ruoyi.oa.domain.bo.OaAiDataQueryBo queryBo) {
        try {
            com.ruoyi.oa.domain.vo.DynamicDataVo result = aiDataQueryService.queryDataByAi(queryBo);
            return R.ok(result);
        } catch (Exception e) {
            log.error("AI数据查询失败", e);
            return R.fail("AI数据查询失败: " + e.getMessage());
        }
    }

    /**
     * 根据关键词匹配相关表
     */
    @PostMapping("/match-tables")
    public R<java.util.List<String>> matchTablesByKeywords(@RequestBody java.util.Map<String, String[]> request) {
        try {
            String[] keywords = request.get("keywords");
            if (keywords == null || keywords.length == 0) {
                return R.fail("关键词不能为空");
            }
            java.util.List<String> matchedTables = aiDataQueryService.matchTablesByKeywords(keywords);
            return R.ok(matchedTables);
        } catch (Exception e) {
            log.error("表匹配失败", e);
            return R.fail("表匹配失败: " + e.getMessage());
        }
    }


} 