package org.xyzh.ai.service.impl;

import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import org.xyzh.ai.client.DifyApiClient;
import org.xyzh.ai.client.dto.DifyFileInfo;
import org.xyzh.ai.client.dto.DocumentUploadRequest;
import org.xyzh.ai.client.dto.DocumentUploadResponse;
import org.xyzh.api.ai.dto.TbAgent;
import org.xyzh.api.ai.service.AIFileUploadService;
import org.xyzh.api.ai.service.AgentService;
import org.xyzh.api.file.dto.TbSysFileDTO;
import org.xyzh.api.file.service.FileService;
import org.xyzh.common.auth.utils.LoginUtil;
import org.xyzh.common.core.domain.ResultDomain;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @description    AI文件上传服务实现（同时上传到MinIO和Dify）
 * @filename AIFileUploadServiceImpl.java
 * @author yslg
 * @copyright xyzh
 * @since 2025-12-17
 */
@DubboService(version = "1.0.0", group = "ai", timeout = 30000, retries = 0)
public class AIFileUploadServiceImpl implements AIFileUploadService {
    private static final Logger logger = LoggerFactory.getLogger(AIFileUploadServiceImpl.class);

    @Autowired
    private DifyApiClient difyApiClient;

    @Autowired
    private AgentService agentService;

    @DubboReference(version = "1.0.0", group = "file", timeout = 30000, retries = 0)
    private FileService fileService;

    // ============================ 对话文件管理 ============================

    @Override
    public ResultDomain<Map<String, Object>> uploadFileForChat(MultipartFile file, String agentId) {
        // 1. 参数校验
        if (file == null || file.isEmpty()) {
            return ResultDomain.failure("文件不能为空");
        }
        if (!StringUtils.hasText(agentId)) {
            return ResultDomain.failure("智能体ID不能为空");
        }

        // 2. 获取智能体API Key
        ResultDomain<TbAgent> agentResult = agentService.selectAgentById(agentId);
        if (!agentResult.getSuccess() || agentResult.getData() == null) {
            return ResultDomain.failure("智能体不存在");
        }
        TbAgent agent = agentResult.getData();

        // 3. 获取当前用户
        String userId = LoginUtil.getCurrentUserId();
        if (!StringUtils.hasText(userId)) {
            userId = "anonymous";
        }

        File tempFile = null;
        String sysFileId = null;
        String sysFileUrl = null;

        try {
            // 4. 上传到MinIO（通过FileService，使用字节数组方式）
            byte[] fileBytes = file.getBytes();
            String fileName = file.getOriginalFilename();
            String contentType = file.getContentType();
            ResultDomain<TbSysFileDTO> fileResult = fileService.uploadFileBytes(fileBytes, fileName, contentType, "ai-chat", agentId);
            if (fileResult.getSuccess() && fileResult.getData() != null) {
                TbSysFileDTO sysFile = fileResult.getData();
                sysFileId = sysFile.getFileId();
                sysFileUrl = sysFile.getUrl();
                logger.info("上传文件到MinIO成功: fileId={}, url={}", sysFileId, sysFileUrl);
            } else {
                logger.warn("上传文件到MinIO失败: {}", fileResult.getMessage());
                // MinIO上传失败不阻断流程，继续上传到Dify
            }

            // 5. 将MultipartFile转换为临时File用于Dify上传
            tempFile = File.createTempFile("upload_", "_" + file.getOriginalFilename());
            file.transferTo(tempFile);

            // 6. 上传到Dify
            DifyFileInfo difyFile = difyApiClient.uploadFileForChat(tempFile, file.getOriginalFilename(), userId, agent.getApiKey());
            if (difyFile != null && StringUtils.hasText(difyFile.getId())) {
                logger.info("上传对话文件到Dify成功: agentId={}, difyFileId={}", agentId, difyFile.getId());
                
                Map<String, Object> result = new HashMap<>();
                // Dify返回的信息
                result.put("id", difyFile.getId());
                result.put("name", difyFile.getName());
                result.put("size", difyFile.getSize());
                result.put("type", difyFile.getType());
                result.put("extension", difyFile.getExtension());
                result.put("mime_type", difyFile.getMimeType());
                result.put("upload_file_id", difyFile.getUploadFileId());
                // 系统文件信息（用于前端展示和数据库存储）
                result.put("sys_file_id", sysFileId);
                result.put("preview_url", sysFileUrl);
                result.put("source_url", sysFileUrl);
                
                return ResultDomain.success("上传成功", result);
            }
            return ResultDomain.failure("上传文件到Dify失败");
        } catch (Exception e) {
            logger.error("上传对话文件异常: {}", e.getMessage(), e);
            return ResultDomain.failure("上传文件异常: " + e.getMessage());
        } finally {
            if (tempFile != null && tempFile.exists()) {
                tempFile.delete();
            }
        }
    }

