package org.xyzh.ai.controller;

import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import org.xyzh.ai.client.dto.ConversationVariablesResponse;
import org.xyzh.api.ai.dto.ChatPrepareData;
import org.xyzh.api.ai.dto.TbChat;
import org.xyzh.api.ai.dto.TbChatMessage;
import org.xyzh.api.ai.service.AIFileUploadService;
import org.xyzh.api.ai.service.AgentChatService;
import org.xyzh.common.auth.utils.LoginUtil;
import org.xyzh.common.core.domain.LoginDomain;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.core.page.PageDomain;
import org.xyzh.common.core.page.PageRequest;
import org.xyzh.common.utils.NonUtils;
import org.xyzh.common.utils.validation.ValidationParam;
import org.xyzh.common.utils.validation.ValidationResult;
import org.xyzh.common.utils.validation.ValidationUtils;

import java.io.IOException;
import java.util.Arrays;
import java.util.Map;

/**
 * @description 智能体对话控制器 所有接口开放
 * @filename ChatController.java
 * @author yslg
 * @copyright xyzh
 * @since 2025-12-17
 */
@Slf4j
@RestController
@Validated
@RequestMapping("/ai/chat")
public class ChatController {

    @Autowired
    private AgentChatService chatService;

    @Autowired
    private AIFileUploadService fileUploadService;

    @Autowired
    private org.xyzh.ai.client.DifyApiClient difyApiClient;

    // ====================== 会话管理 ======================

    /**
     * @description    创建会话
     * @param    
     * @author    yslg
     * @since 2025-12-17
     */
    @PostMapping("/conversation")
    public ResultDomain<TbChat> createChat(@RequestBody TbChat chat, @RequestHeader("Authorization") String token) {
        ValidationResult result = ValidationUtils.validate(chat, Arrays.asList(
            ValidationUtils.requiredString("agentId", "智能体id", 1, 100),
            ValidationUtils.requiredString("title", "对话标题", 1, 100),
            ValidationUtils.requiredString("userId", "用户id", 1, 100)
        ));
        if (!result.isValid()) {
            return ResultDomain.failure(result.getAllErrors());
        }
        // 默认来客，如果token不为空且token对应的用户存在，说明是员工
        chat.setUserType(false);
        if(NonUtils.isNotEmpty(token)){
            LoginDomain loginDomain = LoginUtil.getCurrentLogin();
            if (NonUtils.isNotEmpty(loginDomain) && !"guest".equals(loginDomain.getUser().getStatus())) {
                chat.setUserType(true);
            }
        }
        
        log.info("创建会话: agentId={}, title={}, userId={}, userType={}", chat.getAgentId(), chat.getTitle(), chat.getUserId(), chat.getUserType());
        return chatService.createChat(chat);
    }

    /**
     * @description    更新对话
     * @param    
     * @author    yslg
     * @since 2025-12-17
     */
    @PutMapping("/conversation")
    public ResultDomain<TbChat> updateChat(@RequestBody TbChat chat, @RequestHeader("Authorization") String token) {
        ValidationResult result = ValidationUtils.validate(chat, Arrays.asList(
            ValidationUtils.requiredString("agentId", "智能体id", 1, 100),
            ValidationUtils.requiredString("title", "对话标题", 1, 100),
            ValidationUtils.requiredString("userId", "用户id", 1, 100),
            ValidationParam.builder().fieldName("userType").fieldLabel("用户类型").required().fieldType(Boolean.class).build()
        ));
        if (!result.isValid()) {
            return ResultDomain.failure(result.getAllErrors());
        }
        chat.setUserType(false);
        if(NonUtils.isNotEmpty(token)){
            LoginDomain loginDomain = LoginUtil.getCurrentLogin();
            if (NonUtils.isNotEmpty(loginDomain) && !"guest".equals(loginDomain.getUser().getStatus())) {
                chat.setUserType(true);
            }
        }
        log.info("更新会话: chatId={}", chat.getChatId());
        return chatService.updateChat(chat);
    }

    /**
     * @description    删除对话
     * @param    
     * @author    yslg
     * @since 2025-12-17
     */
    @DeleteMapping("/conversation")
    public ResultDomain<TbChat> deleteChat(@RequestBody TbChat chat, @RequestHeader("Authorization") String token) {
        chat.setUserType(false);
        if(NonUtils.isNotEmpty(token)){
            LoginDomain loginDomain = LoginUtil.getCurrentLogin();
            if (NonUtils.isNotEmpty(loginDomain) && !"guest".equals(loginDomain.getUser().getStatus())) {
                chat.setUserType(true);
            }
        }
        log.info("删除会话: chatId={}", chat.getChatId());
        return chatService.deleteChat(chat);
    }

