package controllers

import (
	"time"

	"net/url"

	"github.com/gofiber/fiber/v2" //nolint:goimports
	"github.com/gofiber/fiber/v2/middleware/session"
	"github.com/sujit-baniya/fiber-boilerplate/app"
	"github.com/sujit-baniya/fiber-boilerplate/pkg/auth"
	"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
)

func LoginGet(c *fiber.Ctx) error {
	data := getFlashData(c)
	data["title"] = "Login | "
	if errMsg := c.Query("error"); errMsg != "" {
		data["error"] = errMsg
	}
	return c.Render("auth/login", data, "layouts/landing")
}

func LoginPost(c *fiber.Ctx) error {
	// Verificar si falta la contraseña
	if c.Locals("missing_password") == true {
		return c.Redirect("/update-credentials") // Redirige directamente
	}

	// Obtener el usuario desde el contexto
	user := c.Locals("user").(*models.Users)

	// Intentar realizar el login
	_, err := auth.Login(c, user.ID, app.Http.Token.AppJwtSecret)
	if err != nil {
		// Si hay error, podrías mandar de nuevo al login con mensaje
		return c.Redirect("/login?error=" + url.QueryEscape(err.Error()))
	}

	// Redirige según la página principal del rol, o por defecto a /app/servidor
	homeUrl := "/app/servidor"
	if user.Role.HomeUrl != "" {
		homeUrl = user.Role.HomeUrl
	}
	return c.Redirect(homeUrl)
}

var store = session.New()

func LogoutPost(c *fiber.Ctx) error {
	// Verifica si el usuario está autenticado
	if auth.IsLoggedIn(c) {
		// Cierra la sesión en el backend
		err := auth.Logout(c)
		if err != nil {
			return fiber.NewError(fiber.StatusInternalServerError, "Logout failed")
		}
	}

	// Elimina la sesión actual
	sess, err := store.Get(c)
	if err == nil {
		_ = sess.Destroy()
	}

	// Limpia ambas cookies de sesión
	c.ClearCookie("session_id")
	c.ClearCookie("Verify-Rest-Token")

	// Limpia la cookie CSRF
	c.Cookie(&fiber.Cookie{
		Name:     "Verify-Rest-Token", // Nombre de la cookie CSRF, ajusta si usas un nombre diferente
		Value:    "",
		Expires:  time.Now().Add(-1 * time.Hour), // Establece la cookie para que expire en el pasado
		HTTPOnly: true,
		Secure:   true,
		SameSite: "Strict",
	})
	// Limpia la cookie CSRF
	c.Cookie(&fiber.Cookie{
		Name:     "session_id", // Nombre de la cookie CSRF, ajusta si usas un nombre diferente
		Value:    "",
		Expires:  time.Now().Add(-1 * time.Hour), // Establece la cookie para que expire en el pasado
		HTTPOnly: true,
		Secure:   true,
		SameSite: "Strict",
	})

	// Ajusta encabezados de caché para evitar almacenamientos no deseados en caché
	c.Set("X-DNS-Prefetch-Control", "off")
	c.Set("Pragma", "no-cache")
	c.Set("Expires", "Fri, 01 Jan 1990 00:00:00 GMT")
	c.Set("Cache-Control", "no-cache, must-revalidate, no-store, max-age=0, private")

	// Redirige al usuario a la página de inicio de sesión
	return c.Redirect("/login")
}

func getFlashData(c *fiber.Ctx) fiber.Map {
	data := app.Http.Flash.Get(c)
	if data == nil {
		data = fiber.Map{}
	}
	return data
}
