package middleware

import (
	"lune/talentscale/internal/pkg/ctxval"
	"lune/talentscale/pkg/response"

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

// TenantMiddleware ensures that the request is contextually bound to a company
// unless the user is a Global Admin (Super Admin).
func TenantMiddleware() fiber.Handler {
	return func(c *fiber.Ctx) error {
		// 1. Get Company ID from Auth context (JWT)
		authCompanyID := ctxval.GetCompanyID(c)
		headerCompanyIDStr := c.Get("x-company-id")

		// Debug Log (Safety: No token logging)
		// log.Printf("[TenantDebug] Incoming x-company-id: %s, Auth company_id: %s", headerCompanyIDStr, authCompanyID.String())

		// 2. Resolve final company context
		var companyID uuid.UUID

		if headerCompanyIDStr != "" {
			parsedID, err := uuid.Parse(headerCompanyIDStr)
			if err != nil {
				return response.BadRequest(c, "Invalid company context format")
			}
			companyID = parsedID
		} else {
			companyID = authCompanyID
		}

		// 3. Security Check: If user is NOT Super Admin, header MUST match JWT
		if !ctxval.IsGlobalRole(c) && authCompanyID != uuid.Nil {
			if companyID != authCompanyID {
				return response.Forbidden(c, "Tenant mismatch: cross-tenant access denied")
			}
		}

		// 4. Final Validation: Missing context check
		if companyID == uuid.Nil && !ctxval.IsGlobalRole(c) {
			return response.Forbidden(c, "Multi-tenant violation: missing company context")
		}

		// Inject for downstream consistency
		if companyID != uuid.Nil {
			c.Locals("company_id", companyID.String())
		}

		return c.Next()
	}
}

// StrictTenantMiddleware forces a company_id to be present (no global bypass)
func StrictTenantMiddleware() fiber.Handler {
	return func(c *fiber.Ctx) error {
		// 1. Get IDs
		authCompanyID := ctxval.GetCompanyID(c)
		headerCompanyIDStr := c.Get("x-company-id")

		// log.Printf("[StrictTenantDebug] Incoming x-company-id: %s, Auth company_id: %s", headerCompanyIDStr, authCompanyID.String())

		// 2. Resolve final company context
		var companyID uuid.UUID

		if headerCompanyIDStr != "" {
			parsedID, err := uuid.Parse(headerCompanyIDStr)
			if err != nil {
				return response.BadRequest(c, "Invalid company context format")
			}
			companyID = parsedID
		} else {
			companyID = authCompanyID
		}

		// 3. Strict match if NOT Super Admin
		if !ctxval.IsGlobalRole(c) && authCompanyID != uuid.Nil {
			if companyID != authCompanyID {
				return response.Forbidden(c, "Tenant mismatch: cross-tenant access denied")
			}
		}

		// 4. Final Validation: Strict check (Nil is not allowed)
		if companyID == uuid.Nil {
			return response.Forbidden(c, "Strict tenant context required")
		}

		c.Locals("company_id", companyID.String())

		return c.Next()
	}
}
