<?php

namespace App\Filament\Widgets;

use App\Models\JobAlertEmailLog;
use Carbon\CarbonImmutable;
use Filament\Support\RawJs;
use Filament\Widgets\ChartWidget;

class AlertPerformanceChart extends ChartWidget
{
    protected static bool $isLazy = false;

    protected static ?int $sort = 6;

    protected ?string $heading = 'Job alert performance';

    protected ?string $description = 'Sent/open/click/unsubscribe trend. Open and click data require Brevo event webhooks.';

    protected string $color = 'primary';

    protected int|string|array $columnSpan = 'full';

    public ?string $filter = '30';

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

    /**
     * @return array<string, string>
     */
    protected function getFilters(): ?array
    {
        return [
            '14' => 'Last 14 days',
            '30' => 'Last 30 days',
            '90' => 'Last 90 days',
        ];
    }

    /**
     * @return array<string, mixed>
     */
    protected function getData(): array
    {
        $days = max(14, (int) ($this->filter ?: 30));
        $start = CarbonImmutable::now()->subDays($days - 1)->startOfDay();
        $dates = collect(range(0, $days - 1))
            ->map(fn (int $offset): CarbonImmutable => $start->addDays($offset));

        return [
            'datasets' => [
                [
                    'label' => 'Sent',
                    'data' => $this->counts($dates, 'sent_at'),
                    'borderColor' => '#0f766e',
                    'backgroundColor' => 'rgba(15, 118, 110, .12)',
                    'fill' => true,
                    'tension' => .42,
                    'pointRadius' => 0,
                ],
                [
                    'label' => 'Opened',
                    'data' => $this->counts($dates, 'opened_at'),
                    'borderColor' => '#2563eb',
                    'backgroundColor' => 'rgba(37, 99, 235, .08)',
                    'fill' => true,
                    'tension' => .42,
                    'pointRadius' => 0,
                ],
                [
                    'label' => 'Clicked',
                    'data' => $this->counts($dates, 'clicked_at'),
                    'borderColor' => '#10b981',
                    'backgroundColor' => 'rgba(16, 185, 129, .08)',
                    'fill' => true,
                    'tension' => .42,
                    'pointRadius' => 0,
                ],
                [
                    'label' => 'Unsubscribed',
                    'data' => $this->counts($dates, 'unsubscribed_at'),
                    'borderColor' => '#f59e0b',
                    'backgroundColor' => 'rgba(245, 158, 11, .10)',
                    'fill' => true,
                    'tension' => .42,
                    'pointRadius' => 0,
                ],
            ],
            'labels' => $dates
                ->map(fn (CarbonImmutable $date): string => $date->format($days > 30 ? 'M j' : 'j M'))
                ->all(),
        ];
    }

    /**
     * @param  \Illuminate\Support\Collection<int, CarbonImmutable>  $dates
     * @return array<int, int>
     */
    private function counts($dates, string $column): array
    {
        return $dates
            ->map(fn (CarbonImmutable $date): int => JobAlertEmailLog::query()
                ->whereDate($column, $date)
                ->count())
            ->all();
    }

    /**
     * @return array<string, mixed>|RawJs|null
     */
    protected function getOptions(): array|RawJs|null
    {
        return [
            'plugins' => [
                'legend' => [
                    'position' => 'bottom',
                    'labels' => [
                        'usePointStyle' => true,
                        'pointStyle' => 'circle',
                    ],
                ],
                'tooltip' => [
                    'mode' => 'index',
                    'intersect' => false,
                ],
            ],
            'interaction' => [
                'mode' => 'nearest',
                'axis' => 'x',
                'intersect' => false,
            ],
            'scales' => [
                'x' => [
                    'grid' => ['display' => false],
                ],
                'y' => [
                    'beginAtZero' => true,
                    'ticks' => ['precision' => 0],
                ],
            ],
        ];
    }
}
