package controllers

import (
	"strconv"

	"github.com/gofiber/fiber/v2"
	"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
	"github.com/sujit-baniya/fiber-boilerplate/pkg/services"
)

// shieldClient construye el cliente Shield desde la config activa.
func shieldClient() (*services.ShieldClient, error) {
	cfg, err := models.GetShieldConfig()
	if err != nil {
		return nil, err
	}
	return services.NewShieldClient(cfg.BaseUrl, cfg.AdminToken), nil
}

// ─── Vista principal ─────────────────────────────────────────────────────────

func ShieldIndex(c *fiber.Ctx) error {
	return c.Render("shield", fiber.Map{
		"user":    c.Locals("user"),
		"modules": c.Locals("userModules"),
	}, "layouts/main")
}

// ─── Configuración ───────────────────────────────────────────────────────────

func LoadShieldConfig(c *fiber.Ctx) error {
	cfg, err := models.GetShieldConfig()
	if err != nil {
		return c.JSON(fiber.Map{"base_url": "https://api-shield.u-s.app", "admin_token": "", "activo": true, "nota": ""})
	}
	return c.JSON(cfg)
}

func SaveShieldConfig(c *fiber.Ctx) error {
	var req models.ShieldConfig
	if err := c.BodyParser(&req); err != nil {
		return c.Status(400).JSON(fiber.Map{"error": err.Error()})
	}
	if req.BaseUrl == "" {
		req.BaseUrl = "https://api-shield.u-s.app"
	}
	if err := models.UpsertShieldConfig(&req); err != nil {
		return c.Status(500).JSON(fiber.Map{"error": err.Error()})
	}
	return c.JSON(fiber.Map{"ok": true})
}

// ─── Health ──────────────────────────────────────────────────────────────────

func ShieldHealth(c *fiber.Ctx) error {
	client, err := shieldClient()
	if err != nil {
		return c.JSON(fiber.Map{"status": "sin configurar", "db": "-", "error": "No hay configuración Shield activa"})
	}
	data, err := client.Health()
	if err != nil {
		return c.JSON(fiber.Map{"status": "offline", "db": "-", "error": err.Error()})
	}
	return c.JSON(data)
}

func ShieldExtensionVersion(c *fiber.Ctx) error {
	client, err := shieldClient()
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": "Sin configuración"})
	}
	data, err := client.ExtensionVersion()
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": err.Error()})
	}
	return c.JSON(data)
}

// ─── Logs ────────────────────────────────────────────────────────────────────

func ShieldLogs(c *fiber.Ctx) error {
	client, err := shieldClient()
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": "Sin configuración"})
	}
	limit, _ := strconv.Atoi(c.Query("limit", "100"))
	data, err := client.Logs(limit, c.Query("path"), c.Query("method"))
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": err.Error()})
	}
	return c.JSON(data)
}

func ShieldLogStats(c *fiber.Ctx) error {
	client, err := shieldClient()
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": "Sin configuración"})
	}
	data, err := client.LogStats()
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": err.Error()})
	}
	return c.JSON(data)
}

// ─── Review requests ─────────────────────────────────────────────────────────

func ShieldReviewRequests(c *fiber.Ctx) error {
	client, err := shieldClient()
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": "Sin configuración"})
	}
	data, err := client.ReviewRequests(c.Query("status", "pending"))
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": err.Error()})
	}
	return c.JSON(data)
}

func ShieldApproveRequest(c *fiber.Ctx) error {
	client, err := shieldClient()
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": "Sin configuración"})
	}
	id := c.Params("id")
	var body struct {
		Note   string `json:"note"`
		Reason string `json:"reason"`
	}
	c.BodyParser(&body)
	data, err := client.ApproveRequest(id, body.Note, body.Reason)
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": err.Error()})
	}
	return c.JSON(data)
}

