<?php

namespace App\Console\Commands;

use App\Models\Setting;
use App\Services\PaymentHealthReportService;
use App\Support\PaymentLogger;
use Illuminate\Console\Command;

class GeneratePaymentHealthReport extends Command
{
    protected $signature = 'payments:health-report
                            {--date= : Date in Y-m-d format (default: today)}
                            {--threshold= : Hard-fail alert threshold percentage}';

    protected $description = 'Generate daily payment health summary and alert on hard-fail spikes';

    public function __construct(
        private readonly PaymentHealthReportService $paymentHealthReportService
    ) {
        parent::__construct();
    }

    public function handle(): int
    {
        $targetDate = $this->option('date') ?: now()->toDateString();
        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', (string) $targetDate)) {
            $this->error('Invalid --date format. Use Y-m-d, for example 2026-03-01.');
            return self::FAILURE;
        }

        $threshold = $this->resolveThreshold();
        $stats = $this->paymentHealthReportService->summarizeDate($targetDate);
        if (empty($stats['log_exists'])) {
            $this->warn("No payment log found for {$targetDate}");
            return self::SUCCESS;
        }
        $hardFailRate = (float) ($stats['hard_fail_rate_pct'] ?? 0.0);
        $backendFailureRate = (float) ($stats['backend_failure_rate_pct'] ?? 0.0);

        $this->table(
            ['Metric', 'Value'],
            [
                ['date', $targetDate],
                ['captured_events', $stats['captured_events']],
                ['failed_events', $stats['failed_events']],
                ['customer_decline_events', $stats['customer_decline_events']],
                ['gateway_timeout_events', $stats['gateway_timeout_events']],
                ['verify_stock_error_events', $stats['verify_stock_error_events']],
                ['backend_state_race_events', $stats['backend_state_race_events']],
                ['webhook_order_not_found_events', $stats['webhook_order_not_found_events']],
                ['backend_failure_events', $stats['backend_failure_events']],
                ['already_paid_verification_skips', $stats['already_paid_verification_skips']],
                ['recovered_non_payable_events', $stats['recovered_non_payable_events']],
                ['unique_orders_attempted', $stats['attempted_unique_orders']],
                ['unique_orders_captured', $stats['captured_unique_orders']],
                ['unique_orders_failed', $stats['failed_unique_orders']],
                ['unique_orders_hard_failed', $stats['hard_fail_unique_orders']],
                ['hard_fail_rate_pct', $hardFailRate],
                ['backend_failure_rate_pct', $backendFailureRate],
                ['alert_threshold_pct', $threshold],
            ]
        );

        if ($stats['top_failure_reasons']) {
            $this->newLine();
            $this->info('Top failure reasons:');
            foreach ($stats['top_failure_reasons'] as $reason => $count) {
                $this->line("- {$count} :: {$reason}");
            }
        }

        PaymentLogger::info('Payment health report generated', [
            'report_date' => $targetDate,
            'captured_events' => $stats['captured_events'],
            'failed_events' => $stats['failed_events'],
            'customer_decline_events' => $stats['customer_decline_events'],
            'gateway_timeout_events' => $stats['gateway_timeout_events'],
            'verify_stock_error_events' => $stats['verify_stock_error_events'],
            'backend_state_race_events' => $stats['backend_state_race_events'],
            'webhook_order_not_found_events' => $stats['webhook_order_not_found_events'],
            'backend_failure_events' => $stats['backend_failure_events'],
            'already_paid_verification_skips' => $stats['already_paid_verification_skips'],
            'recovered_non_payable_events' => $stats['recovered_non_payable_events'],
            'unique_orders_attempted' => $stats['attempted_unique_orders'],
            'unique_orders_hard_failed' => $stats['hard_fail_unique_orders'],
            'hard_fail_rate_pct' => $hardFailRate,
            'backend_failure_rate_pct' => $backendFailureRate,
            'alert_threshold_pct' => $threshold,
            'top_failure_reasons' => $stats['top_failure_reasons'],
        ]);

        if ($stats['attempted_unique_orders'] > 0 && $backendFailureRate >= $threshold) {
            PaymentLogger::warning('Payment backend-failure rate alert threshold breached', [
                'report_date' => $targetDate,
                'hard_fail_rate_pct' => $hardFailRate,
                'backend_failure_rate_pct' => $backendFailureRate,
                'alert_threshold_pct' => $threshold,
                'attempted_unique_orders' => $stats['attempted_unique_orders'],
                'backend_failure_events' => $stats['backend_failure_events'],
                'hard_fail_unique_orders' => $stats['hard_fail_unique_orders'],
                'top_failure_reasons' => $stats['top_failure_reasons'],
            ]);

            $this->warn("ALERT: backend-failure rate {$backendFailureRate}% is above threshold {$threshold}%");
        } else {
            $this->info("Backend-failure rate {$backendFailureRate}% is within threshold {$threshold}%");
        }

        return self::SUCCESS;
    }

    private function resolveThreshold(): float
    {
        $optionThreshold = $this->option('threshold');
        if ($optionThreshold !== null && $optionThreshold !== '') {
            return max(0.0, (float) $optionThreshold);
        }

        $settingThreshold = Setting::get('payment_hard_fail_alert_threshold', '20');
        return max(0.0, (float) $settingThreshold);
    }
}
