<?php

declare(strict_types=1);

namespace App\Repositories;

use App\Core\Database;

final class SettingsRepository
{
    public function all(): array
    {
        $rows = Database::connection()->query('SELECT setting_key, setting_value, setting_type, is_sensitive FROM settings ORDER BY setting_key')->fetchAll();
        $settings = [];
        foreach ($rows as $row) {
            $settings[(string) $row['setting_key']] = [
                'value' => $row['setting_value'],
                'type' => $row['setting_type'],
                'sensitive' => (bool) $row['is_sensitive'],
            ];
        }
        return $settings;
    }

    public function ensureDefaults(array $defaults): void
    {
        $pdo = Database::connection();
        $stmt = $pdo->prepare('INSERT INTO settings (setting_key, setting_value, setting_type, is_sensitive) VALUES (:setting_key, :setting_value, :setting_type, :is_sensitive) ON DUPLICATE KEY UPDATE setting_key = setting_key');
        foreach ($defaults as $key => $definition) {
            $stmt->execute([
                'setting_key' => $key,
                'setting_value' => $definition['value'],
                'setting_type' => $definition['type'],
                'is_sensitive' => !empty($definition['sensitive']) ? 1 : 0,
            ]);
        }
    }

    public function updateMany(array $values): void
    {
        $pdo = Database::connection();
        $stmt = $pdo->prepare('INSERT INTO settings (setting_key, setting_value, setting_type, is_sensitive) VALUES (:key, :value, :type, :sensitive) ON DUPLICATE KEY UPDATE setting_value = VALUES(setting_value), setting_type = VALUES(setting_type), updated_at = NOW()');
        foreach ($values as $key => $value) {
            $type = 'string';
            if (str_starts_with((string)$key, 'regional.decimal_places')) $type = 'integer';
            elseif ($key === 'tax.enabled') $type = 'boolean';
            elseif ($key === 'tax.rate') $type = 'decimal';
            $stmt->execute(['key' => $key, 'value' => $value, 'type' => $type, 'sensitive' => ($key === 'mail.smtp.password' ? 1 : 0)]);
        }
    }

    public function audit(int $userId, string $action, array $metadata = []): void
    {
        $stmt = Database::connection()->prepare('INSERT INTO audit_logs (user_id, action, entity_type, entity_id, ip_address, metadata, created_at) VALUES (:user_id, :action, :entity_type, NULL, :ip, :metadata, NOW())');
        $stmt->execute([
            'user_id' => $userId,
            'action' => $action,
            'entity_type' => 'settings',
            'ip' => $_SERVER['REMOTE_ADDR'] ?? null,
            'metadata' => json_encode($metadata, JSON_THROW_ON_ERROR),
        ]);
    }
}
