package controllers

import (
	"github.com/gofiber/fiber/v2" //nolint:goimports
	"github.com/gookit/validate"
	"github.com/sujit-baniya/fiber-boilerplate/app"
	"github.com/sujit-baniya/fiber-boilerplate/pkg/auth"
	"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
	"github.com/sujit-baniya/fiber-boilerplate/pkg/services"
)

func OAuthToken(c *fiber.Ctx) error { //nolint:wsl
	var login models.Login
	if err := c.BodyParser(&login); err != nil {
		return c.Status(401).JSON(fiber.Map{
			"error":   true,
			"message": "Invalid Credentials",
		})
	}

	v := validate.Struct(login)
	if !v.Validate() {
		return c.Status(401).JSON(fiber.Map{
			"error":   true,
			"message": v.Errors.All(),
		})
	}
	user, err := login.CheckLogin() //nolint:wsl
	if err != nil {
		return c.Status(401).JSON(fiber.Map{
			"error":   true,
			"message": err.Error(),
		})
	}
	token, err := auth.Login(c, user.ID, app.Http.Token.ApiJwtSecret) //nolint:wsl
	if err != nil {
		return c.Status(401).JSON(fiber.Map{
			"error":   true,
			"message": err.Error(),
		})
	}
	return c.JSON(fiber.Map{
		"token":      token.Hash,
		"expires_in": token.Expire,
	})
}

func ApiLoginPost(c *fiber.Ctx) error { //nolint:wsl
	// Obtener el usuario del contexto
	user, ok := c.Locals("user").(*models.User)
	if !ok || user == nil {
		return c.JSON(fiber.Map{
			"success": false,
			"message": "Usuario no encontrado o no autenticado",
		})
	}

	// Generar el token JWT para el usuario
	token, err := auth.Login(c, user.ID, app.Http.Token.AppJwtSecret)
	if err != nil {
		return c.JSON(fiber.Map{
			"success": false,
			"message": "Error al generar el token: " + err.Error(),
		})
	}

	// Retornar respuesta con el usuario y el token
	return c.JSON(fiber.Map{
		"success": true,
		"message": "Inicio de sesión exitoso",
		"user":    user,
		"token":   token,
	})
}

func ApiRegisterPost(c *fiber.Ctx) error {
	register := c.Locals("register").(models.RegisterForm)
	user, err := register.Signup()
	if err != nil {
		return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": true, "message": "Error on register request", "data": err.Error()}) //nolint:errcheck

	}
	store := app.Http.Session.Get(c) // get/create new session
	store.Set("user_id", user.ID)    // save to storage
	_ = store.Save()

	go services.SendConfirmationEmail(user.Email, services.GetPublicURL(), user.NombreUsuario)
	return c.JSON(fiber.Map{
		"success": true,
		"message": "Registered successfully! Please confirm your email",
	})
}

func RefreshOauthToken(c *fiber.Ctx) error {
	return nil
}