    // ============================ 知识库Dify文档管理 ============================

    /**
     * @description    上传文件到Dify知识库（只负责Dify上传，不处理minio和数据库）
     * @param    difyDatasetId Dify知识库ID
     * @param    file 文件
     * @param    fileName 文件名
     * @param    indexingTechnique 索引方式
     * @return    ResultDomain<String> Dify文档ID
     * @author    yslg
     * @since 2025-12-18
     */
    @Override
    public ResultDomain<String> uploadFileToDify(String difyDatasetId, File file, String fileName, String indexingTechnique) {
        if (!StringUtils.hasText(difyDatasetId)) {
            return ResultDomain.failure("Dify知识库ID不能为空");
        }
        if (file == null || !file.exists()) {
            return ResultDomain.failure("文件不能为空");
        }

        try {
            DocumentUploadRequest uploadRequest = new DocumentUploadRequest();
            uploadRequest.setName(fileName);
            if (StringUtils.hasText(indexingTechnique)) {
                uploadRequest.setIndexingTechnique(indexingTechnique);
            }

            DocumentUploadResponse uploadResponse = difyApiClient.uploadDocumentByFile(
                    difyDatasetId,
                    file,
                    fileName,
                    uploadRequest
            );

            if (uploadResponse != null && uploadResponse.getDocument() != null) {
                String difyDocumentId = uploadResponse.getDocument().getId();
                logger.info("上传文件到Dify成功: difyDatasetId={}, difyDocumentId={}", difyDatasetId, difyDocumentId);
                return ResultDomain.success("上传成功", difyDocumentId);
            }
            return ResultDomain.failure("上传文件到Dify失败");
        } catch (Exception e) {
            logger.error("上传文件到Dify异常: {}", e.getMessage(), e);
            return ResultDomain.failure("上传文件到Dify异常: " + e.getMessage());
        }
    }

    /**
     * @description    从Dify知识库删除文档
     * @param    difyDatasetId Dify知识库ID
     * @param    difyDocumentId Dify文档ID
     * @return    ResultDomain<Boolean> 删除结果
     * @author    yslg
     * @since 2025-12-18
     */
    @Override
    public ResultDomain<Boolean> deleteFileFromDify(String difyDatasetId, String difyDocumentId) {
        if (!StringUtils.hasText(difyDatasetId)) {
            return ResultDomain.failure("Dify知识库ID不能为空");
        }
        if (!StringUtils.hasText(difyDocumentId)) {
            return ResultDomain.failure("Dify文档ID不能为空");
        }

        try {
            difyApiClient.deleteDocument(difyDatasetId, difyDocumentId);
            logger.info("从Dify删除文档成功: difyDatasetId={}, difyDocumentId={}", difyDatasetId, difyDocumentId);
            return ResultDomain.success("删除成功", true);
        } catch (Exception e) {
            logger.error("从Dify删除文档异常: {}", e.getMessage(), e);
            return ResultDomain.failure("从Dify删除文档异常: " + e.getMessage());
        }
    }

    /**
     * @description    批量从Dify知识库删除文档
     * @param    difyDatasetId Dify知识库ID
     * @param    difyDocumentIds Dify文档ID列表
     * @return    ResultDomain<Boolean> 删除结果
     * @author    yslg
     * @since 2025-12-18
     */
    @Override
    public ResultDomain<Boolean> batchDeleteFilesFromDify(String difyDatasetId, List<String> difyDocumentIds) {
        if (!StringUtils.hasText(difyDatasetId)) {
            return ResultDomain.failure("Dify知识库ID不能为空");
        }
        if (difyDocumentIds == null || difyDocumentIds.isEmpty()) {
            return ResultDomain.failure("Dify文档ID列表不能为空");
        }

        int successCount = 0;
        int failCount = 0;
        for (String difyDocumentId : difyDocumentIds) {
            if (StringUtils.hasText(difyDocumentId)) {
                try {
                    difyApiClient.deleteDocument(difyDatasetId, difyDocumentId);
                    successCount++;
                } catch (Exception e) {
                    logger.warn("批量删除Dify文档失败: difyDocumentId={}, error={}", difyDocumentId, e.getMessage());
                    failCount++;
                }
            }
        }

        logger.info("批量从Dify删除文档完成: 成功={}, 失败={}", successCount, failCount);
        if (failCount == 0) {
            return ResultDomain.success("批量删除成功", true);
        } else if (successCount == 0) {
            return ResultDomain.failure("批量删除全部失败");
        } else {
            return ResultDomain.success("部分删除成功", true);
        }
    }
}
