<?php

namespace App\Filament\Resources\Visitors;

use App\Filament\Columns\RowIndexColumn;
use App\Filament\Resources\Visitors\Pages\ManageVisitors;
use App\Filament\Support\CheerfulNotification;
use App\Models\Visitor;
use BackedEnum;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Select;
use Filament\Resources\Resource;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Support\Icons\Heroicon;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Enums\FiltersLayout;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use UnitEnum;

class VisitorResource extends Resource
{
    protected static ?string $model = Visitor::class;

    protected static string|UnitEnum|null $navigationGroup = 'Monitoring';

    protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedChartBar;

    protected static ?string $navigationLabel = 'Pengunjung';

    protected static ?int $navigationSort = 4;

    protected static ?string $slug = 'monitoring/visitors';

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                ...RowIndexColumn::make(),

                TextColumn::make('date')
                    ->label('Tanggal & Waktu')
                    ->date('l, d F Y')
                    ->sortable(),

                TextColumn::make('route')
                    ->label('Halaman')
                    ->searchable()
                    ->sortable(),

                TextColumn::make('method')
                    ->label('Method')
                    ->badge()
                    ->color(fn (string $state): string => match ($state) {
                        'GET' => 'success',
                        'POST' => 'warning',
                        default => 'gray',
                    }),

                TextColumn::make('status')
                    ->label('Status')
                    ->badge()
                    ->color(fn (int $state): string => $state >= 200 && $state < 300 ? 'success' : 'danger'),

                TextColumn::make('ip')
                    ->label('IP Address')
                    ->searchable(),

                TextColumn::make('counter')
                    ->label('Hits')
                    ->numeric()
                    ->sortable(),

                TextColumn::make('user.name')
                    ->label('User')
                    ->placeholder('Tamu'),
            ])
            ->defaultSort('date', 'desc')
            ->filters([
                SelectFilter::make('method')
                    ->options([
                        'GET' => 'GET',
                        'POST' => 'POST',
                    ])
                    ->native(false),

                Filter::make('date_filter')
                    ->schema([
                        Select::make('date_type')
                            ->label('Jenis Filter Tanggal')
                            ->options([
                                'date' => 'Tanggal',
                                'month' => 'Bulan & Tahun',
                                'year' => 'Tahun',
                                'range' => 'Rentang Tanggal',
                            ])
                            ->live()
                            ->native(false),

                        DatePicker::make('specific_date')
                            ->label('Tanggal')
                            ->placeholder('Pilih tanggal')
                            ->visible(fn (Get $get) => $get('date_type') === 'date')
                            ->native(false),

                        Select::make('month')
                            ->label('Bulan')
                            ->options([
                                1 => 'Januari',
                                2 => 'Februari',
                                3 => 'Maret',
                                4 => 'April',
                                5 => 'Mei',
                                6 => 'Juni',
                                7 => 'Juli',
                                8 => 'Agustus',
                                9 => 'September',
                                10 => 'Oktober',
                                11 => 'November',
                                12 => 'Desember',
                            ])
                            ->visible(fn (Get $get) => $get('date_type') === 'month')
                            ->native(false),

                        Select::make('year')
                            ->label('Tahun')
                            ->options(function () {
                                $years = range(date('Y'), 2020);

                                return array_combine($years, $years);
                            })
                            ->visible(fn (Get $get) => in_array($get('date_type'), ['month', 'year']))
                            ->native(false),

                        DatePicker::make('start_date')
                            ->label('Tanggal Mulai')
                            ->placeholder('Pilih tanggal mulai')
                            ->visible(fn (Get $get) => $get('date_type') === 'range')
                            ->native(false)
                            ->displayFormat('l, d F Y'),

                        DatePicker::make('end_date')
                            ->label('Tanggal Selesai')
                            ->placeholder('Pilih tanggal selesai')
                            ->visible(fn (Get $get) => $get('date_type') === 'range')
                            ->native(false)
                            ->displayFormat('l, d F Y'),
                    ])
                    ->query(function (Builder $query, array $data): Builder {
                        $type = $data['date_type'] ?? null;
                        $column = 'date';

                        return $query->when($type, function (Builder $query) use ($type, $data, $column) {
                            if ($type === 'date' && ! empty($data['specific_date'])) {
                                $query->whereDate($column, $data['specific_date']);
                            } elseif ($type === 'month' && ! empty($data['month']) && ! empty($data['year'])) {
                                $query->whereMonth($column, $data['month'])
                                    ->whereYear($column, $data['year']);
                            } elseif ($type === 'year' && ! empty($data['year'])) {
                                $query->whereYear($column, $data['year']);
                            } elseif ($type === 'range' && ! empty($data['start_date']) && ! empty($data['end_date'])) {
                                $query->whereBetween($column, [$data['start_date'], $data['end_date']]);
                            }
                        });
                    }),
            ], FiltersLayout::AboveContentCollapsible)
            ->filtersFormColumns(3)
            ->emptyStateIcon(Heroicon::OutlinedChartBar)
            ->emptyStateHeading(fn () => CheerfulNotification::getByKey('visitor.empty_state_heading'))
            ->emptyStateDescription(fn () => CheerfulNotification::getByKey('visitor.empty_state'))
            ->defaultSort('date', 'desc')
            ->deferFilters(false)
            ->paginated([25, 50, 100, 'all'])
            ->deferLoading();
    }

    public static function getPages(): array
    {
        return [
            'index' => ManageVisitors::route('/'),
        ];
    }
}
