package handlers

import (
	"git.elijahkuntz.com/Elijah/drive/database"
	"github.com/gofiber/fiber/v2"
)

type SettingsHandler struct {
	DB *database.DB
}

// GetSettings returns all application settings.
// GET /api/settings
func (h *SettingsHandler) GetSettings(c *fiber.Ctx) error {
	rows, err := h.DB.Query("SELECT key, value FROM settings")
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "database error"})
	}
	defer rows.Close()

	settings := make(map[string]string)
	for rows.Next() {
		var key, value string
		if err := rows.Scan(&key, &value); err != nil {
			continue
		}
		settings[key] = value
	}

	return c.JSON(fiber.Map{"settings": settings})
}

// UpdateSettings updates multiple settings at once.
// PUT /api/settings
func (h *SettingsHandler) UpdateSettings(c *fiber.Ctx) error {
	var body map[string]string
	if err := c.BodyParser(&body); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "invalid request body"})
	}

	allowedKeys := map[string]bool{
		"theme":                 true,
		"thumbnail_images":      true,
		"thumbnail_videos":      true,
		"max_versions":          true,
		"trash_auto_purge_days": true,
	}

	for key, value := range body {
		if !allowedKeys[key] {
			continue // Skip unknown keys silently
		}
		if err := h.DB.SetSetting(key, value); err != nil {
			return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "failed to update setting: " + key})
		}
		h.DB.AddAuditLog("setting_changed", key+"="+value, c.IP())
	}

	return c.JSON(fiber.Map{"message": "settings updated"})
}

// GetAuditLog returns the audit log entries.
// GET /api/audit
func (h *SettingsHandler) GetAuditLog(c *fiber.Ctx) error {
	limit := c.QueryInt("limit", 100)
	offset := c.QueryInt("offset", 0)

	rows, err := h.DB.Query(
		"SELECT id, action, details, ip_address, created_at FROM audit_log ORDER BY created_at DESC LIMIT ? OFFSET ?",
		limit, offset,
	)
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "database error"})
	}
	defer rows.Close()

	type AuditEntry struct {
		ID        int    `json:"id"`
		Action    string `json:"action"`
		Details   string `json:"details"`
		IP        string `json:"ip"`
		CreatedAt string `json:"created_at"`
	}

	entries := []AuditEntry{}
	for rows.Next() {
		var e AuditEntry
		if err := rows.Scan(&e.ID, &e.Action, &e.Details, &e.IP, &e.CreatedAt); err != nil {
			continue
		}
		entries = append(entries, e)
	}

	return c.JSON(fiber.Map{"entries": entries, "count": len(entries)})
}
