package handlers

import (
	"aggios-app/backend/internal/domain"
	"aggios-app/backend/internal/repository"
	"aggios-app/backend/internal/service"
	"encoding/json"
	"log"
	"net/http"

	"golang.org/x/crypto/bcrypt"
)

type AgencyTemplateHandler struct {
	templateRepo  *repository.AgencyTemplateRepository
	agencyService *service.AgencyService
	userRepo      *repository.UserRepository
	tenantRepo    *repository.TenantRepository
}

func NewAgencyTemplateHandler(
	templateRepo *repository.AgencyTemplateRepository,
	agencyService *service.AgencyService,
	userRepo *repository.UserRepository,
	tenantRepo *repository.TenantRepository,
) *AgencyTemplateHandler {
	return &AgencyTemplateHandler{
		templateRepo:  templateRepo,
		agencyService: agencyService,
		userRepo:      userRepo,
		tenantRepo:    tenantRepo,
	}
}

// GetTemplateBySlug - Public endpoint to get template details
func (h *AgencyTemplateHandler) GetTemplateBySlug(w http.ResponseWriter, r *http.Request) {
	slug := r.URL.Query().Get("slug")
	if slug == "" {
		http.Error(w, "Missing slug parameter", http.StatusBadRequest)
		return
	}

	template, err := h.templateRepo.FindBySlug(slug)
	if err != nil {
		log.Printf("Template not found: %v", err)
		http.Error(w, "Template not found or expired", http.StatusNotFound)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(template)
}

// PublicRegisterAgency - Public endpoint for agency registration via template
func (h *AgencyTemplateHandler) PublicRegisterAgency(w http.ResponseWriter, r *http.Request) {
	var req domain.AgencyRegistrationViaTemplate
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, "Invalid request body", http.StatusBadRequest)
		return
	}

	// 1. Validar template
	template, err := h.templateRepo.FindBySlug(req.TemplateSlug)
	if err != nil {
		log.Printf("Template error: %v", err)
		http.Error(w, "Invalid or expired template", http.StatusBadRequest)
		return
	}

	// 2. Validar campos obrigatórios
	if req.AgencyName == "" || req.Subdomain == "" || req.AdminEmail == "" || req.AdminPassword == "" {
		http.Error(w, "Missing required fields", http.StatusBadRequest)
		return
	}

	// 3. Validar senha
	if len(req.AdminPassword) < 8 {
		http.Error(w, "Password must be at least 8 characters", http.StatusBadRequest)
		return
	}

	// 4. Verificar se email já existe
	existingUser, _ := h.userRepo.FindByEmail(req.AdminEmail)
	if existingUser != nil {
		http.Error(w, "Email already registered", http.StatusConflict)
		return
	}

	// 5. Verificar se subdomain já existe
	existingTenant, _ := h.tenantRepo.FindBySubdomain(req.Subdomain)
	if existingTenant != nil {
		http.Error(w, "Subdomain already taken", http.StatusConflict)
		return
	}

	// 6. Hash da senha
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.AdminPassword), bcrypt.DefaultCost)
	if err != nil {
		log.Printf("Error hashing password: %v", err)
		http.Error(w, "Error processing password", http.StatusInternalServerError)
		return
	}

	// 7. Criar tenant (agência)
	tenant := &domain.Tenant{
		Name:        req.AgencyName,
		Domain:      req.Subdomain + ".aggios.app",
		Subdomain:   req.Subdomain,
		CNPJ:        req.CNPJ,
		RazaoSocial: req.RazaoSocial,
		Website:     req.Website,
		Phone:       req.Phone,
		Description: req.Description,
		Industry:    req.Industry,
		TeamSize:    req.TeamSize,
	}

	// Endereço (se fornecido)
	if req.Address != nil {
		tenant.Address = req.Address["street"]
		tenant.Number = req.Address["number"]
		tenant.Complement = req.Address["complement"]
		tenant.Neighborhood = req.Address["neighborhood"]
		tenant.City = req.Address["city"]
		tenant.State = req.Address["state"]
		tenant.Zip = req.Address["cep"]
	}

	// Personalização do template
	if template.CustomPrimaryColor.Valid {
		tenant.PrimaryColor = template.CustomPrimaryColor.String
	}
	if template.CustomLogoURL.Valid {
		tenant.LogoURL = template.CustomLogoURL.String
	}

	if err := h.tenantRepo.Create(tenant); err != nil {
		log.Printf("Error creating tenant: %v", err)
		http.Error(w, "Error creating agency", http.StatusInternalServerError)
		return
	}

	// 8. Criar usuário admin da agência
	user := &domain.User{
		Email:    req.AdminEmail,
		Password: string(hashedPassword),
		Name:     req.AdminName,
		Role:     "ADMIN_AGENCIA",
		TenantID: &tenant.ID,
	}

	if err := h.userRepo.Create(user); err != nil {
		log.Printf("Error creating user: %v", err)
		http.Error(w, "Error creating admin user", http.StatusInternalServerError)
		return
	}

	// 9. Incrementar contador de uso do template
	if err := h.templateRepo.IncrementUsageCount(template.ID.String()); err != nil {
		log.Printf("Warning: failed to increment usage count: %v", err)
	}

	// 10. Preparar resposta com redirect
	redirectURL := template.RedirectURL.String
	if redirectURL == "" {
		redirectURL = "http://" + req.Subdomain + ".localhost/login"
	}

	response := map[string]interface{}{
		"success":      true,
		"message":      template.SuccessMessage.String,
		"tenant_id":    tenant.ID,
		"user_id":      user.ID,
		"redirect_url": redirectURL,
		"subdomain":    req.Subdomain,
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(response)
}

// CreateTemplate - SUPERADMIN only
func (h *AgencyTemplateHandler) CreateTemplate(w http.ResponseWriter, r *http.Request) {
	var req domain.CreateAgencyTemplateRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, "Invalid request", http.StatusBadRequest)
		return
	}

	formFieldsJSON, _ := repository.FormFieldsToJSON(req.FormFields)
	modulesJSON, _ := json.Marshal(req.AvailableModules)

	template := &domain.AgencySignupTemplate{
		Name:             req.Name,
		Slug:             req.Slug,
		Description:      req.Description,
		FormFields:       formFieldsJSON,
		AvailableModules: modulesJSON,
		IsActive:         true,
	}

	if req.CustomPrimaryColor != "" {
		template.CustomPrimaryColor.Valid = true
		template.CustomPrimaryColor.String = req.CustomPrimaryColor
	}
	if req.CustomLogoURL != "" {
		template.CustomLogoURL.Valid = true
		template.CustomLogoURL.String = req.CustomLogoURL
	}
	if req.RedirectURL != "" {
		template.RedirectURL.Valid = true
		template.RedirectURL.String = req.RedirectURL
	}
	if req.SuccessMessage != "" {
		template.SuccessMessage.Valid = true
		template.SuccessMessage.String = req.SuccessMessage
	}

	if err := h.templateRepo.Create(template); err != nil {
		log.Printf("Error creating template: %v", err)
		http.Error(w, "Error creating template", http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(template)
}

// ListTemplates - SUPERADMIN only
func (h *AgencyTemplateHandler) ListTemplates(w http.ResponseWriter, r *http.Request) {
	templates, err := h.templateRepo.List()
	if err != nil {
		http.Error(w, "Error fetching templates", http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(templates)
}
