<?php

namespace App\Filament\Widgets;

use App\Models\ApiLog;
use App\Models\PricePrediction;
use App\Models\Search;
use App\Models\Station;
use App\Models\User;
use Carbon\Carbon;
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;

class StatsOverviewWidget extends BaseWidget
{
    protected ?string $pollingInterval = '30s';

    protected function getStats(): array
    {
        return [
            $this->usersStat(),
            $this->searchesStat(),
            $this->stationsStat(),
            $this->oilPredictionStat(),
            $this->apiErrorsStat(),
        ];
    }

    private function usersStat(): Stat
    {
        return Stat::make('Total users', User::count())
            ->icon('heroicon-o-users')
            ->color('primary');
    }

    private function searchesStat(): Stat
    {
        return Stat::make('Total searches', Search::count())
            ->icon('heroicon-o-magnifying-glass')
            ->url(route('filament.admin.resources.searches.index'))
            ->color('primary');
    }

    private function stationsStat(): Stat
    {
        $count = Station::count();
        $lastSeen = Station::max('last_seen_at');
        $description = $lastSeen
            ? 'Last seen '.Carbon::parse($lastSeen)->diffForHumans()
            : 'No stations yet';

        return Stat::make('Stations in DB', number_format($count))
            ->description($description)
            ->url(route('filament.admin.resources.stations.index'))
            ->icon('heroicon-o-map-pin')
            ->color('success');
    }

    private function oilPredictionStat(): Stat
    {
        $prediction = PricePrediction::bestFirst()->latest('generated_at')->first();

        if ($prediction === null) {
            return Stat::make('Latest oil prediction', 'None')
                ->icon('heroicon-o-beaker')
                ->color('gray');
        }

        $ageHours = $prediction->generated_at->diffInHours(now());
        $color = $ageHours > 24 ? 'warning' : 'success';
        $value = $prediction->direction->label().' · '.$prediction->confidence.'%';

        return Stat::make('Latest oil prediction', $value)
            ->description('Generated '.$prediction->generated_at->diffForHumans())
            ->url(route('filament.admin.resources.oil-predictions.index'))
            ->icon('heroicon-o-beaker')
            ->color($color);
    }

    private function apiErrorsStat(): Stat
    {
        $errors = ApiLog::where('created_at', '>=', now()->subDay())
            ->where(fn ($q) => $q->where('status_code', '>=', 400)
                ->orWhereNull('status_code')
                ->orWhereNotNull('error'))
            ->count();

        $color = $errors > 0 ? 'danger' : 'success';

        return Stat::make('API errors (24h)', $errors)
            ->icon('heroicon-o-exclamation-triangle')
            ->url(route('filament.admin.resources.api-logs.index'))
            ->color($color);
    }
}
