package handlers

import (
	"encoding/json"
	"log"
	"net/http"

	"aggios-app/backend/internal/api/middleware"
	"aggios-app/backend/internal/service"

	"github.com/google/uuid"
)

// TenantHandler handles tenant/agency listing endpoints
type TenantHandler struct {
	tenantService *service.TenantService
}

// NewTenantHandler creates a new tenant handler
func NewTenantHandler(tenantService *service.TenantService) *TenantHandler {
	return &TenantHandler{
		tenantService: tenantService,
	}
}

// ListAll lists all agencies/tenants (SUPERADMIN only)
func (h *TenantHandler) ListAll(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	tenants, err := h.tenantService.ListAllWithDetails()
	if err != nil {
		log.Printf("Error listing tenants with details: %v", err)
		http.Error(w, "Internal server error", http.StatusInternalServerError)
		return
	}

	if tenants == nil {
		tenants = []map[string]interface{}{}
	}

	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	json.NewEncoder(w).Encode(tenants)
}

// CheckExists returns 200 if tenant exists by subdomain, otherwise 404
func (h *TenantHandler) CheckExists(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	subdomain := r.URL.Query().Get("subdomain")
	if subdomain == "" {
		http.Error(w, "subdomain is required", http.StatusBadRequest)
		return
	}

	_, err := h.tenantService.GetBySubdomain(subdomain)
	if err != nil {
		if err == service.ErrTenantNotFound {
			http.NotFound(w, r)
			return
		}
		http.Error(w, "Internal server error", http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
}

// GetPublicConfig returns public branding info for a tenant by subdomain
func (h *TenantHandler) GetPublicConfig(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	subdomain := r.URL.Query().Get("subdomain")
	if subdomain == "" {
		http.Error(w, "subdomain is required", http.StatusBadRequest)
		return
	}

	tenant, err := h.tenantService.GetBySubdomain(subdomain)
	if err != nil {
		if err == service.ErrTenantNotFound {
			http.NotFound(w, r)
			return
		}
		http.Error(w, "Internal server error", http.StatusInternalServerError)
		return
	}

	// Return only public info
	response := map[string]interface{}{
		"id":                  tenant.ID.String(),
		"name":                tenant.Name,
		"primary_color":       tenant.PrimaryColor,
		"secondary_color":     tenant.SecondaryColor,
		"logo_url":            tenant.LogoURL,
		"logo_horizontal_url": tenant.LogoHorizontalURL,
	}

	log.Printf("📤 Returning tenant config for %s: logo_url=%s", subdomain, tenant.LogoURL)

	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	json.NewEncoder(w).Encode(response)
}

// GetBranding returns branding info for the current authenticated tenant
func (h *TenantHandler) GetBranding(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	// Get tenant from context (set by auth middleware)
	tenantID := r.Context().Value(middleware.TenantIDKey)
	if tenantID == nil {
		http.Error(w, "Tenant not found in context", http.StatusUnauthorized)
		return
	}

	// Parse tenant ID
	tid, err := uuid.Parse(tenantID.(string))
	if err != nil {
		http.Error(w, "Invalid tenant ID", http.StatusBadRequest)
		return
	}

	// Get tenant from database
	tenant, err := h.tenantService.GetByID(tid)
	if err != nil {
		http.Error(w, "Error fetching branding", http.StatusInternalServerError)
		return
	}

	// Return branding info
	response := map[string]interface{}{
		"id":                  tenant.ID.String(),
		"name":                tenant.Name,
		"primary_color":       tenant.PrimaryColor,
		"secondary_color":     tenant.SecondaryColor,
		"logo_url":            tenant.LogoURL,
		"logo_horizontal_url": tenant.LogoHorizontalURL,
	}

	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	json.NewEncoder(w).Encode(response)
}

// GetProfile returns public tenant information by tenant ID
func (h *TenantHandler) GetProfile(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	// Extract tenant ID from URL path
	// URL format: /api/tenants/{id}/profile
	tenantIDStr := r.URL.Path[len("/api/tenants/"):]
	if idx := len(tenantIDStr) - len("/profile"); idx > 0 {
		tenantIDStr = tenantIDStr[:idx]
	}

	if tenantIDStr == "" {
		http.Error(w, "tenant_id is required", http.StatusBadRequest)
		return
	}

	// Para compatibilidade, aceitar tanto UUID quanto ID numérico
	// Primeiro tentar como UUID, se falhar buscar tenant diretamente
	tenant, err := h.tenantService.GetBySubdomain(tenantIDStr)
	if err != nil {
		log.Printf("Error getting tenant: %v", err)
		http.Error(w, "Tenant not found", http.StatusNotFound)
		return
	}

	// Return public info
	response := map[string]interface{}{
		"tenant": map[string]string{
			"company":             tenant.Name,
			"primary_color":       tenant.PrimaryColor,
			"secondary_color":     tenant.SecondaryColor,
			"logo_url":            tenant.LogoURL,
			"logo_horizontal_url": tenant.LogoHorizontalURL,
		},
	}

	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	json.NewEncoder(w).Encode(response)
}
