package controller

import (
	"net/http"
	"strconv"

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

// ConversationController 负责处理会话相关的 HTTP 请求。
type ConversationController struct {
	conversationService *service.ConversationService
	aiConfigService     *service.AIConfigService // 用于获取开放的模型列表
	users               *service.UserService
}

// NewConversationController 创建 ConversationController 实例。
func NewConversationController(
	conversationService *service.ConversationService,
	aiConfigService *service.AIConfigService,
	users *service.UserService,
) *ConversationController {
	return &ConversationController{
		conversationService: conversationService,
		aiConfigService:     aiConfigService,
		users:               users,
	}
}

type initConversationRequest struct {
	VisitorID  uint   `json:"visitor_id"`
	Website    string `json:"website"`
	Referrer   string `json:"referrer"`
	Browser    string `json:"browser"`
	OS         string `json:"os"`
	Language   string `json:"language"`
	ChatMode   string `json:"chat_mode"`   // 对话模式：human（人工客服）、ai（AI客服）
	AIConfigID *uint  `json:"ai_config_id"` // AI 配置 ID（访客选择的模型配置，AI 模式时必需）
}

type updateContactRequest struct {
	Email *string `json:"email"`
	Phone *string `json:"phone"`
	Notes *string `json:"notes"`
}

// InitConversation 为访客初始化或恢复会话。
func (cc *ConversationController) InitConversation(c *gin.Context) {
	var req initConversationRequest
	if err := c.ShouldBindJSON(&req); err != nil || req.VisitorID == 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数错误"})
		return
	}

	browser := req.Browser
	os := req.OS
	if browser == "" || os == "" {
		parsedBrowser, parsedOS := utils.ParseUserAgent(c.GetHeader("User-Agent"))
		if browser == "" {
			browser = parsedBrowser
		}
		if os == "" {
			os = parsedOS
		}
	}

	result, err := cc.conversationService.InitConversation(service.InitConversationInput{
		VisitorID:  req.VisitorID,
		Website:    req.Website,
		Referrer:   req.Referrer,
		Browser:    browser,
		OS:         os,
		Language:   req.Language,
		IPAddress:  utils.GetClientIP(c),
		ChatMode:   req.ChatMode,
		AIConfigID: req.AIConfigID,
	})

	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"conversation_id": result.ConversationID,
		"status":          result.Status,
	})
}

// InitInternalConversation 为当前客服创建一条新的内部对话（知识库测试）。需要 query user_id。
func (cc *ConversationController) InitInternalConversation(c *gin.Context) {
	if !requirePermission(c, cc.users, string(service.PermKBTest)) {
		return
	}
	userIDStr := c.Query("user_id")
	if userIDStr == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "需要 user_id"})
		return
	}
	userID, err := strconv.ParseUint(userIDStr, 10, 32)
	if err != nil || userID == 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "user_id 不合法"})
		return
	}
	result, err := cc.conversationService.InitInternalConversation(uint(userID))
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"conversation_id": result.ConversationID,
		"status":          result.Status,
	})
}

// GetPublicAIModels 获取所有开放的模型配置（供访客选择）。
func (cc *ConversationController) GetPublicAIModels(c *gin.Context) {
	modelType := c.DefaultQuery("model_type", "text")
	models, err := cc.aiConfigService.GetPublicModels(modelType)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"models": models})
}

// UpdateContactInfo 用于更新访客的联系信息。
func (cc *ConversationController) UpdateContactInfo(c *gin.Context) {
	id, err := parseUintParam(c, "id")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "会话ID不合法"})
		return
	}

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

	if req.Email == nil && req.Phone == nil && req.Notes == nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "至少提供一个需要更新的字段"})
		return
	}

	result, err := cc.conversationService.UpdateConversationContact(service.UpdateConversationContactInput{
		ConversationID: uint(id),
		Email:          req.Email,
		Phone:          req.Phone,
		Notes:          req.Notes,
	})
	if err != nil {
		if err == service.ErrConversationNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "会话不存在"})
		} else {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "更新失败"})
		}
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"email": result.Email,
		"phone": result.Phone,
		"notes": result.Notes,
	})
}

// CloseConversation 客服关闭会话（进入历史/归档）。
// POST /conversations/:id/close
func (cc *ConversationController) CloseConversation(c *gin.Context) {
	if !requirePermission(c, cc.users, string(service.PermChat)) {
		return
	}
	id, err := parseUintParam(c, "id")
	if err != nil || id == 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "会话ID不合法"})
		return
	}
	userID := getUserIDFromHeader(c)
	if err := cc.conversationService.CloseConversation(uint(id), userID); err != nil {
		if err == service.ErrConversationNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "会话不存在"})
			return
		}
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"ok": true})
}

