package controller

import (
	"log"
	"net/http"
	"strconv"

	"github.com/2930134478/AI-CS/backend/service"
	"github.com/gin-gonic/gin"
)

// KnowledgeBaseController 知识库控制器
type KnowledgeBaseController struct {
	knowledgeBaseService   *service.KnowledgeBaseService
	embeddingConfigService *service.EmbeddingConfigService
	users                  *service.UserService
}

// NewKnowledgeBaseController 创建知识库控制器实例
func NewKnowledgeBaseController(knowledgeBaseService *service.KnowledgeBaseService, embeddingConfigService *service.EmbeddingConfigService, users *service.UserService) *KnowledgeBaseController {
	return &KnowledgeBaseController{
		knowledgeBaseService:   knowledgeBaseService,
		embeddingConfigService: embeddingConfigService,
		users:                  users,
	}
}

// checkKBAccess 校验当前用户是否允许使用知识库（请求头须带 X-User-Id；未带则放行以兼容旧前端）
func (c *KnowledgeBaseController) checkKBAccess(ctx *gin.Context) bool {
	userID := getUserIDFromHeader(ctx)
	if userID == 0 {
		return true
	}
	if err := c.embeddingConfigService.CheckKnowledgeBaseAccess(userID); err != nil {
		ctx.JSON(http.StatusForbidden, gin.H{"error": err.Error()})
		return false
	}
	return true
}

// ListKnowledgeBases 获取知识库列表
func (c *KnowledgeBaseController) ListKnowledgeBases(ctx *gin.Context) {
	if !requirePermission(ctx, c.users, string(service.PermKnowledge)) {
		return
	}
	if !c.checkKBAccess(ctx) {
		return
	}
	kbs, err := c.knowledgeBaseService.ListKnowledgeBases()
	if err != nil {
		log.Printf("获取知识库列表失败: %v", err)
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": "获取知识库列表失败"})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"knowledge_bases": kbs,
	})
}

// GetKnowledgeBase 获取知识库详情
func (c *KnowledgeBaseController) GetKnowledgeBase(ctx *gin.Context) {
	if !requirePermission(ctx, c.users, string(service.PermKnowledge)) {
		return
	}
	if !c.checkKBAccess(ctx) {
		return
	}
	idStr := ctx.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil || id == 0 {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": "知识库 ID 不合法"})
		return
	}

	kb, err := c.knowledgeBaseService.GetKnowledgeBase(uint(id))
	if err != nil {
		log.Printf("获取知识库详情失败: %v", err)
		ctx.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
		return
	}

	ctx.JSON(http.StatusOK, kb)
}

// CreateKnowledgeBase 创建知识库
func (c *KnowledgeBaseController) CreateKnowledgeBase(ctx *gin.Context) {
	if !requirePermission(ctx, c.users, string(service.PermKnowledge)) {
		return
	}
	if !c.checkKBAccess(ctx) {
		return
	}
	var req struct {
		Name        string `json:"name" binding:"required"`
		Description string `json:"description"`
	}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	kb, err := c.knowledgeBaseService.CreateKnowledgeBase(service.CreateKnowledgeBaseInput{
		Name:        req.Name,
		Description: req.Description,
	})
	if err != nil {
		log.Printf("创建知识库失败: %v", err)
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	ctx.JSON(http.StatusOK, kb)
}

// UpdateKnowledgeBase 更新知识库
func (c *KnowledgeBaseController) UpdateKnowledgeBase(ctx *gin.Context) {
	if !requirePermission(ctx, c.users, string(service.PermKnowledge)) {
		return
	}
	if !c.checkKBAccess(ctx) {
		return
	}
	idStr := ctx.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil || id == 0 {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": "知识库 ID 不合法"})
		return
	}

	var req struct {
		Name        *string `json:"name"`
		Description *string `json:"description"`
		RAGEnabled  *bool   `json:"rag_enabled"`
	}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	kb, err := c.knowledgeBaseService.UpdateKnowledgeBase(uint(id), service.UpdateKnowledgeBaseInput{
		Name:        req.Name,
		Description: req.Description,
		RAGEnabled:  req.RAGEnabled,
	})
	if err != nil {
		log.Printf("更新知识库失败: %v", err)
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	ctx.JSON(http.StatusOK, kb)
}

// DeleteKnowledgeBase 删除知识库
func (c *KnowledgeBaseController) DeleteKnowledgeBase(ctx *gin.Context) {
	if !requirePermission(ctx, c.users, string(service.PermKnowledge)) {
		return
	}
	if !c.checkKBAccess(ctx) {
		return
	}
	idStr := ctx.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil || id == 0 {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": "知识库 ID 不合法"})
		return
	}

	if err := c.knowledgeBaseService.DeleteKnowledgeBase(uint(id)); err != nil {
		log.Printf("删除知识库失败: %v", err)
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{"message": "删除成功"})
}

// UpdateKnowledgeBaseRAGEnabled 仅更新知识库「参与 RAG」开关。
func (c *KnowledgeBaseController) UpdateKnowledgeBaseRAGEnabled(ctx *gin.Context) {
	if !requirePermission(ctx, c.users, string(service.PermKnowledge)) {
		return
	}
	if !c.checkKBAccess(ctx) {
		return
	}
	idStr := ctx.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil || id == 0 {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": "知识库 ID 不合法"})
		return
	}
	var req struct {
		RAGEnabled bool `json:"rag_enabled"`
	}
	if err := ctx.ShouldBindJSON(&req); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	kb, err := c.knowledgeBaseService.UpdateKnowledgeBase(uint(id), service.UpdateKnowledgeBaseInput{
		RAGEnabled: &req.RAGEnabled,
	})
	if err != nil {
		log.Printf("更新知识库 RAG 开关失败: %v", err)
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	ctx.JSON(http.StatusOK, kb)
}

// ListDocumentsByKnowledgeBase 获取知识库的文档列表
func (c *KnowledgeBaseController) ListDocumentsByKnowledgeBase(ctx *gin.Context) {
	if !c.checkKBAccess(ctx) {
		return
	}
	// 这个功能由 DocumentController 实现，这里可以重定向或调用
	ctx.JSON(http.StatusOK, gin.H{"message": "请使用 /documents?knowledge_base_id=:id"})
}
