<?php

namespace App\Filament\Pages;

use App\Models\ImportedJob;
use App\Models\JobSource;
use App\Models\JobSourceSyncLog;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Support\Enums\Width;
use Filament\Support\Icons\Heroicon;
use Illuminate\Support\Facades\Artisan;

class JobSourceHealth extends Page
{
    protected static string|BackedEnum|null $navigationIcon = Heroicon::Link;

    protected static ?string $navigationLabel = 'Source Health';

    protected static string|\UnitEnum|null $navigationGroup = 'Jobs';

    protected static ?int $navigationSort = 15;

    protected string $view = 'filament.pages.job-source-health';

    protected Width|string|null $maxContentWidth = Width::Full;

    /**
     * @return array<int, Action>
     */
    protected function getHeaderActions(): array
    {
        return [
            Action::make('queueSync')
                ->label('Queue active source sync')
                ->icon(Heroicon::ArrowPath)
                ->requiresConfirmation()
                ->action(function (): void {
                    Artisan::call('jobs:sync-sources');

                    Notification::make()
                        ->success()
                        ->title('Job source sync queued')
                        ->body(trim(Artisan::output()) ?: 'Active sources were queued.')
                        ->send();
                }),
        ];
    }

    /**
     * @return array<string, mixed>
     */
    protected function getViewData(): array
    {
        $sources = JobSource::query()
            ->withCount([
                'importedJobs',
                'importedJobs as active_jobs_count' => fn ($query) => $query->active(),
            ])
            ->with(['syncLogs' => fn ($query) => $query->latest('finished_at')->limit(3)])
            ->orderByDesc('is_active')
            ->orderBy('name')
            ->get();

        $failedSources = $sources->filter(fn (JobSource $source): bool => $source->last_failed_at !== null
            && ($source->last_synced_at === null || $source->last_failed_at->gt($source->last_synced_at)));
        $staleSources = $sources->filter(fn (JobSource $source): bool => $source->is_active
            && $source->isAutomaticallySyncable()
            && ($source->last_synced_at === null || $source->last_synced_at->lt(now()->subDay())));

        return [
            'summary' => [
                ['label' => 'Total sources', 'value' => $sources->count(), 'tone' => 'slate'],
                ['label' => 'Active sources', 'value' => $sources->where('is_active', true)->count(), 'tone' => 'teal'],
                ['label' => 'Failed sources', 'value' => $failedSources->count(), 'tone' => 'rose'],
                ['label' => 'Stale sources', 'value' => $staleSources->count(), 'tone' => 'amber'],
                ['label' => 'Active jobs', 'value' => ImportedJob::query()->active()->count(), 'tone' => 'sky'],
            ],
            'sources' => $sources,
            'recentSyncLogs' => JobSourceSyncLog::query()
                ->with('source')
                ->latest('finished_at')
                ->limit(12)
                ->get(),
        ];
    }
}
