<?php

namespace App\Services\Operations;

use App\Models\AlertLog;
use App\Models\ApiRequestLog;
use App\Models\Client;
use App\Models\ClientHealthScore;
use App\Models\EmailLog;
use App\Models\GeneratedReport;
use App\Models\OperationTask;
use App\Models\PlatformConnection;
use App\Models\ReportSchedule;
use Carbon\CarbonInterface;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Schema;

class ClientHealthScoreService
{
    public function dashboard(array $filters = []): array
    {
        $clients = $this->filteredClients($filters)
            ->with(['platformConnections', 'generatedReports', 'reportSchedules', 'alertLogs'])
            ->orderBy('company_name')
            ->get();

        $cards = $clients->map(fn (Client $client) => $this->calculate($client));

        if (! empty($filters['health_status'])) {
            $cards = $cards->filter(fn (array $card) => $card['status'] === $filters['health_status'])->values();
        }

        if (! empty($filters['min_score'])) {
            $cards = $cards->filter(fn (array $card) => $card['score'] >= (int) $filters['min_score'])->values();
        }

        if (! empty($filters['max_score'])) {
            $cards = $cards->filter(fn (array $card) => $card['score'] <= (int) $filters['max_score'])->values();
        }

        return [
            'summary' => $this->summary($cards),
            'clients' => $cards,
            'risk_clients' => $cards->whereIn('status', ['critical', 'risk'])->sortBy('score')->take(12)->values(),
            'top_clients' => $cards->sortByDesc('score')->take(8)->values(),
            'recent_scores' => $this->recentScores(),
        ];
    }

    public function calculate(Client $client): array
    {
        $client->loadMissing(['platformConnections', 'generatedReports', 'reportSchedules', 'alertLogs']);

        $api = $this->apiScore($client);
        $quality = $this->dataQualityScore($client);
        $report = $this->reportScore($client);
        $mail = $this->mailScore($client);
        $alert = $this->alertScore($client);
        $task = $this->taskScore($client);
        $onboarding = $this->onboardingScore($client);

        $weights = [
            'api' => 20,
            'data_quality' => 20,
            'report' => 15,
            'mail' => 10,
            'alert' => 15,
            'task' => 10,
            'onboarding' => 10,
        ];

        $score = (int) round(
            ($api['score'] * $weights['api']
            + $quality['score'] * $weights['data_quality']
            + $report['score'] * $weights['report']
            + $mail['score'] * $weights['mail']
            + $alert['score'] * $weights['alert']
            + $task['score'] * $weights['task']
            + $onboarding['score'] * $weights['onboarding']) / array_sum($weights)
        );

        $breakdown = [
            'api' => $api,
            'data_quality' => $quality,
            'report' => $report,
            'mail' => $mail,
            'alert' => $alert,
            'task' => $task,
            'onboarding' => $onboarding,
        ];

        $riskItems = collect($breakdown)
            ->flatMap(fn (array $item, string $key) => collect($item['risks'] ?? [])->map(fn (array $risk) => $risk + ['group' => $key]))
            ->sortBy(fn (array $risk) => $this->priorityOrder($risk['priority'] ?? 'medium'))
            ->values()
            ->all();

        $recommendations = $this->recommendations($breakdown, $riskItems);
        $status = $this->statusFromScore($score, $riskItems);

        return [
            'client' => $client,
            'score' => $score,
            'status' => $status,
            'status_label' => $this->statusLabel($status),
            'badge_class' => $this->badgeClass($status),
            'readiness' => $this->readinessFromStatus($status),
            'breakdown' => $breakdown,
            'risk_items' => $riskItems,
            'recommendations' => $recommendations,
            'last_snapshot' => $this->lastSnapshot($client),
            'calculated_at' => now(),
        ];
    }

    public function calculateAndStore(Client $client, ?CarbonInterface $date = null): ClientHealthScore
    {
        $date = $date ?: now();
        $card = $this->calculate($client);

        return ClientHealthScore::updateOrCreate(
            [
                'client_id' => $client->id,
                'score_date' => $date->toDateString(),
            ],
            [
                'score' => $card['score'],
                'status' => $card['status'],
                'readiness' => $card['readiness'],
                'api_score' => $card['breakdown']['api']['score'],
                'data_quality_score' => $card['breakdown']['data_quality']['score'],
                'report_score' => $card['breakdown']['report']['score'],
                'mail_score' => $card['breakdown']['mail']['score'],
                'alert_score' => $card['breakdown']['alert']['score'],
                'task_score' => $card['breakdown']['task']['score'],
                'onboarding_score' => $card['breakdown']['onboarding']['score'],
                'breakdown' => $card['breakdown'],
                'risk_items' => $card['risk_items'],
                'recommendations' => $card['recommendations'],
                'calculated_at' => now(),
            ]
        );
    }

