package handlers

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

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

// AuthHandler handles authentication-related requests
type AuthHandler struct {
	botToken     string
	userService  service.UserService
	adminService service.AdminService
}

// NewAuthHandler creates a new auth handler
func NewAuthHandler(botToken string, userService service.UserService, adminService service.AdminService) *AuthHandler {
	return &AuthHandler{
		botToken:     botToken,
		userService:  userService,
		adminService: adminService,
	}
}

// Validate validates Telegram WebApp init data and creates/updates user
// @Summary Validate Telegram WebApp init data
// @Description Validates Telegram WebApp init data, creates/updates user, and returns user information
// @Tags auth
// @Accept json
// @Produce json
// @Param request body object{initData=string} true "Init data 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/auth/validate [post]
func (h *AuthHandler) Validate(c *fiber.Ctx) error {
	// Get initData from request body
	var request struct {
		InitData string `json:"initData"`
	}

	if err := c.BodyParser(&request); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(Response{
			Success: false,
			Message: "Cannot parse JSON",
		})
	}

	if request.InitData == "" {
		return c.Status(fiber.StatusBadRequest).JSON(Response{
			Success: false,
			Message: "Init data is required",
		})
	}

	// Validate the init data
	userData, err := middleware.ValidateTelegramInitData(request.InitData, h.botToken)
	if err != nil {
		return c.Status(fiber.StatusUnauthorized).JSON(Response{
			Success: false,
			Message: err.Error(),
		})
	}


	// Create or update user in database
	dbUser, err := h.userService.GetOrCreateUser(
		c.Context(),
		userData.ID,
		userData.FirstName,
		userData.LastName,
		userData.Username,
		userData.PhotoURL,
	)
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(Response{
			Success: false,
			Message: "Failed to create or update user",
		})
	}


	return c.Status(fiber.StatusOK).JSON(Response{
		Success: true,
		Message: "Authentication successful",
		Data:    dbUser,
	})
}

// GetMe returns current authenticated user info from database
// @Summary Get current authenticated user
// @Description Returns information about the currently authenticated user from database
// @Tags auth
// @Accept json
// @Produce json
// @Success 200 {object} object{success=bool,message=string,data=object}
// @Failure 401 {object} object{success=bool,message=string}
// @Failure 404 {object} object{success=bool,message=string}
// @Router /api/auth/me [get]
// @Security ApiKeyAuth
func (h *AuthHandler) GetMe(c *fiber.Ctx) error {
	userData := middleware.GetTelegramUser(c)
	if userData == nil {
		return c.Status(fiber.StatusUnauthorized).JSON(Response{
			Success: false,
			Message: "User not authenticated",
		})
	}

	// Get user from database
	dbUser, err := h.userService.GetUserProfile(c.Context(), userData.ID)
	if err != nil {
		return c.Status(fiber.StatusNotFound).JSON(Response{
			Success: false,
			Message: "User not found in database",
		})
	}

	return c.Status(fiber.StatusOK).JSON(Response{
		Success: true,
		Message: "User data retrieved successfully",
		Data:    dbUser,
	})
}

// GetAdminRole returns the admin role for the current user
// @Summary Get admin role for current user
// @Description Returns the admin role (admin, operator, or user) for the currently authenticated user
// @Tags auth
// @Accept json
// @Produce json
// @Success 200 {object} object{success=bool,message=string,data=object}
// @Failure 401 {object} object{success=bool,message=string}
// @Router /api/auth/admin-role [get]
// @Security ApiKeyAuth
func (h *AuthHandler) GetAdminRole(c *fiber.Ctx) error {
	userData := middleware.GetTelegramUser(c)
	if userData == nil {
		return c.Status(fiber.StatusUnauthorized).JSON(Response{
			Success: false,
			Message: "User not authenticated",
		})
	}

	// Check user role from admin service
	role, err := h.adminService.GetUserRole(c.Context(), userData.ID)
	if err != nil {
		// If user not found in admins table, they are a regular user
		role = "user"
	}

	return c.Status(fiber.StatusOK).JSON(Response{
		Success: true,
		Message: "Admin role retrieved successfully",
		Data: map[string]string{
			"role": string(role),
		},
	})
}