<?php
// ─────────────────────────────────────────────────────────────
//  lib/ModuleToggle.php — Module on/off gate
// ─────────────────────────────────────────────────────────────
//  Usage:
//    ModuleToggle::isEnabled('module_booking')      → bool
//    ModuleToggle::requireEnabled('module_booking') → exits with 403 JSON if off
// ─────────────────────────────────────────────────────────────
if (!defined('DB_HOST')) require_once dirname(__DIR__) . '/lib.php';

class ModuleToggle {

    /** Per-request cache so we hit the DB at most once per key. */
    private static array $cache = [];

    /**
     * Returns true when the module is enabled, false otherwise.
     * Unknown keys return false in production; throw in dev (APP_DEBUG=true).
     */
    public static function isEnabled(string $key): bool {
        if (array_key_exists($key, self::$cache)) {
            return self::$cache[$key];
        }

        try {
            $stmt = db()->prepare(
                'SELECT is_enabled FROM sys_feature_toggles WHERE `key` = ? LIMIT 1'
            );
            $stmt->execute([$key]);
            $val = $stmt->fetchColumn();
        } catch (\Throwable $e) {
            // Table not yet created (first boot before migration runs)
            error_log('ModuleToggle: ' . $e->getMessage());
            return self::$cache[$key] = true; // fail open until table exists
        }

        if ($val === false) {
            // Unknown key
            if (defined('APP_DEBUG') && APP_DEBUG) {
                throw new \RuntimeException("ModuleToggle: unknown key '{$key}'");
            }
            return self::$cache[$key] = false;
        }

        return self::$cache[$key] = (bool) $val;
    }

    /**
     * Exits immediately with a 403 JSON response if the module is disabled.
     * Call as the very first line of any module-gated API endpoint.
     */
    public static function requireEnabled(string $key): void {
        if (!self::isEnabled($key)) {
            if (!headers_sent()) {
                header('Content-Type: application/json');
                http_response_code(403);
            }
            echo json_encode(['ok' => false, 'error' => 'This module is currently disabled.']);
            exit;
        }
    }

    /**
     * Returns the full list of toggles for the admin UI.
     */
    public static function all(): array {
        try {
            return db()->query(
                'SELECT `key`, label, description, is_enabled, updated_at
                 FROM sys_feature_toggles ORDER BY `key`'
            )->fetchAll();
        } catch (\Throwable $e) {
            return [];
        }
    }

    /**
     * Enable or disable a module. Called by the admin modules API.
     */
    public static function set(string $key, bool $enabled): bool {
        // First verify the key exists
        $check = db()->prepare('SELECT COUNT(*) FROM sys_feature_toggles WHERE `key` = ?');
        $check->execute([$key]);
        if ((int)$check->fetchColumn() === 0) {
            return false; // Unknown key
        }
        $stmt = db()->prepare(
            'UPDATE sys_feature_toggles SET is_enabled = ? WHERE `key` = ?'
        );
        $stmt->execute([(int) $enabled, $key]);
        unset(self::$cache[$key]);
        return true; // Key exists, update applied (even if value unchanged)
    }
}
