<?php

namespace App\Console\Commands;

use App\Campaigns\CampaignPerformanceAdopsMonitor;
use Illuminate\Console\Attributes\Description;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;
use Symfony\Component\Console\Helper\ProgressBar;

#[Signature('campaigns:monitor-adops {--platform=meta : meta, google, or linkedin} {--campaign= : platform campaign id} {--limit= : max campaigns, 0 for all} {--hourly : use hourly windows (default)} {--daily : use daily windows} {--quiet-progress : hide per-campaign lines (progress bar only)}')]
#[Description('Analyse Whale adops tables and write performance verdicts (Meta first; no platform API calls)')]
class MonitorAdopsPerformanceCommand extends Command
{
    private ?ProgressBar $bar = null;

    public function handle(CampaignPerformanceAdopsMonitor $monitor): int
    {
        $hourly = ! (bool) $this->option('daily');
        $runType = $hourly ? 'hourly' : 'daily';
        $platform = $this->option('platform') !== null && $this->option('platform') !== ''
            ? (string) $this->option('platform')
            : 'meta';
        $campaign = $this->option('campaign') !== null && $this->option('campaign') !== ''
            ? (string) $this->option('campaign')
            : null;
        $limit = $this->option('limit');
        $limit = is_numeric($limit) ? (int) $limit : null;
        $quietLines = (bool) $this->option('quiet-progress');

        $this->components->info(sprintf('Adops monitor (%s) — loading campaigns from Whale…', $runType));

        $result = $monitor->run($platform, $campaign, $limit, $runType, function (string $event, array $payload): void {
            $this->handleProgress($event, $payload);
        });

        $this->bar?->finish();
        $this->newLine(2);

        if ($result['skipped'] !== null) {
            $this->components->warn('Adops monitor skipped: '.$result['skipped']);

            return self::SUCCESS;
        }

        $this->components->info(sprintf(
            'Finished: %d campaign(s) attempted, %d mapped, %d failed.',
            $result['attempted'],
            $result['mapped'],
            $result['failed'],
        ));

        if (! $quietLines && $result['results'] !== []) {
            $this->newLine();
            $this->line('  <fg=gray>Verdict summary</>');
            foreach ($result['results'] as $row) {
                if ($row['success']) {
                    $this->line(sprintf(
                        '  <fg=green>✓</> %s · %s — <comment>%s</comment>',
                        $row['campaign_id'],
                        $row['verdict_label'] ?? $row['verdict'],
                        $this->truncateReason((string) $row['reason']),
                    ));
                } else {
                    $this->line(sprintf(
                        '  <fg=red>✗</> %s — %s',
                        $row['campaign_id'],
                        $row['error'] ?? 'failed',
                    ));
                }
            }
        }

        return self::SUCCESS;
    }

    /**
     * @param  array<string, mixed>  $payload
     */
    private function handleProgress(string $event, array $payload): void
    {
        if ($event === 'discovering') {
            return;
        }

        if ($event === 'discovered') {
            $total = (int) ($payload['total'] ?? 0);

            if ($total === 0) {
                $this->components->warn('No campaigns found for this platform/filter.');

                return;
            }

            $this->components->info(sprintf('Processing %d campaign(s)…', $total));
            $this->bar = $this->output->createProgressBar($total);
            $this->bar->setFormat(' %current%/%max% [%bar%] %percent:3s%% — %message%');
            $this->bar->setMessage('starting');
            $this->bar->start();

            return;
        }

        if ($event === 'campaign_start') {
            $name = (string) ($payload['name'] ?? '');
            $id = (string) ($payload['campaign_id'] ?? '');
            $this->bar?->setMessage($id.($name !== '' && $name !== 'Campaign '.$id ? ' · '.$name : ''));

            return;
        }

        if ($event === 'campaign_done') {
            $this->bar?->advance();

            if (! (bool) $this->option('quiet-progress') && (bool) ($payload['success'] ?? false)) {
                $this->bar?->clear();
                $this->line(sprintf(
                    '  <fg=green>✓</> %s · <info>%s</info> — %s',
                    $payload['campaign_id'] ?? '',
                    $payload['verdict_label'] ?? $payload['verdict'] ?? '',
                    $this->truncateReason((string) ($payload['reason'] ?? '')),
                ));
                $this->bar?->display();
            }
        }
    }

    private function truncateReason(string $reason): string
    {
        $reason = trim(preg_replace('/\s+/', ' ', $reason) ?? $reason);

        if (mb_strlen($reason) <= 120) {
            return $reason;
        }

        return mb_substr($reason, 0, 117).'…';
    }
}