// ListConversations 返回当前活跃会话的列表。type=internal 时返回该客服的内部对话（知识库测试）。
func (cc *ConversationController) ListConversations(c *gin.Context) {
	var userID uint
	if userIDStr := c.Query("user_id"); userIDStr != "" {
		if parsed, err := strconv.ParseUint(userIDStr, 10, 32); err == nil {
			userID = uint(parsed)
		}
	}

	conversationType := c.DefaultQuery("type", "visitor")
	status := c.DefaultQuery("status", "open")
	var conversations []service.ConversationSummary
	var err error
	if conversationType == "internal" {
		if !requirePermission(c, cc.users, string(service.PermKBTest)) {
			return
		}
		if userID == 0 {
			c.JSON(http.StatusBadRequest, gin.H{"error": "内部对话列表需要 user_id"})
			return
		}
		conversations, err = cc.conversationService.ListInternalConversations(userID, status)
	} else {
		conversations, err = cc.conversationService.ListConversations(userID, status)
	}
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "查询对话列表失败"})
		return
	}

	items := make([]gin.H, 0, len(conversations))
	for _, conv := range conversations {
		item := gin.H{
			"id":                conv.ID,
			"conversation_type": conv.ConversationType,
			"visitor_id":        conv.VisitorID,
			"agent_id":          conv.AgentID,
			"status":            conv.Status,
			"chat_mode":         conv.ChatMode,
			"created_at":        formatTimeValue(conv.CreatedAt),
			"updated_at":        formatTimeValue(conv.UpdatedAt),
			"unread_count":      conv.UnreadCount,
			"has_participated":  conv.HasParticipated,
		}

		// 添加 last_seen_at 字段（用于判断在线状态）
		if lastSeen := formatTimePointer(conv.LastSeenAt); lastSeen != "" {
			item["last_seen_at"] = lastSeen
		}

		if conv.LastMessage != nil {
			item["last_message"] = gin.H{
				"id":              conv.LastMessage.ID,
				"content":         conv.LastMessage.Content,
				"sender_is_agent": conv.LastMessage.SenderIsAgent,
				"message_type":    conv.LastMessage.MessageType,
				"is_read":         conv.LastMessage.IsRead,
				"read_at":         formatTimePointer(conv.LastMessage.ReadAt),
				"created_at":      formatTimeValue(conv.LastMessage.CreatedAt),
			}
		}
		items = append(items, item)
	}

	c.JSON(http.StatusOK, items)
}

// GetConversationDetail 返回会话的详细信息。
func (cc *ConversationController) GetConversationDetail(c *gin.Context) {
	id, err := parseUintParam(c, "id")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "会话ID不合法"})
		return
	}

	// 从查询参数获取 user_id（可选，用于检查参与状态）
	var userID uint
	if userIDStr := c.Query("user_id"); userIDStr != "" {
		// 使用 strconv 解析查询参数（不是路径参数）
		if parsed, err := strconv.ParseUint(userIDStr, 10, 32); err == nil {
			userID = uint(parsed)
		}
	}

	detail, err := cc.conversationService.GetConversationDetail(uint(id), userID)
	if err != nil {
		if err == service.ErrConversationNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "会话不存在"})
		} else {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "查询失败"})
		}
		return
	}

	response := gin.H{
		"id":           detail.ID,
		"visitor_id":   detail.VisitorID,
		"agent_id":     detail.AgentID,
		"status":       detail.Status,
		"website":      detail.Website,
		"referrer":     detail.Referrer,
		"browser":      detail.Browser,
		"os":           detail.OS,
		"language":     detail.Language,
		"ip_address":   detail.IPAddress,
		"location":     detail.Location,
		"email":        detail.Email,
		"phone":        detail.Phone,
		"notes":        detail.Notes,
		"created_at":   formatTimeValue(detail.CreatedAt),
		"updated_at":   formatTimeValue(detail.UpdatedAt),
		"unread_count": detail.UnreadCount,
	}
	if lastSeen := formatTimePointer(detail.LastSeen); lastSeen != "" {
		response["last_seen_at"] = lastSeen
	}
	if detail.LastMessage != nil {
		response["last_message"] = gin.H{
			"id":              detail.LastMessage.ID,
			"content":         detail.LastMessage.Content,
			"sender_is_agent": detail.LastMessage.SenderIsAgent,
			"message_type":    detail.LastMessage.MessageType,
			"is_read":         detail.LastMessage.IsRead,
			"read_at":         formatTimePointer(detail.LastMessage.ReadAt),
			"created_at":      formatTimeValue(detail.LastMessage.CreatedAt),
		}
	}

	c.JSON(http.StatusOK, response)
}

// SearchConversations 根据关键字进行会话的模糊搜索。
func (cc *ConversationController) SearchConversations(c *gin.Context) {
	query := c.Query("q")
	if query == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "搜索关键词不能为空"})
		return
	}
	status := c.DefaultQuery("status", "open")

	// 从查询参数获取 user_id（可选，用于检查参与状态）
	var userID uint
	if userIDStr := c.Query("user_id"); userIDStr != "" {
		// 使用 strconv 解析查询参数（不是路径参数）
		if parsed, err := strconv.ParseUint(userIDStr, 10, 32); err == nil {
			userID = uint(parsed)
		}
	}

	conversations, err := cc.conversationService.SearchConversations(query, userID, status)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "搜索失败"})
		return
	}

	items := make([]gin.H, 0, len(conversations))
	for _, conv := range conversations {
		item := gin.H{
			"id":               conv.ID,
			"visitor_id":       conv.VisitorID,
			"agent_id":         conv.AgentID,
			"status":           conv.Status,
			"created_at":       formatTimeValue(conv.CreatedAt),
			"updated_at":       formatTimeValue(conv.UpdatedAt),
			"unread_count":     conv.UnreadCount,
			"has_participated": conv.HasParticipated, // 当前用户是否参与过该会话
		}

		// 添加 last_seen_at 字段（用于判断在线状态）
		if lastSeen := formatTimePointer(conv.LastSeenAt); lastSeen != "" {
			item["last_seen_at"] = lastSeen
		}

		if conv.LastMessage != nil {
			item["last_message"] = gin.H{
				"id":              conv.LastMessage.ID,
				"content":         conv.LastMessage.Content,
				"sender_is_agent": conv.LastMessage.SenderIsAgent,
				"message_type":    conv.LastMessage.MessageType,
				"is_read":         conv.LastMessage.IsRead,
				"read_at":         formatTimePointer(conv.LastMessage.ReadAt),
				"created_at":      formatTimeValue(conv.LastMessage.CreatedAt),
			}
		}
		items = append(items, item)
	}

	c.JSON(http.StatusOK, items)
}