    public function storeAll(array $filters = []): array
    {
        $clients = $this->filteredClients($filters)->orderBy('company_name')->get();
        $stored = 0;

        foreach ($clients as $client) {
            $this->calculateAndStore($client);
            $stored++;
        }

        return [
            'stored' => $stored,
            'message' => $stored.' müşteri için sağlık skoru güncellendi.',
        ];
    }

    public function clientDetail(Client $client): array
    {
        $card = $this->calculate($client);

        return [
            'card' => $card,
            'history' => $this->history($client),
            'platforms' => $this->platformBreakdown($client),
            'mail_failures' => $this->mailFailures($client),
            'api_errors' => $this->apiErrors($client),
            'open_tasks' => $this->openTasks($client),
            'open_alerts' => $this->openAlerts($client),
        ];
    }

    protected function apiScore(Client $client): array
    {
        $connections = $client->platformConnections instanceof Collection
            ? $client->platformConnections
            : $client->platformConnections()->get();

        $risks = [];

        if ($connections->isEmpty()) {
            return [
                'score' => 0,
                'label' => 'API bağlantısı yok',
                'risks' => [[
                    'title' => 'Müşteriye hiçbir API bağlantısı eklenmemiş',
                    'description' => 'Google Ads, Meta Ads, Search Console veya GA4 bağlantısı kurulmadan rapor üretimi eksik kalır.',
                    'priority' => 'critical',
                ]],
                'meta' => ['connections_total' => 0],
            ];
        }

        $active = $connections->filter(fn ($connection) => ($connection->status ?? null) === 'active')->count();
        $score = (int) round(($active / max(1, $connections->count())) * 100);

        foreach ($connections as $connection) {
            if (($connection->status ?? null) !== 'active') {
                $risks[] = [
                    'title' => $this->platformLabel($connection->platform).' bağlantısı aktif değil',
                    'description' => $connection->last_error ?: 'Bağlantı durumu aktif görünmüyor.',
                    'priority' => 'critical',
                    'url' => $this->connectionUrl($connection),
                ];
            }

            if (! empty($connection->last_error)) {
                $score -= 12;
                $risks[] = [
                    'title' => $this->platformLabel($connection->platform).' son hata kaydetmiş',
                    'description' => str($connection->last_error)->limit(160)->toString(),
                    'priority' => 'high',
                    'url' => $this->connectionUrl($connection),
                ];
            }

            if (! $connection->last_sync_at) {
                $score -= 8;
                $risks[] = [
                    'title' => $this->platformLabel($connection->platform).' henüz senkronize edilmemiş',
                    'description' => 'Bağlantı aktif olsa bile rapor için veri tabanı boş olabilir.',
                    'priority' => 'medium',
                    'url' => route('admin.sync.index', ['connection_id' => $connection->id]),
                ];
            }
        }

        $recentApiErrors = $this->safeCount(ApiRequestLog::class, fn ($query) => $query
            ->where('client_id', $client->id)
            ->whereNotNull('error_message')
            ->where('created_at', '>=', now()->subDays(3))
        );

        if ($recentApiErrors > 0) {
            $score -= min(30, $recentApiErrors * 6);
            $risks[] = [
                'title' => 'Son 3 günde API hatası var',
                'description' => $recentApiErrors.' API hatası loglandı. Token, izin veya limitler kontrol edilmeli.',
                'priority' => 'high',
                'url' => route('admin.system.logs'),
            ];
        }

        return [
            'score' => $this->clamp($score),
            'label' => $active.'/'.$connections->count().' aktif bağlantı',
            'risks' => $risks,
            'meta' => [
                'connections_total' => $connections->count(),
                'connections_active' => $active,
                'recent_api_errors' => $recentApiErrors,
            ],
        ];
    }

