<?php

namespace Modules\Payment\Filament\Widgets;

use Filament\Widgets\ChartWidget;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Modules\Payment\Enums\PaymentStatus;
use Modules\Payment\Models\Payment;

/**
 * 30-day revenue trend from completed payments. Cached per day (T7.1) —
 * refreshes at most once every 5 minutes since this aggregates a whole
 * month of rows on every dashboard load otherwise.
 */
class RevenueChartWidget extends ChartWidget
{
    protected static ?int $sort = 1;

    protected ?string $heading = 'Revenue (Last 30 Days)';

    protected function getData(): array
    {
        $days = Cache::tags('payments')->remember(
            'dashboard:revenue-chart:'.today()->toDateString(),
            now()->addMinutes(5),
            fn () => $this->revenueByDay(),
        );

        return [
            'datasets' => [
                [
                    'label' => 'Revenue',
                    'data' => $days->pluck('total')->all(),
                    'fill' => true,
                ],
            ],
            'labels' => $days->pluck('label')->all(),
        ];
    }

    protected function getType(): string
    {
        return 'line';
    }

    /**
     * @return Collection<int, array{label: string, total: float}>
     */
    private function revenueByDay(): Collection
    {
        $start = today()->subDays(29);

        $totals = Payment::query()
            ->where('status', PaymentStatus::Completed)
            ->whereDate('completed_at', '>=', $start)
            ->selectRaw('DATE(completed_at) as day, SUM(amount) as total')
            ->groupBy('day')
            ->pluck('total', 'day');

        return collect(range(0, 29))
            ->map(function (int $offset) use ($start, $totals) {
                $date = $start->copy()->addDays($offset);

                return [
                    'label' => $date->format('M j'),
                    'total' => (float) ($totals[$date->toDateString()] ?? 0),
                ];
            });
    }
}
