<?php

declare(strict_types=1);

namespace ShieldX\WPCLI;

defined('ABSPATH') || exit;

use ShieldX\Security\MinimalWaf;
use ShieldX\Security\WafSettings;
use ShieldX\Security\WafStats;
use ShieldX\Storage\FileStorage;

final class WafCommand
{
    /**
     * Inspect or refresh the SHIELD-X WAF rule catalog.
     *
     * @synopsis [<status|rules|refresh>] [--format=<format>]
     *
     * @param array<int,string>   $args
     * @param array<string,mixed> $assocArgs
     */
    public function __invoke(array $args, array $assocArgs): void
    {
        AdminGate::requireManageOptions();

        $subcommand = isset($args[0]) ? (string) $args[0] : 'status';
        $json = CommandOutput::isJson($assocArgs);

        switch ($subcommand) {
            case 'status':
                $this->status($json);
                return;

            case 'rules':
                $this->rules($json);
                return;

            case 'refresh':
                $this->refresh($json);
                return;

            default:
                \WP_CLI::error('Unknown WAF command. Use status, rules, or refresh.');
        }
    }

    private function status(bool $json): void
    {
        $settings = WafSettings::fromWordPress();
        $waf = new MinimalWaf(MinimalWaf::defaultRules(), $settings);
        $summary = $waf->ruleSummary();
        $stats = (new WafStats(FileStorage::fromWordPress()))->summary();

        if ($json) {
            CommandOutput::writeJson([
                'command' => 'waf',
                'subcommand' => 'status',
                'mode' => $waf->mode(),
                'engine_version' => $waf->engineVersion(),
                'rules' => $summary,
                'stats' => $stats,
            ]);
            return;
        }

        \WP_CLI::line('Mode: ' . $waf->mode());
        \WP_CLI::line('Engine: ' . $waf->engineVersion());
        \WP_CLI::line('Rules: ' . (string) ($summary['enabled'] ?? 0) . '/' . (string) ($summary['total'] ?? 0));
        \WP_CLI::line('Hits 24h: ' . (string) ($stats['hits_24h'] ?? 0));
        \WP_CLI::line('Total hits: ' . (string) ($stats['total_hits'] ?? 0));
        \WP_CLI::success('SHIELD-X WAF status completed.');
    }

    private function rules(bool $json): void
    {
        $waf = new MinimalWaf(MinimalWaf::defaultRules(), WafSettings::fromWordPress());
        $rules = $waf->rules();

        if ($json) {
            CommandOutput::writeJson([
                'command' => 'waf',
                'subcommand' => 'rules',
                'rules' => $rules,
            ]);
            return;
        }

        foreach ($rules as $rule) {
            \WP_CLI::line(sprintf(
                '%s [%s/%s] %s',
                (string) ($rule['id'] ?? ''),
                (string) ($rule['category'] ?? ''),
                (string) ($rule['severity'] ?? ''),
                empty($rule['enabled']) ? 'disabled' : 'enabled'
            ));
        }
        \WP_CLI::success('SHIELD-X WAF rules listed.');
    }

    private function refresh(bool $json): void
    {
        $rules = MinimalWaf::defaultRules();
        $summary = MinimalWaf::summarizeRules($rules);
        if (function_exists('update_option')) {
            update_option('shieldx_waf_rules_refreshed_at', gmdate('c'), false);
        }

        if ($json) {
            CommandOutput::writeJson([
                'command' => 'waf',
                'subcommand' => 'refresh',
                'rule_channel' => 'bundled_mvp',
                'summary' => $summary,
            ]);
            return;
        }

        \WP_CLI::line('Rule channel: bundled_mvp');
        \WP_CLI::line('Rules loaded from bundled catalog: ' . (string) ($summary['total'] ?? count($rules)));
        \WP_CLI::success('SHIELD-X WAF rules refreshed from the bundled catalog.');
    }
}
