<?php

namespace App\Nexus\Console\Commands;

use App\Nexus\Engine\NexusConfig;
use App\Nexus\Engine\BotGovernor;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

/**
 * Runs the AI bot profit governance cycle.
 * Every 5 minutes via Laravel scheduler.
 *
 * No emergency pause check -- bot governance is not a trading action.
 * It adjusts trade ranges for future trades, not executing trades itself.
 * BotGovernor::runGovernanceCycle() has its own isNexusActive() check.
 *
 * Phase 8 additions:
 *   --dry-run flag: calculates governance for all active bots without
 *   writing anything. Outputs detailed table of what WOULD happen.
 *   Works even when nexus_status = inactive.
 *
 * Usage:
 *   php artisan nexus:bot-governor              (normal mode, requires NEXUS active)
 *   php artisan nexus:bot-governor --dry-run    (test mode, works while inactive)
 */
class NexusBotGovernorCommand extends Command
{
    protected $signature = 'nexus:bot-governor {--dry-run : Calculate governance without writing}';
    protected $description = 'NEXUS: Run AI bot profit governance cycle';

    public function handle(): void
    {
        $dryRun = $this->option('dry-run');

        // Normal mode: respect NEXUS active check
        if (!$dryRun && !NexusConfig::isNexusActive()) return;

        $governor = new BotGovernor();
        $result = $governor->runGovernanceCycle($dryRun);

        if ($dryRun) {
            $this->outputDryRunResults($result);
            return;
        }

        // Normal mode output
        if ($result['governed'] > 0 || $result['errors'] > 0) {
            $this->info("Governed: {$result['governed']} | Skipped: {$result['skipped']} | Errors: {$result['errors']}");
            Log::info('[NEXUS] bot-governor complete', $result);
        }
    }

    /**
     * Format and output dry-run results to the console.
     */
    private function outputDryRunResults(array $result): void
    {
        $this->newLine();
        $this->info('=== NEXUS BotGovernor Dry Run ===');
        $this->info("Governed: {$result['governed']} | Skipped: {$result['skipped']} | Errors: {$result['errors']}");
        $this->newLine();

        if (empty($result['details'])) {
            $this->warn('No active bots with NEXUS governance configured.');
            return;
        }

        // Group by plan for readability
        $grouped = [];
        foreach ($result['details'] as $detail) {
            if (isset($detail['error'])) {
                $this->error("Bot {$detail['bot_id']}: {$detail['error']}");
                continue;
            }
            $plan = $detail['plan'] ?? 'Unknown';
            $grouped[$plan][] = $detail;
        }

        foreach ($grouped as $planName => $bots) {
            $this->newLine();
            $this->info("--- {$planName} (" . count($bots) . " bots) ---");

            foreach ($bots as $d) {
                $this->line(sprintf(
                    '  Bot #%d | Capital: $%s | Profit: $%s (%s%%) | Target: %s%% monthly',
                    $d['bot_id'],
                    number_format($d['capital'], 2),
                    number_format($d['current_profit'], 2),
                    $d['current_profit_pct'],
                    $d['target_monthly_pct']
                ));
                $this->line(sprintf(
                    '    Expected by now: $%s | Actual: $%s | Drift: $%s | Status: %s',
                    number_format($d['expected_by_now'], 2),
                    number_format($d['current_profit'], 2),
                    number_format($d['drift'], 2),
                    $d['track_status']
                ));
                $this->line(sprintf(
                    '    Days: %d elapsed / %d remaining | Daily target: $%s',
                    $d['days_elapsed'],
                    $d['days_remaining'],
                    number_format($d['daily_target'], 4)
                ));
                $this->line(sprintf(
                    '    Trade range: %s%% - %s%% (current: %s%% - %s%%)',
                    $d['trade_range_min'],
                    $d['trade_range_max'],
                    $d['current_trade_min'],
                    $d['current_trade_max']
                ));
                $this->line(sprintf(
                    '    Capital ratio: %s (global log) | Base success: %s%% | Final: %s%% success / %s%% failure',
                    $d['global_capital_ratio'],
                    $d['capital_base_success'],
                    $d['success_rate'],
                    $d['failure_rate']
                ));
            }

            // Plan summary
            $totalCapital = array_sum(array_column($bots, 'capital'));
            $totalProfit = array_sum(array_column($bots, 'current_profit'));
            $avgFailure = count($bots) > 0
                ? array_sum(array_column($bots, 'failure_rate')) / count($bots)
                : 0;
            $trackCounts = array_count_values(array_column($bots, 'track_status'));

            $this->newLine();
            $this->line(sprintf(
                '  PLAN SUMMARY: %d bots | $%s capital | $%s profit | Avg failure: %s%%',
                count($bots),
                number_format($totalCapital, 2),
                number_format($totalProfit, 2),
                round($avgFailure, 2)
            ));
            $this->line(sprintf(
                '  Track: %d ON_TRACK | %d HOT | %d COLD',
                $trackCounts['ON_TRACK'] ?? 0,
                $trackCounts['HOT'] ?? 0,
                $trackCounts['COLD'] ?? 0
            ));
        }

        $this->newLine();
        $this->info('=== Dry run complete. No data was written. ===');
    }
}
