package handler

import (
	"bytes"
	"encoding/json"
	"fmt"
	"html"
	"io"
	"git.yeij.top/AskaEth/Cyrene/pkg/logger"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"

	"git.yeij.top/AskaEth/Cyrene/gateway/internal/middleware"
)

// MemoryHandler 记忆查询处理器 — 代理到 Memory-Service
type MemoryHandler struct {
	memoryServiceURL string
	client           *http.Client
}

// NewMemoryHandler 创建记忆处理器
func NewMemoryHandler(memoryServiceURL string) *MemoryHandler {
	return &MemoryHandler{
		memoryServiceURL: memoryServiceURL,
		client: &http.Client{
			Timeout: 15 * time.Second,
		},
	}
}

// Query 搜索用户记忆 — 代理 POST /api/v1/memories/query
// 管理员可通过 user_id 查询参数查询任意用户的记忆
func (h *MemoryHandler) Query(c *gin.Context) {
	authUserID := middleware.GetUserID(c)
	userID := c.Query("user_id")

	// 非管理员只能查询自己的记忆；管理员可通过查询参数指定目标用户
	if authUserID != "admin" || userID == "" {
		userID = authUserID
	}

	query := c.Query("q")
	if query == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "查询参数q不能为空"})
		return
	}

	// 使用 memory-service 的 POST /api/v1/memories/query 端点
	reqBody, _ := json.Marshal(map[string]interface{}{
		"user_id":    userID,
		"query_text": query,
		"limit":      10,
	})

	url := fmt.Sprintf("%s/api/v1/memories/query", h.memoryServiceURL)
	httpReq, err := http.NewRequest("POST", url, bytes.NewReader(reqBody))
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "构建请求失败"})
		return
	}
	httpReq.Header.Set("Content-Type", "application/json")

	resp, err := h.client.Do(httpReq)
	if err != nil {
		logger.Printf("[memory] Memory-Service 不可达 (Query): %v", err)
		c.JSON(http.StatusBadGateway, gin.H{
			"error":     fmt.Sprintf("Memory-Service 不可达: %v", err),
			"errorType": "memory_service_unreachable",
			"hint":      "Memory-Service 服务未启动或不可达，请先在「服务管理」面板中启动 Memory-Service",
		})
		return
	}
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)

	var result interface{}
	json.Unmarshal(body, &result)
	c.JSON(resp.StatusCode, result)
}

// List 列出用户所有记忆 — 代理 GET /api/v1/memories?user_id=...
// 管理员可通过 user_id 查询参数查询任意用户的记忆
func (h *MemoryHandler) List(c *gin.Context) {
	authUserID := middleware.GetUserID(c)
	userID := c.Query("user_id")

	// 非管理员只能查询自己的记忆；管理员可通过查询参数指定目标用户
	if authUserID != "admin" || userID == "" {
		userID = authUserID
	}

	limit := c.Query("limit")
	offset := c.Query("offset")

	url := fmt.Sprintf("%s/api/v1/memories?user_id=%s", h.memoryServiceURL, userID)
	if limit != "" {
		url += "&limit=" + limit
	}
	if offset != "" {
		url += "&offset=" + offset
	}

	resp, err := h.client.Get(url)
	if err != nil {
		logger.Printf("[memory] Memory-Service 不可达 (List): %v", err)
		c.JSON(http.StatusBadGateway, gin.H{
			"error":     fmt.Sprintf("Memory-Service 不可达: %v", err),
			"errorType": "memory_service_unreachable",
			"hint":      "Memory-Service 服务未启动或不可达，请先在「服务管理」面板中启动 Memory-Service",
		})
		return
	}
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)

	var result interface{}
	json.Unmarshal(body, &result)
	c.JSON(resp.StatusCode, result)
}

// Add 手动添加记忆 — 代理 POST /api/v1/memories
// 管理员可通过请求体中的 user_id 字段为任意用户添加记忆
func (h *MemoryHandler) Add(c *gin.Context) {
	authUserID := middleware.GetUserID(c)

	var req struct {
		UserID   string `json:"user_id"`
		Content  string `json:"content" binding:"required"`
		Category string `json:"category"`
		Priority int    `json:"priority"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数无效"})
		return
	}

	if req.Category == "" {
		req.Category = "other"
	}
	if req.Priority <= 0 {
		req.Priority = 1
	}

	// 管理员可通过请求体指定目标用户，否则使用认证用户
	userID := authUserID
	if authUserID == "admin" && req.UserID != "" {
		userID = req.UserID
	}

	// 转发到 Memory-Service（对用户输入进行 HTML 转义防 XSS）
	memReq := map[string]interface{}{
		"user_id":  userID,
		"content":  html.EscapeString(req.Content),
		"category": html.EscapeString(req.Category),
		"priority": req.Priority,
	}
	reqBody, _ := json.Marshal(memReq)

	url := fmt.Sprintf("%s/api/v1/memories", h.memoryServiceURL)
	httpReq, err := http.NewRequest("POST", url, bytes.NewReader(reqBody))
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "构建请求失败"})
		return
	}
	httpReq.Header.Set("Content-Type", "application/json")

	resp, err := h.client.Do(httpReq)
	if err != nil {
		logger.Printf("[memory] Memory-Service 不可达 (Add): %v", err)
		c.JSON(http.StatusBadGateway, gin.H{
			"error":     fmt.Sprintf("Memory-Service 不可达: %v", err),
			"errorType": "memory_service_unreachable",
			"hint":      "Memory-Service 服务未启动或不可达，请先在「服务管理」面板中启动 Memory-Service",
		})
		return
	}
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)

	var result interface{}
	json.Unmarshal(body, &result)
	c.JSON(resp.StatusCode, result)
}

// Delete 删除单条记忆 — 代理 DELETE /api/v1/memories/:id
func (h *MemoryHandler) Delete(c *gin.Context) {
	memoryID := c.Query("id")
	if memoryID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "缺少 id 参数"})
		return
	}

	url := fmt.Sprintf("%s/api/v1/memories/%s", h.memoryServiceURL, memoryID)

	req, err := http.NewRequest("DELETE", url, nil)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "构建请求失败"})
		return
	}

	resp, err := h.client.Do(req)
	if err != nil {
		logger.Printf("[memory] Memory-Service 不可达 (Delete): %v", err)
		c.JSON(http.StatusBadGateway, gin.H{
			"error":     fmt.Sprintf("Memory-Service 不可达: %v", err),
			"errorType": "memory_service_unreachable",
			"hint":      "Memory-Service 服务未启动或不可达，请先在「服务管理」面板中启动 Memory-Service",
		})
		return
	}
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)

	var result interface{}
	json.Unmarshal(body, &result)
	c.JSON(resp.StatusCode, result)
}