    /**
     * @description    获取对话列表
     * @param    
     * @author    yslg
     * @since 2025-12-17
     */
    @PostMapping("/conversation/list")
    public ResultDomain<TbChat> getChatList(@RequestBody TbChat filter, @RequestHeader("Authorization") String token) {
        log.info("获取会话列表: agentId={}", filter.getAgentId());

        filter.setUserType(false);
        if(NonUtils.isNotEmpty(token)){
            LoginDomain loginDomain = LoginUtil.getCurrentLogin();
            if (NonUtils.isNotEmpty(loginDomain) && !"guest".equals(loginDomain.getUser().getStatus())) {
                filter.setUserType(true);
            }
        }
        return chatService.getChatList(filter);
    }

    /**
     * @description    分页获取对话列表
     * @param    pageRequest 分页请求参数
     * @author    yslg
     * @since 2025-12-17
     */
    @PostMapping("/conversation/page")
    public ResultDomain<TbChat> getChatPage(@RequestBody PageRequest<TbChat> pageRequest, @RequestHeader("Authorization") String token) {
        log.info("分页获取会话列表: agentId={}", pageRequest.getFilter().getAgentId());

        pageRequest.getFilter().setUserType(false);
        if(NonUtils.isNotEmpty(token)){
            LoginDomain loginDomain = LoginUtil.getCurrentLogin();
            if (NonUtils.isNotEmpty(loginDomain) && !"guest".equals(loginDomain.getUser().getStatus())) {
                pageRequest.getFilter().setUserType(true);
            }
        }
        return chatService.getChatPage(pageRequest);
    }

    /**
     * @description    获取对话变量
     * @param    params 请求参数（包含agentId, conversationId, userId, lastId, limit）
     * @author    yslg
     * @since 2025-12-29
     */
    @PostMapping("/conversation/variables")
    public ResultDomain<org.xyzh.ai.client.dto.ConversationVariablesResponse> getConversationVariables(
            @RequestBody Map<String, Object> params,
            @RequestHeader("Authorization") String token) {

        // 参数验证
        ValidationResult result = ValidationUtils.validateMap(params, Arrays.asList(
            ValidationUtils.requiredString("agentId", "智能体ID", 1, 100),
            ValidationUtils.requiredString("conversationId", "会话ID", 1, 100),
            ValidationUtils.requiredString("userId", "用户ID", 1, 100)
        ));
        if (!result.isValid()) {
            return ResultDomain.failure(result.getAllErrors());
        }

        String agentId = (String) params.get("agentId");
        String conversationId = (String) params.get("conversationId");
        String userId = (String) params.get("userId");
        String lastId = params.containsKey("lastId") ? (String) params.get("lastId") : null;
        Integer limit = params.containsKey("limit") ?
            Integer.parseInt(params.get("limit").toString()) : 20;

        log.info("获取对话变量: agentId={}, conversationId={}, userId={}", agentId, conversationId, userId);

        try {
            // 获取智能体信息以获取 API Key
            // 这里需要根据 agentId 获取对应的 API Key
            // 暂时先使用一个占位符,实际使用时需要从数据库或配置中获取
            // 或者通过 chatService 获取智能体配置

            // 调用 Dify API 获取会话变量
            ConversationVariablesResponse response =
                difyApiClient.getConversationVariables(conversationId, userId, lastId, limit, agentId);

            return ResultDomain.success("获取对话变量成功",response);
        } catch (Exception e) {
            log.error("获取对话变量失败", e);
            return ResultDomain.failure("获取对话变量失败: " + e.getMessage());
        }
    }

    // ====================== 消息管理 ======================

    /**
     * @description    获取对话消息列表
     * @param    
     * @author    yslg
     * @since 2025-12-17
     */
    @PostMapping("/messages")
    public ResultDomain<TbChatMessage> getMessageList(@RequestBody TbChat filter, @RequestHeader("Authorization") String token) {
        ValidationResult result = ValidationUtils.validate(filter, Arrays.asList(
            ValidationUtils.requiredString("agentId", "智能体id",10,50),
            ValidationUtils.requiredString("chatId", "对话Id", 10, 50),
            ValidationUtils.requiredString("userId", "用户Id")
        ));

        filter.setUserType(false);
        if(NonUtils.isNotEmpty(token)){
            LoginDomain loginDomain = LoginUtil.getCurrentLogin();
            if (NonUtils.isNotEmpty(loginDomain) && !"guest".equals(loginDomain.getUser().getStatus())) {
                filter.setUserType(true);
            }
        }
        log.info("获取消息列表: chatId={}", filter.getChatId());
        return chatService.getChatMessageList(filter);
    }

    // ====================== 流式对话 ======================

