package controllers

import (
	"github.com/gofiber/fiber/v2"
	"github.com/sujit-baniya/fiber-boilerplate/app"
	"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
	"github.com/sujit-baniya/fiber-boilerplate/utils"
)

func SmtpConfigView(c *fiber.Ctx) error {
	cfg, _ := models.GetSmtpConfig()
	return c.Render("renovaciones/smtp", fiber.Map{
		"user":    c.Locals("user"),
		"modules": c.Locals("userModules"),
		"config":  cfg,
	}, "layouts/main")
}

func GetSmtpConfig(c *fiber.Ctx) error {
	cfg, err := models.GetSmtpConfig()
	if err != nil {
		return c.JSON(fiber.Map{"ok": false, "config": nil})
	}
	// No exponer contraseña en claro
	cfg.Password = "***"
	return c.JSON(fiber.Map{"ok": true, "config": cfg})
}

func SaveSmtpConfig(c *fiber.Ctx) error {
	type Input struct {
		Host        string `json:"host"`
		Port        int    `json:"port"`
		Username    string `json:"username"`
		Password    string `json:"password"`
		Encryption  string `json:"encryption"`
		FromAddress string `json:"from_address"`
		FromName    string `json:"from_name"`
	}
	var inp Input
	if err := c.BodyParser(&inp); err != nil {
		return c.Status(400).JSON(fiber.Map{"error": err.Error()})
	}

	// Cifrar contraseña solo si se provee una nueva (no es placeholder)
	passEncrypted := inp.Password
	if inp.Password != "" && inp.Password != "***" {
		passEncrypted = utils.Encrypt(inp.Password, app.Http.Server.Key)
	} else if inp.Password == "***" {
		// Mantener contraseña ya guardada
		if existing, err := models.GetSmtpConfig(); err == nil {
			passEncrypted = existing.Password
		}
	}

	cfg := models.SmtpConfig{
		Host:        inp.Host,
		Port:        inp.Port,
		Username:    inp.Username,
		Password:    passEncrypted,
		Encryption:  inp.Encryption,
		FromAddress: inp.FromAddress,
		FromName:    inp.FromName,
	}

	if err := models.SaveSmtpConfig(cfg); err != nil {
		return c.Status(500).JSON(fiber.Map{"error": err.Error()})
	}

	// Recargar el mailer en memoria con la nueva config
	app.Http.Mail.Host = cfg.Host
	app.Http.Mail.Port = cfg.Port
	app.Http.Mail.Username = cfg.Username
	app.Http.Mail.Password = utils.Decrypt(passEncrypted, app.Http.Server.Key)
	app.Http.Mail.Encryption = cfg.Encryption
	app.Http.Mail.FromAddress = cfg.FromAddress
	app.Http.Mail.FromName = cfg.FromName
	app.Http.Mail.SetupMailer()

	return c.JSON(fiber.Map{"message": "Configuración guardada", "ok": true})
}

func TestSmtpConfig(c *fiber.Ctx) error {
	var body struct {
		Email string `json:"email"`
	}
	if err := c.BodyParser(&body); err != nil || body.Email == "" {
		return c.Status(400).JSON(fiber.Map{"error": "Email de destino requerido"})
	}

	// Recargar siempre la config activa desde BD para evitar usar credenciales
	// del .env que pudieran estar desactualizadas en memoria.
	cfg, err := models.GetSmtpConfig()
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": "No hay configuración SMTP activa"})
	}
	app.Http.Mail.Host = cfg.Host
	app.Http.Mail.Port = cfg.Port
	app.Http.Mail.Username = cfg.Username
	app.Http.Mail.Password = utils.Decrypt(cfg.Password, app.Http.Server.Key)
	app.Http.Mail.Encryption = cfg.Encryption
	app.Http.Mail.FromAddress = cfg.FromAddress
	app.Http.Mail.FromName = cfg.FromName
	app.Http.Mail.SetupMailer()

	htmlBody := "<h2>Test SMTP</h2><p>La configuración SMTP funciona correctamente.</p>"
	if err := app.Http.Mail.Send(body.Email, "Test SMTP - U-site", htmlBody); err != nil {
		return c.Status(500).JSON(fiber.Map{"error": err.Error()})
	}
	return c.JSON(fiber.Map{"message": "Correo de prueba enviado", "ok": true})
}
