package handler

import (
	"io"
	"mime"
	"net/http"
	"path/filepath"

	"github.com/gin-gonic/gin"
	"x-agents/server/internal/repository"
	"x-agents/server/internal/service"
)

type UploadHandler struct {
	uploadService    *service.UploadService
	knowledgeRepo    *repository.KnowledgeRepository
}

func NewUploadHandler(uploadService *service.UploadService, knowledgeRepo *repository.KnowledgeRepository) *UploadHandler {
	return &UploadHandler{uploadService: uploadService, knowledgeRepo: knowledgeRepo}
}

// Upload 上传文件
func (h *UploadHandler) Upload(c *gin.Context) {
	file, err := c.FormFile("file")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "No file uploaded"})
		return
	}

	// 检查文件大小（最大 100MB）
	if file.Size > 100*1024*1024 {
		c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "File too large (max 100MB)"})
		return
	}

	result, err := h.uploadService.Upload(file)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
		return
	}

	if !result.Success {
		c.JSON(http.StatusInternalServerError, result)
		return
	}

	c.JSON(http.StatusOK, result)
}

// Delete 删除文件
func (h *UploadHandler) Delete(c *gin.Context) {
	filename := c.Param("filename")
	if filename == "" {
		c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "Filename is required"})
		return
	}

	if err := h.uploadService.DeleteFile(filename); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"success": true, "message": "File deleted"})
}

// ProxyFile 代理文件访问（解决 MinIO 内网地址和 HTTPS 问题）
func (h *UploadHandler) ProxyFile(c *gin.Context) {
	fileKey := c.Query("key")
	kbID := c.Query("kb_id")

	if fileKey == "" {
		c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "File key is required"})
		return
	}

	var content io.Reader
	var contentType string

	// 如果提供了知识库 ID，使用知识库的存储配置
	if kbID != "" && h.knowledgeRepo != nil {
		kb, err := h.knowledgeRepo.FindByID(kbID)
		if err == nil && kb.StorageConfig.Type == "minio" {
			reader, ct, err := h.uploadService.GetFileContentWithConfig(fileKey, kb.StorageConfig)
			if err != nil {
				c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
				return
			}
			content = reader
			contentType = ct
			defer reader.Close()
		} else {
			// 使用全局配置
			reader, ct, err := h.uploadService.GetFileContent(fileKey)
			if err != nil {
				c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
				return
			}
			content = reader
			contentType = ct
			defer reader.Close()
		}
	} else {
		// 使用全局配置
		reader, ct, err := h.uploadService.GetFileContent(fileKey)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": err.Error()})
			return
		}
		content = reader
		contentType = ct
		defer reader.Close()
	}

	// 设置响应头
	// 如果 Content-Type 是 application/octet-stream，根据文件扩展名推断
	if contentType == "application/octet-stream" {
		ext := filepath.Ext(fileKey)
		if detected := mime.TypeByExtension(ext); detected != "" {
			contentType = detected
		}
	}

	if contentType != "" {
		c.Header("Content-Type", contentType)
	} else {
		c.Header("Content-Type", "application/octet-stream")
	}
	c.Header("Content-Disposition", "inline")

	// 直接流式输出文件内容
	c.DataFromReader(http.StatusOK, -1, contentType, content, nil)
}
