package handlers

import (
	"context"
	"net/http"

	"github.com/gin-gonic/gin"

	"customer-support-system/internal/ai"
	"customer-support-system/internal/models"
	"customer-support-system/pkg/logger"
)

// AIHandler handles AI-related HTTP requests
type AIHandler struct {
	aiService *ai.AIService
}

// NewAIHandler creates a new AI handler
func NewAIHandler() *AIHandler {
	return &AIHandler{
		aiService: ai.NewAIService(),
	}
}

// QueryAI handles querying the AI service
func (h *AIHandler) QueryAI(c *gin.Context) {
	// Check if user is authenticated
	_, exists := c.Get("userID")
	if !exists {
		logger.Error("Failed to get user ID from context")
		c.JSON(http.StatusUnauthorized, gin.H{
			"success": false,
			"message": "Unauthorized",
		})
		return
	}

	var req struct {
		Prompt              string           `json:"prompt" binding:"required"`
		ConversationHistory []models.Message `json:"conversationHistory"`
		Complexity          int              `json:"complexity"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		logger.WithError(err).Error("Failed to parse query AI request")
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"message": "Invalid request body",
		})
		return
	}

	// If complexity is not provided, analyze it
	if req.Complexity == 0 {
		req.Complexity = h.aiService.AnalyzeComplexity(req.Prompt)
	}

	// Query AI
	ctx := context.Background()
	response, err := h.aiService.Query(ctx, req.Prompt, req.ConversationHistory, req.Complexity)
	if err != nil {
		logger.WithError(err).Error("Failed to query AI")
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": "Failed to query AI",
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "AI query successful",
		"data": gin.H{
			"response":   response,
			"complexity": req.Complexity,
		},
	})
}

// AnalyzeComplexity handles analyzing the complexity of a prompt
func (h *AIHandler) AnalyzeComplexity(c *gin.Context) {
	var req struct {
		Prompt string `json:"prompt" binding:"required"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		logger.WithError(err).Error("Failed to parse analyze complexity request")
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"message": "Invalid request body",
		})
		return
	}

	// Analyze complexity
	complexity := h.aiService.AnalyzeComplexity(req.Prompt)

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "Complexity analysis successful",
		"data": gin.H{
			"complexity": complexity,
		},
	})
}

// GetAvailableModels handles getting available AI models
func (h *AIHandler) GetAvailableModels(c *gin.Context) {
	// Get available models
	models := h.aiService.GetAvailableModels()

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"data": gin.H{
			"models": models,
		},
	})
}

// QueryOpenAI handles querying the OpenAI API
func (h *AIHandler) QueryOpenAI(c *gin.Context) {
	// Check if user is authenticated
	_, exists := c.Get("userID")
	if !exists {
		logger.Error("Failed to get user ID from context")
		c.JSON(http.StatusUnauthorized, gin.H{
			"success": false,
			"message": "Unauthorized",
		})
		return
	}

	var req struct {
		Prompt              string           `json:"prompt" binding:"required"`
		ConversationHistory []models.Message `json:"conversationHistory"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		logger.WithError(err).Error("Failed to parse query OpenAI request")
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"message": "Invalid request body",
		})
		return
	}

	// Query OpenAI
	ctx := context.Background()
	response, err := h.aiService.QueryOpenAI(ctx, req.Prompt, req.ConversationHistory)
	if err != nil {
		logger.WithError(err).Error("Failed to query OpenAI")
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": "Failed to query OpenAI",
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "OpenAI query successful",
		"data": gin.H{
			"response": response,
		},
	})
}

// QueryOllama handles querying the Ollama API
func (h *AIHandler) QueryOllama(c *gin.Context) {
	// Check if user is authenticated
	_, exists := c.Get("userID")
	if !exists {
		logger.Error("Failed to get user ID from context")
		c.JSON(http.StatusUnauthorized, gin.H{
			"success": false,
			"message": "Unauthorized",
		})
		return
	}

	var req struct {
		Prompt              string           `json:"prompt" binding:"required"`
		ConversationHistory []models.Message `json:"conversationHistory"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		logger.WithError(err).Error("Failed to parse query Ollama request")
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"message": "Invalid request body",
		})
		return
	}

	// Query Ollama
	ctx := context.Background()
	response, err := h.aiService.QueryOllama(ctx, req.Prompt, req.ConversationHistory)
	if err != nil {
		logger.WithError(err).Error("Failed to query Ollama")
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": "Failed to query Ollama",
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "Ollama query successful",
		"data": gin.H{
			"response": response,
		},
	})
}
