package middlewares

import (
	"net/url"
	"strings"

	"github.com/gofiber/fiber/v2"
	"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
)

// AuthUmindWidget resuelve el agente a partir de la site_key en la URL y
// valida que la petición venga de uno de los dominios permitidos del tenant
// dueño de ese agente (Origin, o Referer si el navegador no manda Origin).
// La site_key no es un secreto — cualquiera puede verla en el HTML público
// del sitio — la protección real es el chequeo de dominio, igual que una
// site key de reCAPTCHA/Analytics.
func AuthUmindWidget(c *fiber.Ctx) error {
	siteKey := c.Params("site_key")
	if siteKey == "" {
		return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": true, "message": "site_key requerida"})
	}
	agente, err := models.GetUmindAgenteBySiteKey(siteKey)
	if err != nil {
		return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": true, "message": "sitio no encontrado"})
	}
	tenant, err := models.GetUmindTenantByID(agente.TenantID)
	if err != nil || !tenant.Activo {
		return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": true, "message": "sitio no encontrado"})
	}

	origen := c.Get("Origin")
	if origen == "" {
		origen = c.Get("Referer")
	}
	host := hostDeOrigen(origen)
	if !tenant.DominioPermitido(host) {
		return c.Status(fiber.StatusForbidden).JSON(fiber.Map{"error": true, "message": "dominio no autorizado para este sitio"})
	}

	if origen != "" {
		c.Set("Access-Control-Allow-Origin", origen)
		c.Set("Vary", "Origin")
	}
	c.Locals("umind_agente", agente)
	c.Locals("umind_tenant", tenant)
	return c.Next()
}

// UmindWidgetCORS responde el preflight OPTIONS que el navegador manda antes
// del POST real (el widget corre en un dominio distinto al de la API).
func UmindWidgetCORS(c *fiber.Ctx) error {
	origen := c.Get("Origin")
	if origen != "" {
		c.Set("Access-Control-Allow-Origin", origen)
		c.Set("Vary", "Origin")
	}
	c.Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
	c.Set("Access-Control-Allow-Headers", "Content-Type")
	c.Set("Access-Control-Max-Age", "600")
	return c.SendStatus(fiber.StatusNoContent)
}

func hostDeOrigen(origenURL string) string {
	if origenURL == "" {
		return ""
	}
	u, err := url.Parse(origenURL)
	if err != nil {
		return ""
	}
	return strings.ToLower(u.Hostname())
}