    protected function dataQualityScore(Client $client): array
    {
        $connections = $client->platformConnections instanceof Collection
            ? $client->platformConnections
            : $client->platformConnections()->get();

        if ($connections->isEmpty()) {
            return ['score' => 0, 'label' => 'Kalite verisi yok', 'risks' => [], 'meta' => []];
        }

        $scores = [];
        $risks = [];

        foreach ($connections as $connection) {
            $quality = data_get($connection->meta, 'last_quality_check');
            $score = is_array($quality) ? data_get($quality, 'score') : null;

            if ($score === null) {
                $scores[] = 55;
                $risks[] = [
                    'title' => $this->platformLabel($connection->platform).' için kalite kontrolü yapılmamış',
                    'description' => 'Snapshot sonrası veri kalite kontrolü çalıştırılmalı.',
                    'priority' => 'medium',
                    'url' => route('admin.sync.quality', ['connection_id' => $connection->id]),
                ];
                continue;
            }

            $scores[] = (int) $score;
            $status = data_get($quality, 'status');

            if ((int) $score < 70 || $status === 'problem') {
                $risks[] = [
                    'title' => $this->platformLabel($connection->platform).' kalite skoru düşük',
                    'description' => 'Son kalite skoru: '.$score.'. Eksik gün veya boş metrik olabilir.',
                    'priority' => ((int) $score < 50) ? 'high' : 'medium',
                    'url' => route('admin.sync.quality', ['connection_id' => $connection->id]),
                ];
            }
        }

        $average = count($scores) ? (int) round(collect($scores)->avg()) : 0;

        return [
            'score' => $this->clamp($average),
            'label' => 'Ortalama kalite: '.$average,
            'risks' => $risks,
            'meta' => ['average_quality' => $average],
        ];
    }

    protected function reportScore(Client $client): array
    {
        $risks = [];
        $score = 100;

        $lastReport = $this->safeFirst(GeneratedReport::class, fn ($query) => $query
            ->where('client_id', $client->id)
            ->latest('created_at')
        );

        $activeSchedules = $this->safeCount(ReportSchedule::class, fn ($query) => $query
            ->where('client_id', $client->id)
            ->where('is_active', true)
        );

        if (! $lastReport) {
            $score -= 55;
            $risks[] = [
                'title' => 'İlk rapor henüz oluşturulmamış',
                'description' => 'Müşterinin ilk rapor sihirbazı çalıştırılmalı.',
                'priority' => 'high',
                'url' => route('admin.first-report.show', $client),
            ];
        } elseif ($lastReport->created_at && $lastReport->created_at->lt(now()->subDays(14))) {
            $score -= 22;
            $risks[] = [
                'title' => 'Son rapor eski',
                'description' => 'Son rapor '.$lastReport->created_at->diffForHumans().' oluşturulmuş.',
                'priority' => 'medium',
                'url' => route('admin.reports.show', $lastReport),
            ];
        }

        if ($activeSchedules === 0) {
            $score -= 30;
            $risks[] = [
                'title' => 'Aktif otomatik rapor planı yok',
                'description' => 'Günlük, haftalık veya aylık rapor planı oluşturulmalı.',
                'priority' => 'medium',
                'url' => route('admin.report-schedules.create', ['client_id' => $client->id]),
            ];
        }

        $failedReports = $this->safeCount(GeneratedReport::class, fn ($query) => $query
            ->where('client_id', $client->id)
            ->whereIn('status', ['failed', 'error'])
            ->where('created_at', '>=', now()->subDays(30))
        );

        if ($failedReports > 0) {
            $score -= min(25, $failedReports * 8);
            $risks[] = [
                'title' => 'Başarısız rapor var',
                'description' => 'Son 30 günde '.$failedReports.' rapor hata durumunda.',
                'priority' => 'medium',
                'url' => route('admin.reports.archive', ['client_id' => $client->id]),
            ];
        }

        return [
            'score' => $this->clamp($score),
            'label' => $lastReport ? 'Son rapor: '.$lastReport->created_at?->format('d.m.Y H:i') : 'Rapor yok',
            'risks' => $risks,
            'meta' => [
                'active_schedules' => $activeSchedules,
                'failed_reports_30d' => $failedReports,
                'last_report_at' => $lastReport?->created_at?->toDateTimeString(),
            ],
        ];
    }

