<?php

declare(strict_types=1);

namespace ProRank\SEO\CLI;

use ProRank\SEO\Core\Performance\ObjectCacheHealth;
use WP_CLI;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Read-only object-cache diagnostics.
 *
 * ## EXAMPLES
 *
 *     # Quick status (backend, drop-in, persistent?)
 *     wp prorank object-cache status
 *
 *     # Test the cache/Redis connection with the real config
 *     wp prorank object-cache test
 *
 *     # Full health report with flags + recommendations
 *     wp prorank object-cache health
 *
 * No subcommand performs a destructive action.
 */
class ObjectCacheCommand {

    private function diagnostic(): ObjectCacheHealth {
        return new ObjectCacheHealth();
    }

    /**
     * Show object-cache status.
     *
     * @when after_wp_load
     */
    public function status(): void {
        $r = $this->diagnostic()->report();
        WP_CLI::log('Persistent object cache : ' . (!empty($r['persistent_cache']) ? 'yes' : 'no'));
        WP_CLI::log('Backend                 : ' . ($r['backend_label'] ?? 'Unknown'));
        $d = $r['dropin'] ?? [];
        WP_CLI::log('object-cache.php        : ' . ($d['state'] ?? 'unknown') . (empty($d['owner']) ? '' : ' (' . $d['owner'] . ')'));
        $c = $r['connection'] ?? [];
        if (!empty($c['tested'])) {
            WP_CLI::log('Connection              : ' . (!empty($c['connected']) ? 'connected' : 'FAILED') .
                ($c['latency_ms'] !== null ? sprintf(' (%.2f ms)', $c['latency_ms']) : ''));
        }
        WP_CLI::log('Overall status          : ' . strtoupper((string) ($r['status'] ?? 'unknown')));
    }

    /**
     * Test the cache/Redis connection using the resolved real configuration.
     *
     * @when after_wp_load
     */
    public function test(): void {
        $h = $this->diagnostic();
        $c = $h->probe_connection();

        if (empty($c['tested'])) {
            WP_CLI::warning('No persistent object cache is active — nothing to test.');
            return;
        }

        WP_CLI::log('Method     : ' . ($c['method'] ?? 'unknown'));
        if (!empty($c['config'])) {
            $cfg = $c['config'];
            WP_CLI::log('Config src : ' . ($cfg['source'] ?? 'unknown'));
            if (!empty($cfg['path'])) {
                WP_CLI::log('Socket     : ' . $cfg['path']);
            } else {
                WP_CLI::log('Endpoint   : ' . ($cfg['host'] ?? '?') . ':' . ($cfg['port'] ?? '?'));
            }
            WP_CLI::log('Database   : ' . ($cfg['database'] ?? 0));
            WP_CLI::log('Auth       : ' . (!empty($cfg['auth']) ? 'yes' : 'no'));
        }
        if ($c['latency_ms'] !== null) {
            WP_CLI::log(sprintf('Latency    : %.2f ms', $c['latency_ms']));
        }

        if (!empty($c['connected'])) {
            WP_CLI::success('Connection OK.');
        } else {
            WP_CLI::error('Connection FAILED' . (!empty($c['error']) ? ': ' . $c['error'] : '.'), false);
        }
    }

    /**
     * Full object-cache health report.
     *
     * ## OPTIONS
     *
     * [--format=<format>]
     * : table|json|yaml. Default table.
     *
     * @when after_wp_load
     */
    public function health($args, $assoc_args): void {
        $r = $this->diagnostic()->report();
        $format = $assoc_args['format'] ?? 'table';

        if ($format === 'json') {
            WP_CLI::log((string) wp_json_encode($r));
            return;
        }

        WP_CLI::log('=== ProRank Object Cache Health ===');
        WP_CLI::log('Status            : ' . strtoupper((string) ($r['status'] ?? 'unknown')));
        WP_CLI::log('Persistent cache  : ' . (!empty($r['persistent_cache']) ? 'yes' : 'no'));
        WP_CLI::log('Backend           : ' . ($r['backend_label'] ?? 'Unknown'));

        $d = $r['dropin'] ?? [];
        WP_CLI::log('Drop-in state     : ' . ($d['state'] ?? 'unknown'));
        WP_CLI::log('Drop-in owner     : ' . ($d['owner'] ?? '—'));

        $c = $r['connection'] ?? [];
        if (!empty($c['tested'])) {
            WP_CLI::log('Connection        : ' . (!empty($c['connected']) ? 'connected' : 'FAILED') .
                ($c['latency_ms'] !== null ? sprintf(' (%.2f ms)', $c['latency_ms']) : ''));
        }

        if (!empty($r['redis'])) {
            $x = $r['redis'];
            WP_CLI::log('--- Redis ---');
            WP_CLI::log('  Version         : ' . ($x['version'] ?? '?'));
            WP_CLI::log('  Used memory     : ' . ($x['used_memory_human'] ?? '?'));
            WP_CLI::log('  Maxmemory       : ' . ($x['maxmemory_human'] ?? ($x['maxmemory'] ? $x['maxmemory'] : 'unlimited')));
            WP_CLI::log('  Eviction policy : ' . ($x['maxmemory_policy'] ?? '?'));
            WP_CLI::log('  Hit ratio       : ' . ($x['hit_ratio'] !== null ? $x['hit_ratio'] . '%' : 'n/a'));
            WP_CLI::log('  Evicted keys    : ' . ($x['evicted_keys'] ?? 0));
            WP_CLI::log('  Rejected conns  : ' . ($x['rejected_connections'] ?? 0));
            WP_CLI::log('  Fragmentation   : ' . ($x['mem_fragmentation_ratio'] ?? '?'));
        }

        $flags = $r['flags'] ?? [];
        if (empty($flags)) {
            WP_CLI::success('No object-cache health problems detected.');
            return;
        }

        WP_CLI::log('--- Flags (' . count($flags) . ') ---');
        $rows = [];
        foreach ($flags as $f) {
            $rows[] = [
                'severity'       => strtoupper((string) ($f['severity'] ?? '')),
                'code'           => (string) ($f['code'] ?? ''),
                'message'        => (string) ($f['message'] ?? ''),
            ];
        }
        WP_CLI\Utils\format_items($format === 'table' ? 'table' : $format, $rows, ['severity', 'code', 'message']);
        WP_CLI::log('');
        foreach ($flags as $f) {
            WP_CLI::log('• [' . strtoupper((string) ($f['severity'] ?? '')) . '] ' . (string) ($f['code'] ?? ''));
            WP_CLI::log('  ' . (string) ($f['recommendation'] ?? ''));
        }
    }
}

if (defined('WP_CLI') && WP_CLI) {
    WP_CLI::add_command('prorank object-cache', 'ProRank\\SEO\\CLI\\ObjectCacheCommand');
}
