package handlers

import (
	"context"
	"net/http"
	"time"

	"github.com/breakpilot/consent-service/internal/middleware"
	"github.com/breakpilot/consent-service/internal/models"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
)

// ========================================
// PUBLIC ENDPOINTS - Cookie Consent
// ========================================

// GetCookieCategories returns all active cookie categories
func (h *Handler) GetCookieCategories(c *gin.Context) {
	language := c.DefaultQuery("language", "de")
	ctx := context.Background()

	rows, err := h.db.Pool.Query(ctx, `
		SELECT id, name, display_name_de, display_name_en, description_de, description_en,
		       is_mandatory, sort_order
		FROM cookie_categories
		WHERE is_active = true
		ORDER BY sort_order ASC
	`)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch categories"})
		return
	}
	defer rows.Close()

	var categories []map[string]interface{}
	for rows.Next() {
		var cat models.CookieCategory
		if err := rows.Scan(&cat.ID, &cat.Name, &cat.DisplayNameDE, &cat.DisplayNameEN,
			&cat.DescriptionDE, &cat.DescriptionEN, &cat.IsMandatory, &cat.SortOrder); err != nil {
			continue
		}

		// Return localized data
		displayName := cat.DisplayNameDE
		description := cat.DescriptionDE
		if language == "en" && cat.DisplayNameEN != nil {
			displayName = *cat.DisplayNameEN
			if cat.DescriptionEN != nil {
				description = cat.DescriptionEN
			}
		}

		categories = append(categories, map[string]interface{}{
			"id":           cat.ID,
			"name":         cat.Name,
			"display_name": displayName,
			"description":  description,
			"is_mandatory": cat.IsMandatory,
		})
	}

	c.JSON(http.StatusOK, gin.H{"categories": categories})
}

// SetCookieConsent sets cookie preferences for a user
func (h *Handler) SetCookieConsent(c *gin.Context) {
	var req models.CookieConsentRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
		return
	}

	userID, err := middleware.GetUserID(c)
	if err != nil || userID == uuid.Nil {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid user"})
		return
	}

	ctx := context.Background()
	ipAddress := middleware.GetClientIP(c)
	userAgent := middleware.GetUserAgent(c)

	// Process each category
	for _, cat := range req.Categories {
		categoryID, err := uuid.Parse(cat.CategoryID)
		if err != nil {
			continue
		}

		_, err = h.db.Pool.Exec(ctx, `
			INSERT INTO cookie_consents (user_id, category_id, consented)
			VALUES ($1, $2, $3)
			ON CONFLICT (user_id, category_id)
			DO UPDATE SET consented = $3, updated_at = NOW()
		`, userID, categoryID, cat.Consented)

		if err != nil {
			continue
		}
	}

	// Log to audit trail
	h.logAudit(ctx, &userID, "cookie_consent_updated", "cookie", nil, nil, ipAddress, userAgent)

	c.JSON(http.StatusOK, gin.H{"message": "Cookie preferences saved"})
}

// GetMyCookieConsent returns cookie preferences for the current user
func (h *Handler) GetMyCookieConsent(c *gin.Context) {
	userID, err := middleware.GetUserID(c)
	if err != nil || userID == uuid.Nil {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid user"})
		return
	}

	ctx := context.Background()

	rows, err := h.db.Pool.Query(ctx, `
		SELECT cc.category_id, cc.consented, cc.updated_at,
		       cat.name, cat.display_name_de, cat.is_mandatory
		FROM cookie_consents cc
		JOIN cookie_categories cat ON cc.category_id = cat.id
		WHERE cc.user_id = $1
	`, userID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch preferences"})
		return
	}
	defer rows.Close()

	var consents []map[string]interface{}
	for rows.Next() {
		var (
			categoryID   uuid.UUID
			consented    bool
			updatedAt    time.Time
			name         string
			displayName  string
			isMandatory  bool
		)

		if err := rows.Scan(&categoryID, &consented, &updatedAt, &name, &displayName, &isMandatory); err != nil {
			continue
		}

		consents = append(consents, map[string]interface{}{
			"category_id":  categoryID,
			"name":         name,
			"display_name": displayName,
			"consented":    consented,
			"is_mandatory": isMandatory,
			"updated_at":   updatedAt,
		})
	}

	c.JSON(http.StatusOK, gin.H{"cookie_consents": consents})
}