func ShieldRejectRequest(c *fiber.Ctx) error {
	client, err := shieldClient()
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": "Sin configuración"})
	}
	id := c.Params("id")
	var body struct {
		Note string `json:"note"`
	}
	c.BodyParser(&body)
	data, err := client.RejectRequest(id, body.Note)
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": err.Error()})
	}
	return c.JSON(data)
}

// ─── Whitelist ───────────────────────────────────────────────────────────────

func ShieldWhitelist(c *fiber.Ctx) error {
	client, err := shieldClient()
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": "Sin configuración"})
	}
	data, err := client.Whitelist()
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": err.Error()})
	}
	return c.JSON(data)
}

func ShieldAddWhitelist(c *fiber.Ctx) error {
	client, err := shieldClient()
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": "Sin configuración"})
	}
	var body struct {
		Domain  string `json:"domain"`
		Reason  string `json:"reason"`
		AddedBy string `json:"added_by"`
	}
	if err := c.BodyParser(&body); err != nil || body.Domain == "" {
		return c.Status(400).JSON(fiber.Map{"error": "domain requerido"})
	}
	if body.AddedBy == "" {
		body.AddedBy = "admin"
	}
	data, err := client.AddWhitelist(body.Domain, body.Reason, body.AddedBy)
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": err.Error()})
	}
	return c.JSON(data)
}

func ShieldDeleteWhitelist(c *fiber.Ctx) error {
	client, err := shieldClient()
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": "Sin configuración"})
	}
	domain := c.Params("domain")
	if err := client.DeleteWhitelist(domain); err != nil {
		return c.Status(500).JSON(fiber.Map{"error": err.Error()})
	}
	return c.JSON(fiber.Map{"ok": true})
}

// ─── Blacklist ───────────────────────────────────────────────────────────────

func ShieldBlacklist(c *fiber.Ctx) error {
	client, err := shieldClient()
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": "Sin configuración"})
	}
	data, err := client.Blacklist()
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": err.Error()})
	}
	return c.JSON(data)
}

func ShieldAddBlacklist(c *fiber.Ctx) error {
	client, err := shieldClient()
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": "Sin configuración"})
	}
	var body struct {
		Domain  string `json:"domain"`
		Reason  string `json:"reason"`
		AddedBy string `json:"added_by"`
	}
	if err := c.BodyParser(&body); err != nil || body.Domain == "" {
		return c.Status(400).JSON(fiber.Map{"error": "domain requerido"})
	}
	if body.AddedBy == "" {
		body.AddedBy = "admin"
	}
	data, err := client.AddBlacklist(body.Domain, body.Reason, body.AddedBy)
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": err.Error()})
	}
	return c.JSON(data)
}

func ShieldDeleteBlacklist(c *fiber.Ctx) error {
	client, err := shieldClient()
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": "Sin configuración"})
	}
	domain := c.Params("domain")
	if err := client.DeleteBlacklist(domain); err != nil {
		return c.Status(500).JSON(fiber.Map{"error": err.Error()})
	}
	return c.JSON(fiber.Map{"ok": true})
}

// ─── Reputación ──────────────────────────────────────────────────────────────

func ShieldReputation(c *fiber.Ctx) error {
	client, err := shieldClient()
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": "Sin configuración"})
	}
	domain := c.Params("domain")
	data, err := client.Reputation(domain)
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": err.Error()})
	}
	return c.JSON(data)
}

func ShieldAdjustScore(c *fiber.Ctx) error {
	client, err := shieldClient()
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": "Sin configuración"})
	}
	domain := c.Params("domain")
	var body struct {
		VotesReal int `json:"votes_real"`
		VotesFake int `json:"votes_fake"`
	}
	if err := c.BodyParser(&body); err != nil {
		return c.Status(400).JSON(fiber.Map{"error": err.Error()})
	}
	data, err := client.AdjustScore(domain, body.VotesReal, body.VotesFake)
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": err.Error()})
	}
	return c.JSON(data)
}
