<?php

namespace App\Filament\Widgets\Charts;

use App\Enums\IssueSentiment;
use App\Models\IssueManagement;
use BezhanSalleh\FilamentShield\Traits\HasWidgetShield;
use Filament\Widgets\ChartWidget;
use Filament\Widgets\Concerns\InteractsWithPageFilters;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;

class SentimentTrendChart extends ChartWidget
{
    use HasWidgetShield, InteractsWithPageFilters;

    protected ?string $heading = 'Dinamika Sentimen Isu (Area)';

    protected static ?int $sort = 18;

    protected int|string|array $columnSpan = 1;

    protected ?string $pollingInterval = null;

    protected function getData(): array
    {
        $startDate = $this->filters['startDate'] ?? Carbon::now()->subDays(30);
        $endDate = $this->filters['endDate'] ?? Carbon::now();

        $startDate = Carbon::parse($startDate)->startOfDay();
        $endDate = Carbon::parse($endDate)->endOfDay();

        $query = IssueManagement::query()
            ->select(
                DB::raw('DATE(created_at) as date'),
                'issue',
                DB::raw('count(*) as total')
            )
            ->whereBetween('created_at', [$startDate, $endDate])
            ->groupBy('date', 'issue')
            ->orderBy('date')
            ->get();

        $labels = [];
        $current = clone $startDate;
        while ($current <= $endDate) {
            $labels[] = $current->translatedFormat('d M');
            $current->addDay();
        }

        $datasets = [];
        foreach (IssueSentiment::cases() as $sentiment) {
            $data = [];
            $current = clone $startDate;
            while ($current <= $endDate) {
                $dateStr = $current->toDateString();
                $count = $query->where('date', $dateStr)
                    ->where('issue', $sentiment->value)
                    ->first();
                $data[] = $count ? $count->total : 0;
                $current->addDay();
            }

            $datasets[] = [
                'label' => $sentiment->getLabel(),
                'data' => $data,
                'fill' => 'origin',
                'backgroundColor' => $this->getHexColorRGBA($sentiment, 0.2),
                'borderColor' => $this->getHexColor($sentiment),
                'tension' => 0.4,
            ];
        }

        return [
            'datasets' => $datasets,
            'labels' => $labels,
        ];
    }

    private function getHexColor(IssueSentiment $sentiment): string
    {
        return match ($sentiment) {
            IssueSentiment::POSITIVE => '#10B981',
            IssueSentiment::NEGATIVE => '#EF4444',
            IssueSentiment::NEUTRAL => '#6B7280',
            IssueSentiment::CRISIS => '#F97316',
        };
    }

    private function getHexColorRGBA(IssueSentiment $sentiment, float $opacity): string
    {
        return match ($sentiment) {
            IssueSentiment::POSITIVE => "rgba(16, 185, 129, {$opacity})",
            IssueSentiment::NEGATIVE => "rgba(239, 68, 68, {$opacity})",
            IssueSentiment::NEUTRAL => "rgba(107, 114, 128, {$opacity})",
            IssueSentiment::CRISIS => "rgba(249, 115, 22, {$opacity})",
        };
    }

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

    protected function getOptions(): array
    {
        return [
            'plugins' => [
                'legend' => [
                    'display' => true,
                ],
            ],
            'scales' => [
                'y' => [
                    'beginAtZero' => true,
                    'ticks' => [
                        'stepSize' => 1,
                    ],
                ],
            ],
        ];
    }
}