    protected function mailScore(Client $client): array
    {
        $score = 100;
        $risks = [];

        $failed7 = $this->safeCount(EmailLog::class, fn ($query) => $query
            ->where('client_id', $client->id)
            ->where('status', 'failed')
            ->where('created_at', '>=', now()->subDays(7))
        );

        if ($failed7 > 0) {
            $score -= min(60, $failed7 * 15);
            $risks[] = [
                'title' => 'Son 7 günde mail hatası var',
                'description' => $failed7.' mail gönderimi başarısız olmuş. SMTP ve alıcı adresleri kontrol edilmeli.',
                'priority' => $failed7 >= 3 ? 'high' : 'medium',
                'url' => route('admin.mail.logs', ['client_id' => $client->id]),
            ];
        }

        $lastMail = $this->safeFirst(EmailLog::class, fn ($query) => $query
            ->where('client_id', $client->id)
            ->latest('created_at')
        );

        if (! $lastMail) {
            $score -= 12;
        }

        return [
            'score' => $this->clamp($score),
            'label' => $failed7 > 0 ? $failed7.' başarısız mail' : 'Mail sorunu yok',
            'risks' => $risks,
            'meta' => [
                'failed_7d' => $failed7,
                'last_mail_at' => $lastMail?->created_at?->toDateTimeString(),
            ],
        ];
    }

    protected function alertScore(Client $client): array
    {
        $openAlerts = $this->openAlerts($client);
        $critical = $openAlerts->filter(fn ($alert) => in_array($alert->severity ?? null, ['critical', 'danger', 'high'], true))->count();
        $score = 100;
        $risks = [];

        if ($critical > 0) {
            $score -= min(70, $critical * 22);
            $risks[] = [
                'title' => 'Kritik uyarı var',
                'description' => $critical.' kritik/yüksek uyarı çözüm bekliyor.',
                'priority' => 'critical',
                'url' => route('admin.alert-logs.index', ['client_id' => $client->id]),
            ];
        }

        $normalOpen = max(0, $openAlerts->count() - $critical);
        if ($normalOpen > 0) {
            $score -= min(30, $normalOpen * 5);
            $risks[] = [
                'title' => 'Açık uyarılar var',
                'description' => $normalOpen.' uyarı takip edilmeli.',
                'priority' => 'medium',
                'url' => route('admin.alert-logs.index', ['client_id' => $client->id]),
            ];
        }

        return [
            'score' => $this->clamp($score),
            'label' => $openAlerts->count().' açık uyarı',
            'risks' => $risks,
            'meta' => [
                'open_alerts' => $openAlerts->count(),
                'critical_alerts' => $critical,
            ],
        ];
    }

    protected function taskScore(Client $client): array
    {
        if (! Schema::hasTable('operation_tasks')) {
            return ['score' => 80, 'label' => 'Görev tablosu yok', 'risks' => [], 'meta' => []];
        }

        $open = OperationTask::where('client_id', $client->id)->whereIn('status', ['open', 'in_progress', 'waiting']);
        $overdue = (clone $open)->whereNotNull('due_at')->where('due_at', '<', now()->startOfDay())->count();
        $critical = (clone $open)->where('priority', 'critical')->count();
        $totalOpen = (clone $open)->count();
        $score = 100 - min(35, $overdue * 12) - min(35, $critical * 15) - min(20, $totalOpen * 2);
        $risks = [];

        if ($critical > 0) {
            $risks[] = [
                'title' => 'Kritik operasyon görevi var',
                'description' => $critical.' kritik görev çözüm bekliyor.',
                'priority' => 'high',
                'url' => route('admin.task-board.index', ['client_id' => $client->id, 'priority' => 'critical']),
            ];
        }

        if ($overdue > 0) {
            $risks[] = [
                'title' => 'Geciken görev var',
                'description' => $overdue.' görev termin tarihini geçmiş.',
                'priority' => 'high',
                'url' => route('admin.task-board.index', ['client_id' => $client->id, 'due' => 'overdue']),
            ];
        }

        return [
            'score' => $this->clamp($score),
            'label' => $totalOpen.' açık görev',
            'risks' => $risks,
            'meta' => [
                'open_tasks' => $totalOpen,
                'critical_tasks' => $critical,
                'overdue_tasks' => $overdue,
            ],
        ];
    }

    protected function onboardingScore(Client $client): array
    {
        if (method_exists($client, 'onboardingIsComplete') && $client->onboardingIsComplete()) {
            return ['score' => 100, 'label' => 'Onboarding tamamlandı', 'risks' => [], 'meta' => []];
        }

        if (($client->onboarding_status ?? null) === 'in_progress') {
            return [
                'score' => 60,
                'label' => 'Onboarding devam ediyor',
                'risks' => [[
                    'title' => 'Onboarding tamamlanmamış',
                    'description' => 'Kurulum akışı tamamlanmadan müşteri raporlaması eksik kalabilir.',
                    'priority' => 'medium',
                    'url' => route('admin.onboarding.summary', $client),
                ]],
                'meta' => ['status' => $client->onboarding_status],
            ];
        }

        return [
            'score' => 40,
            'label' => 'Onboarding başlamadı',
            'risks' => [[
                'title' => 'Onboarding başlatılmamış',
                'description' => 'Müşteri kurulum sihirbazı çalıştırılmalı.',
                'priority' => 'medium',
                'url' => route('admin.onboarding.start', ['client_id' => $client->id]),
            ]],
            'meta' => ['status' => $client->onboarding_status],
        ];
    }