    /**
     * @description    准备流式对话会话数据
     * @param    chatPrepareData
     * @author    yslg
     * @since 2025-12-17
     */
    @PostMapping("/stream/prepare")
    public ResultDomain<String> prepareStreamChat(@RequestBody ChatPrepareData chatPrepareData, @RequestHeader("Authorization") String token) {
        ValidationResult result = ValidationUtils.validate(chatPrepareData, Arrays.asList(
            ValidationUtils.requiredString("agentId", "智能体Id", 1, 50),
            ValidationUtils.requiredString("chatId", "会话Id", 1, 50),
            ValidationUtils.requiredString("query", "用户问题"),
            ValidationUtils.requiredString("userId", "用户Id", 1, 100)
        ));
        if(!result.isValid()){
            return ResultDomain.failure(result.getAllErrors());
        }
        // 设置用户类型
        chatPrepareData.setUserType(false);
        if(NonUtils.isNotEmpty(token)){
            LoginDomain loginDomain = LoginUtil.getCurrentLogin();
            if (NonUtils.isNotEmpty(loginDomain) && !"guest".equals(loginDomain.getUser().getStatus())) {
                chatPrepareData.setUserType(true);
            }
        }
        log.info("准备流式对话: agentId={}, chatId={}, query={}", chatPrepareData.getAgentId(), chatPrepareData.getChatId(), chatPrepareData.getQuery());
        return chatService.prepareChatMessageSession(chatPrepareData);
    }

    /**
     * @description    进行流式对话
     * @param    
     * @author    yslg
     * @since 2025-12-17
     */
    @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter streamChat(@RequestParam("sessionId") String sessionId) {
        if(NonUtils.isEmpty(sessionId)){
            SseEmitter emitter = new SseEmitter(300000L);
            try {
                emitter.send(SseEmitter.event().name("error").data("{\"message\":\"会话不存在\"}"));
            } catch (IOException e) {
                log.error("发送错误事件失败", e);
            }finally {
                emitter.complete();
            }
            return emitter;
        }
        log.info("建立SSE连接: sessionId={}", sessionId);
        return chatService.streamChatMessageWithSse(sessionId);
    }

    /**
     * @description    停止会话
     * @param    
     * @author    yslg
     * @since 2025-12-17
     */
    @PostMapping("/stop")
    public ResultDomain<Boolean> stopChat(@RequestBody Map<String, String> params, @RequestHeader("Authorization") String token) {
        ValidationResult result = ValidationUtils.validateMap(params, Arrays.asList(
            ValidationUtils.requiredString("taskId", "任务ID"),
            ValidationUtils.requiredString("agentId", "智能体ID"),
            ValidationUtils.requiredString("userId", "用户ID")
        ));
        if (!result.isValid()) {
            return ResultDomain.failure(result.getAllErrors());
        }
        TbChat filter = new TbChat();
        filter.setAgentId(params.get("agentId"));
        filter.setUserId(params.get("userId"));
        filter.setUserType(false);
        if(NonUtils.isNotEmpty(token)){
            LoginDomain loginDomain = LoginUtil.getCurrentLogin();
            if (NonUtils.isNotEmpty(loginDomain) && !"guest".equals(loginDomain.getUser().getStatus())) {
                filter.setUserType(true);
            }
        }
        log.info("停止对话: taskId={}", params.get("taskId"));
        return chatService.stopChatMessageByTaskId(filter, params.get("taskId"));
    }

    /**
     * @description    评价消息
     * @param    
     * @author    yslg
     * @since 2025-12-17
     */
    @PostMapping("/comment")
    public ResultDomain<Boolean> commentMessage(@RequestBody Map<String, String> params, @RequestHeader("Authorization") String token) {
        ValidationResult result = ValidationUtils.validateMap(params, Arrays.asList(
            ValidationUtils.requiredString("agentId", "智能体ID"),
            ValidationUtils.requiredString("chatId", "对话ID"),
            ValidationUtils.requiredString("messageId", "消息ID"),
            ValidationUtils.requiredString("comment", "评价"),
            ValidationUtils.requiredString("userId", "用户ID")
        ));
        if (!result.isValid()) {
            return ResultDomain.failure(result.getAllErrors());
        }
        TbChat filter = new TbChat();
        filter.setAgentId(params.get("agentId"));
        filter.setChatId(params.get("chatId"));
        filter.setUserId(params.get("userId"));
        filter.setUserType(false);
        if(NonUtils.isNotEmpty(token)){
            LoginDomain loginDomain = LoginUtil.getCurrentLogin();
            if (NonUtils.isNotEmpty(loginDomain) && !"guest".equals(loginDomain.getUser().getStatus())) {
                filter.setUserType(true);
            }
        }
        log.info("评价消息: messageId={}, comment={}", params.get("messageId"), params.get("comment"));
        return chatService.commentChatMessage(filter, params.get("messageId"), params.get("comment"));
    }

    // ====================== 文件上传 ======================

    /**
     * @description    上传文件用于对话（图文多模态）
     * @param    file 文件
     * @param    agentId 智能体ID
     * @author    yslg
     * @since 2025-12-17
     */
    @PostMapping(value = "/file/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResultDomain<Map<String, Object>> uploadFileForChat(
            @RequestPart("file") @NotNull MultipartFile file,
            @RequestPart("agentId") @NotNull String agentId) {
        log.info("上传对话文件: agentId={}, fileName={}", agentId, file.getOriginalFilename());
        return fileUploadService.uploadFileForChat(file, agentId);
    }
}
