package middleware

import (
	"context"
	"log"
	"net/http"
	"strings"

	"aggios-app/backend/internal/repository"
)

const SubdomainKey contextKey = "subdomain"

// TenantDetector detects tenant from subdomain
func TenantDetector(tenantRepo *repository.TenantRepository) func(http.Handler) http.Handler {
	return func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			// Get host from X-Forwarded-Host header (set by Next.js proxy) or Host header
			// Priority order: X-Tenant-Subdomain (set by Next.js middleware) > X-Forwarded-Host > X-Original-Host > Host
			tenantSubdomain := r.Header.Get("X-Tenant-Subdomain")
			
			var host string
			if tenantSubdomain != "" {
				// Use direct subdomain from Next.js middleware
				host = tenantSubdomain
				log.Printf("TenantDetector: using X-Tenant-Subdomain = %s", tenantSubdomain)
			} else {
				// Fallback to extracting from host headers
				host = r.Header.Get("X-Forwarded-Host")
				if host == "" {
					host = r.Header.Get("X-Original-Host")
				}
				if host == "" {
					host = r.Host
				}
				log.Printf("TenantDetector: host = %s (from headers), path = %s", host, r.RequestURI)
			}
			
			// Extract subdomain
			// Examples:
			// - agencia-xyz.localhost -> agencia-xyz
			// - agencia-xyz.aggios.app -> agencia-xyz
			// - dash.localhost -> dash (master admin)
			// - localhost -> (institutional site)
			
			var subdomain string
			
			// If we got the subdomain directly from X-Tenant-Subdomain, use it
			if tenantSubdomain != "" {
				subdomain = tenantSubdomain
				// Remove port if present
				if strings.Contains(subdomain, ":") {
					subdomain = strings.Split(subdomain, ":")[0]
				}
			} else {
				// Extract from host
				parts := strings.Split(host, ".")
				
				if len(parts) >= 2 {
					// Has subdomain
					subdomain = parts[0]
					
					// Remove port if present
					if strings.Contains(subdomain, ":") {
						subdomain = strings.Split(subdomain, ":")[0]
					}
				}
			}
			
			log.Printf("TenantDetector: extracted subdomain = %s", subdomain)
			
			// Add subdomain to context
			ctx := context.WithValue(r.Context(), SubdomainKey, subdomain)
			
			// If subdomain is not empty and not "dash" or "api", try to find tenant
			if subdomain != "" && subdomain != "dash" && subdomain != "api" && subdomain != "localhost" {
				tenant, err := tenantRepo.FindBySubdomain(subdomain)
				if err == nil && tenant != nil {
					log.Printf("TenantDetector: found tenant %s for subdomain %s", tenant.ID.String(), subdomain)
					ctx = context.WithValue(ctx, TenantIDKey, tenant.ID.String())
				} else {
					log.Printf("TenantDetector: tenant not found for subdomain %s (err=%v)", subdomain, err)
				}
			}
			
			next.ServeHTTP(w, r.WithContext(ctx))
		})
	}
}