    protected function recommendations(array $breakdown, array $riskItems): array
    {
        $recommendations = [];

        foreach ($riskItems as $risk) {
            $group = $risk['group'] ?? null;
            $priority = $risk['priority'] ?? 'medium';

            $recommendations[] = match ($group) {
                'api' => 'API bağlantısını test edip token/izin durumunu kontrol et.',
                'data_quality' => 'Veri kalite kontrolünü tekrar çalıştır; eksik gün varsa snapshot senkronu yap.',
                'report' => 'İlk rapor veya güncel dönem raporunu üretip rapor arşivini kontrol et.',
                'mail' => 'SMTP ayarlarını ve rapor alıcı e-posta adreslerini kontrol et.',
                'alert' => $priority === 'critical' ? 'Kritik uyarıları önce çöz; gerekiyorsa müşteriye ara bilgi ver.' : 'Açık uyarıları operasyon listesine al.',
                'task' => 'Geciken/kritik görevleri görev panosunda önceliklendir.',
                'onboarding' => 'Onboarding sihirbazını tamamla ve ilk rapor akışına geç.',
                default => 'Müşteri detayını kontrol et.',
            };
        }

        return collect($recommendations)->unique()->take(8)->values()->all();
    }

    protected function summary(Collection $cards): array
    {
        $avg = $cards->count() ? (int) round($cards->avg('score')) : 0;

        return [
            'clients_total' => $cards->count(),
            'average_score' => $avg,
            'excellent' => $cards->where('status', 'excellent')->count(),
            'healthy' => $cards->where('status', 'healthy')->count(),
            'watch' => $cards->where('status', 'watch')->count(),
            'risk' => $cards->where('status', 'risk')->count(),
            'critical' => $cards->where('status', 'critical')->count(),
            'needs_attention' => $cards->whereIn('status', ['watch', 'risk', 'critical'])->count(),
            'lowest_score' => $cards->min('score') ?? 0,
            'highest_score' => $cards->max('score') ?? 0,
        ];
    }

    protected function filteredClients(array $filters): Builder
    {
        return Client::query()
            ->when(! empty($filters['q']), function ($query) use ($filters) {
                $term = '%'.trim($filters['q']).'%';
                $query->where(function ($sub) use ($term) {
                    $sub->where('company_name', 'like', $term)
                        ->orWhere('contact_person', 'like', $term)
                        ->orWhere('email', 'like', $term)
                        ->orWhere('website', 'like', $term);
                });
            })
            ->when(! empty($filters['client_id']), fn ($query) => $query->where('id', $filters['client_id']))
            ->when(! empty($filters['status']), fn ($query) => $query->where('status', $filters['status']))
            ->when(! empty($filters['platform']), function ($query) use ($filters) {
                $query->whereHas('platformConnections', fn ($sub) => $sub->where('platform', $filters['platform']));
            });
    }

    protected function history(Client $client): Collection
    {
        if (! Schema::hasTable('client_health_scores')) {
            return collect();
        }

        return ClientHealthScore::where('client_id', $client->id)
            ->orderByDesc('score_date')
            ->limit(30)
            ->get();
    }

    protected function recentScores(): Collection
    {
        if (! Schema::hasTable('client_health_scores')) {
            return collect();
        }

        return ClientHealthScore::with('client')
            ->latest('calculated_at')
            ->limit(12)
            ->get();
    }

    protected function lastSnapshot(Client $client): ?ClientHealthScore
    {
        if (! Schema::hasTable('client_health_scores')) {
            return null;
        }

        return ClientHealthScore::where('client_id', $client->id)->latest('score_date')->first();
    }

    protected function platformBreakdown(Client $client): Collection
    {
        $connections = $client->platformConnections instanceof Collection
            ? $client->platformConnections
            : $client->platformConnections()->get();

        return $connections->map(fn ($connection) => [
            'connection' => $connection,
            'platform_label' => $this->platformLabel($connection->platform),
            'status' => $connection->status,
            'last_sync_at' => $connection->last_sync_at,
            'quality_score' => data_get($connection->meta, 'last_quality_check.score'),
            'last_error' => $connection->last_error,
            'url' => $this->connectionUrl($connection),
        ]);
    }

