package handlers

import (
	"log"
	"sno/internal/middleware"
	"sno/internal/models"
	"sno/internal/service"

	"github.com/gofiber/fiber/v2"
)

// QRHandler handles HTTP requests for QR code operations.
type QRHandler struct {
	qrService service.QRService
}

// NewQRHandler creates a new instance of a QR handler.
func NewQRHandler(s service.QRService) *QRHandler {
	return &QRHandler{qrService: s}
}

// Validate handles the request to validate a QR code payload.
// @Summary Validate QR code payload
// @Description Validates a QR code payload and processes the associated action
// @Tags qr
// @Accept json
// @Produce json
// @Param request body models.QRValidateRequest true "QR validation request"
// @Success 200 {object} object{success=bool,message=string,data=object}
// @Failure 400 {object} object{success=bool,message=string}
// @Failure 401 {object} object{success=bool,message=string}
// @Router /api/qr/validate [post]
// @Security ApiKeyAuth
func (h *QRHandler) Validate(c *fiber.Ctx) error {
	var req models.QRValidateRequest
	if err := c.BodyParser(&req); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(Response{
			Success: false,
			Message: "Cannot parse JSON",
		})
	}

	if req.Payload == "" {
		return c.Status(fiber.StatusBadRequest).JSON(Response{
			Success: false,
			Message: "Payload cannot be empty",
		})
	}

	// Get user data from auth middleware
	userData := middleware.GetTelegramUser(c)
	if userData == nil {
		return c.Status(fiber.StatusUnauthorized).JSON(Response{
			Success: false,
			Message: "User not authenticated",
		})
	}

	resp, err := h.qrService.ValidatePayload(c.Context(), userData.ID, req.Payload)
	if err != nil {
		log.Printf("ERROR: Failed to validate QR payload: %v", err)
		return c.Status(fiber.StatusBadRequest).JSON(Response{ // Using 400 for invalid payloads
			Success: false,
			Message: err.Error(),
		})
	}

	return c.Status(fiber.StatusOK).JSON(Response{
		Success: true,
		Message: "QR payload validated successfully",
		Data:    resp,
	})
}

// GenerateQRCodes handles the request to generate unique QR codes
// @Summary Generate QR codes
// @Description Generates unique QR codes for rewards, quizzes, or shop items (admin/operator only)
// @Tags qr
// @Accept json
// @Produce json
// @Param request body models.GenerateQRCodesRequest true "QR codes generation request"
// @Success 200 {object} object{success=bool,message=string,data=models.GenerateQRCodesResponse}
// @Failure 400 {object} object{success=bool,message=string}
// @Failure 500 {object} object{success=bool,message=string}
// @Router /api/admin/qrcodes [post]
// @Security ApiKeyAuth
func (h *QRHandler) GenerateQRCodes(c *fiber.Ctx) error {
	var req models.GenerateQRCodesRequest
	if err := c.BodyParser(&req); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(Response{
			Success: false,
			Message: "Cannot parse JSON",
		})
	}

	// Validate request
	if req.Type == "" {
		return c.Status(fiber.StatusBadRequest).JSON(Response{
			Success: false,
			Message: "Type cannot be empty",
		})
	}

	if req.Value == "" {
		return c.Status(fiber.StatusBadRequest).JSON(Response{
			Success: false,
			Message: "Value cannot be empty",
		})
	}

	if req.Count <= 0 || req.Count > 100 {
		return c.Status(fiber.StatusBadRequest).JSON(Response{
			Success: false,
			Message: "Count must be between 1 and 100",
		})
	}

	// Validate type
	validTypes := map[string]bool{
		"reward": true,
		"quiz":   true,
		"shop":   true,
	}
	if !validTypes[req.Type] {
		return c.Status(fiber.StatusBadRequest).JSON(Response{
			Success: false,
			Message: "Invalid type. Must be 'reward', 'quiz', or 'shop'",
		})
	}

	tokens := make([]string, 0, req.Count)
	for i := 0; i < req.Count; i++ {
		token, err := h.qrService.GenerateUniqueToken(c.Context(), req.Type, req.Value)
		if err != nil {
			log.Printf("ERROR: Failed to generate QR token: %v", err)
			return c.Status(fiber.StatusInternalServerError).JSON(Response{
				Success: false,
				Message: "Failed to generate QR codes",
			})
		}
		tokens = append(tokens, token)
	}

	return c.Status(fiber.StatusOK).JSON(Response{
		Success: true,
		Message: "QR codes generated successfully",
		Data: models.GenerateQRCodesResponse{
			Tokens: tokens,
		},
	})
}
