<?php

namespace App\Filament\Widgets;

use App\Models\AssessmentAttempt;
use App\Models\Consultation;
use App\Models\Enrollment;
use App\Models\Guide;
use App\Models\Lead;
use App\Models\ToolResult;
use App\Models\User;
use Filament\Widgets\StatsOverviewWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;

class MoneywiseStats extends StatsOverviewWidget
{
    protected static ?int $sort = -5;

    protected static bool $isLazy = false;

    protected ?string $heading = 'At a glance';

    /** Count of rows created in the last 7 days. */
    private function thisWeek(string $model, string $column = 'created_at'): int
    {
        return $model::query()->where($column, '>=', now()->subDays(7))->count();
    }

    /** Percentage change of the last 7 days vs the previous 7 days. */
    private function trend(string $model, string $column = 'created_at'): array
    {
        $current = $model::query()->where($column, '>=', now()->subDays(7))->count();
        $previous = $model::query()
            ->whereBetween($column, [now()->subDays(14), now()->subDays(7)])
            ->count();

        if ($previous === 0) {
            return [$current > 0 ? 100 : 0, $current >= $previous];
        }

        return [(int) round((($current - $previous) / $previous) * 100), $current >= $previous];
    }

    /** Daily counts for the last 7 days, feeds the stat sparkline. */
    private function spark(string $model, string $column = 'created_at'): array
    {
        $rows = $model::query()
            ->where($column, '>=', now()->subDays(6)->startOfDay())
            ->get([$column])
            ->groupBy(fn ($r) => optional($r->{$column})->format('Y-m-d'))
            ->map->count();

        return collect(range(6, 0))
            ->map(fn ($d) => $rows[now()->subDays($d)->format('Y-m-d')] ?? 0)
            ->values()->all();
    }

    private function trendLabel(array $trend): string
    {
        [$pct, $up] = $trend;

        return ($up ? '+' : '').$pct.'% vs last week';
    }

    protected function getStats(): array
    {
        $completed = AssessmentAttempt::where('status', 'completed');
        $avgScore = (clone $completed)->avg('percent');
        $memberTrend = $this->trend(User::class);
        $leadTrend = $this->trend(Lead::class);
        $toolTrend = $this->trend(ToolResult::class);

        return [
            Stat::make('Members', User::count())
                ->description($this->trendLabel($memberTrend))
                ->descriptionIcon($memberTrend[1] ? 'heroicon-m-arrow-trending-up' : 'heroicon-m-arrow-trending-down')
                ->chart($this->spark(User::class))
                ->color($memberTrend[1] ? 'success' : 'danger'),

            Stat::make('Assessments completed', (clone $completed)->count())
                ->description($this->thisWeek(AssessmentAttempt::class, 'completed_at').' this week')
                ->descriptionIcon('heroicon-m-sparkles')
                ->chart($this->spark(AssessmentAttempt::class, 'completed_at'))
                ->color('info'),

            Stat::make('Average money score', $avgScore ? round($avgScore).'%' : '-')
                ->description('Across all completed checks')
                ->descriptionIcon('heroicon-m-chart-bar')
                ->color('warning'),

            Stat::make('Leads captured', Lead::count())
                ->description($this->trendLabel($leadTrend))
                ->descriptionIcon('heroicon-m-user-plus')
                ->chart($this->spark(Lead::class))
                ->color($leadTrend[1] ? 'success' : 'danger'),

            Stat::make('Open consultations', Consultation::where('status', 'new')->count())
                ->description(Consultation::count().' booked all-time')
                ->descriptionIcon('heroicon-m-calendar-days')
                ->color('primary'),

            Stat::make('Tool sessions', ToolResult::count())
                ->description($this->trendLabel($toolTrend))
                ->descriptionIcon('heroicon-m-calculator')
                ->chart($this->spark(ToolResult::class))
                ->color($toolTrend[1] ? 'success' : 'danger'),

            Stat::make('Course enrolments', Enrollment::count())
                ->description(Enrollment::where('status', 'completed')->count().' completed')
                ->descriptionIcon('heroicon-m-academic-cap')
                ->color('info'),

            Stat::make('Guide downloads', (int) Guide::sum('download_count'))
                ->description(Guide::where('is_published', true)->count().' guides live')
                ->descriptionIcon('heroicon-m-arrow-down-tray')
                ->color('warning'),
        ];
    }
}