    protected function mailFailures(Client $client): Collection
    {
        if (! Schema::hasTable('email_logs')) {
            return collect();
        }

        return EmailLog::where('client_id', $client->id)->where('status', 'failed')->latest()->limit(10)->get();
    }

    protected function apiErrors(Client $client): Collection
    {
        if (! Schema::hasTable('api_request_logs')) {
            return collect();
        }

        return ApiRequestLog::where('client_id', $client->id)->whereNotNull('error_message')->latest()->limit(10)->get();
    }

    protected function openTasks(Client $client): Collection
    {
        if (! Schema::hasTable('operation_tasks')) {
            return collect();
        }

        return OperationTask::where('client_id', $client->id)->whereIn('status', ['open', 'in_progress', 'waiting'])->latest()->limit(12)->get();
    }

    protected function openAlerts(Client $client): Collection
    {
        if (! Schema::hasTable('alert_logs')) {
            return collect();
        }

        return AlertLog::where('client_id', $client->id)
            ->where(function ($query) {
                $query->whereNull('resolved_at');
                if (Schema::hasColumn('alert_logs', 'status')) {
                    $query->where('status', '!=', 'resolved');
                }
            })
            ->latest('triggered_at')
            ->latest()
            ->get();
    }

    protected function safeCount(string $modelClass, callable $callback): int
    {
        try {
            $instance = new $modelClass();
            if (! Schema::hasTable($instance->getTable())) {
                return 0;
            }

            $query = $modelClass::query();
            $callback($query);

            return (int) $query->count();
        } catch (\Throwable) {
            return 0;
        }
    }

    protected function safeFirst(string $modelClass, callable $callback)
    {
        try {
            $instance = new $modelClass();
            if (! Schema::hasTable($instance->getTable())) {
                return null;
            }

            $query = $modelClass::query();
            $callback($query);

            return $query->first();
        } catch (\Throwable) {
            return null;
        }
    }

    protected function statusFromScore(int $score, array $riskItems): string
    {
        $hasCritical = collect($riskItems)->contains(fn (array $risk) => ($risk['priority'] ?? null) === 'critical');

        if ($hasCritical || $score < 45) {
            return 'critical';
        }

        if ($score < 65) {
            return 'risk';
        }

        if ($score < 80) {
            return 'watch';
        }

        if ($score < 92) {
            return 'healthy';
        }

        return 'excellent';
    }

    protected function readinessFromStatus(string $status): string
    {
        return match ($status) {
            'excellent', 'healthy' => 'ready',
            'watch' => 'warning',
            default => 'critical',
        };
    }

    protected function statusLabel(string $status): string
    {
        return match ($status) {
            'excellent' => 'Çok İyi',
            'healthy' => 'Sağlıklı',
            'watch' => 'Takip Gerekli',
            'risk' => 'Riskli',
            'critical' => 'Kritik',
            default => ucfirst($status),
        };
    }

    protected function badgeClass(string $status): string
    {
        return match ($status) {
            'excellent' => 'badge-success',
            'healthy' => 'badge-info',
            'watch' => 'badge-warning',
            'risk' => 'badge-danger',
            'critical' => 'badge-dark',
            default => 'badge-secondary',
        };
    }

    protected function priorityOrder(string $priority): int
    {
        return match ($priority) {
            'critical' => 1,
            'high' => 2,
            'medium' => 3,
            'low' => 4,
            default => 5,
        };
    }

    protected function platformLabel(?string $platform): string
    {
        return match ($platform) {
            'google_ads' => 'Google Ads',
            'meta_ads' => 'Meta Ads',
            'search_console' => 'Search Console',
            'ga4' => 'GA4',
            default => ucfirst(str_replace('_', ' ', (string) $platform)),
        };
    }

    protected function connectionUrl(PlatformConnection $connection): ?string
    {
        return match ($connection->platform) {
            'google_ads' => route('admin.accounts.google-ads.show', $connection),
            'meta_ads' => route('admin.accounts.meta-ads.show', $connection),
            'search_console' => route('admin.accounts.search-console.show', $connection),
            'ga4' => route('admin.accounts.ga4.show', $connection),
            default => null,
        };
    }

    protected function clamp(int|float $score): int
    {
        return (int) max(0, min(100, round($score)));
    }
}
