package plant

import (
	"fmt"
	"sundynix-go/global"
	"sundynix-go/model/commom/response"
	"sundynix-go/utils/auth"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

type AiChatApi struct{}

// ChatStreamPlant 接收用户输入，基于植物百科 RAG 产生流式 SSE 回答
// @Summary 植物助手聊天（SSE 流式输出）
// @Tags Plant-AiChat
// @Param query query string true "用户提问内容"
// @Produce text/event-stream
// @Router /plant/chat/stream [get]
func (a *AiChatApi) ChatStreamPlant(c *gin.Context) {
	query := c.Query("query")
	if query == "" {
		response.FailWithMsg("参数 query 不能为空", c)
		return
	}

	userId := auth.GetUserId(c)

	// ── 每日用量检查 ──
	cfg, cfgErr := sysAiConfigService.GetActiveAiConfig()
	if cfgErr == nil && cfg.DailyQueryLimit > 0 {
		todayCount, _ := chatHistoryService.GetTodayCount(userId)
		if todayCount >= int64(cfg.DailyQueryLimit) {
			response.FailWithMsg(fmt.Sprintf("今日问答次数已达上限（%d次），明天再来吧", cfg.DailyQueryLimit), c)
			return
		}
	}

	// SSE Headers
	w := c.Writer
	header := w.Header()
	header.Set("Content-Type", "text/event-stream")
	header.Set("Cache-Control", "no-cache")
	header.Set("Connection", "keep-alive")
	header.Set("Transfer-Encoding", "chunked")
	w.WriteHeader(200)

	var fullAnswer string
	err := aiRagService.PlantChatStreamRAG(c.Request.Context(), query, func(chunk string) error {
		fullAnswer += chunk
		_, writeErr := w.WriteString("data: " + chunk + "\n\n")
		w.Flush()
		return writeErr
	})

	if err != nil {
		global.Logger.Error("PlantChatStreamRAG error", zap.Error(err))
		_, _ = w.WriteString("data: [ERROR]" + err.Error() + "\n\n")
		w.Flush()
	} else {
		_, _ = w.WriteString("data: [DONE]\n\n")
		w.Flush()
	}

	// 异步保存问答历史
	if fullAnswer != "" {
		go func() {
			if saveErr := chatHistoryService.SaveHistory(userId, query, fullAnswer); saveErr != nil {
				global.Logger.Error("Save chat history failed", zap.Error(saveErr))
			}
		}()
	}
}

// SyncWikiToQdrant 手动触发全量植物百科同步到 Qdrant
// @Summary 同步植物百科数据到 Qdrant 向量库
// @Tags System-SysAiConfig
// @Produce json
// @Success 200 {object} response.Response
// @Router /plant/chat/sync [post]
func (a *AiChatApi) SyncWikiToQdrant(c *gin.Context) {
	if err := aiRagService.SyncWikiToQdrant(); err != nil {
		global.Logger.Error("SyncWikiToQdrant error", zap.Error(err))
		response.FailWithMsg("同步失败: "+err.Error(), c)
		return
	}
	response.OkWithMsg("同步成功", c)
}

// GetChatHistory 获取AI问答历史列表
// @Tags Plant-AiChat
// @Param current query int false "页码"
// @Param pageSize query int false "每页条数"
// @Router /plant/chat/history [get]
func (a *AiChatApi) GetChatHistory(c *gin.Context) {
	userId := auth.GetUserId(c)
	current := 1
	pageSize := 20
	if v, ok := c.GetQuery("current"); ok {
		if n := parseInt(v); n > 0 {
			current = n
		}
	}
	if v, ok := c.GetQuery("pageSize"); ok {
		if n := parseInt(v); n > 0 {
			pageSize = n
		}
	}
	list, total, err := chatHistoryService.GetHistoryList(userId, current, pageSize)
	if err != nil {
		response.FailWithMsg("查询失败", c)
		return
	}
	response.OkWithData(map[string]interface{}{
		"list":  list,
		"total": total,
	}, c)
}

// DeleteChatHistory 删除单条历史
// @Tags Plant-AiChat
// @Router /plant/chat/history/delete [post]
func (a *AiChatApi) DeleteChatHistory(c *gin.Context) {
	var req struct {
		Id string `json:"id"`
	}
	if err := c.ShouldBindJSON(&req); err != nil || req.Id == "" {
		response.FailWithMsg("参数错误", c)
		return
	}
	userId := auth.GetUserId(c)
	if err := chatHistoryService.DeleteHistory(userId, req.Id); err != nil {
		response.FailWithMsg("删除失败", c)
		return
	}
	response.OkWithMsg("删除成功", c)
}

// ClearChatHistory 清空所有历史
// @Tags Plant-AiChat
// @Router /plant/chat/history/clear [post]
func (a *AiChatApi) ClearChatHistory(c *gin.Context) {
	userId := auth.GetUserId(c)
	if err := chatHistoryService.ClearHistory(userId); err != nil {
		response.FailWithMsg("清空失败", c)
		return
	}
	response.OkWithMsg("已清空", c)
}

// GetChatQuota 获取当前用户今日剩余问答额度
// @Tags Plant-AiChat
// @Router /plant/chat/quota [get]
func (a *AiChatApi) GetChatQuota(c *gin.Context) {
	userId := auth.GetUserId(c)
	todayCount, _ := chatHistoryService.GetTodayCount(userId)

	limit := 0 // 0 = unlimited
	cfg, err := sysAiConfigService.GetActiveAiConfig()
	if err == nil && cfg.DailyQueryLimit > 0 {
		limit = cfg.DailyQueryLimit
	}

	remaining := -1 // -1 means unlimited
	if limit > 0 {
		remaining = limit - int(todayCount)
		if remaining < 0 {
			remaining = 0
		}
	}

	response.OkWithData(map[string]interface{}{
		"used":      todayCount,
		"limit":     limit,
		"remaining": remaining,
	}, c)
}

func parseInt(s string) int {
	n := 0
	for _, c := range s {
		if c >= '0' && c <= '9' {
			n = n*10 + int(c-'0')
		}
	}
	return n
}
