<?php

namespace App\Filament\Resources;

use App\Filament\Resources\JadwalResource\Pages\CreateJadwal;
use App\Filament\Resources\JadwalResource\Pages\EditJadwal;
use App\Filament\Resources\JadwalResource\Pages\ListJadwals;
use App\Models\Guru;
use App\Models\Jadwal;
use App\Models\Kelas;
use App\Models\Mapel;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Notifications\Notification;
use Filament\Resources\Resource;
use Filament\Tables\Actions\BulkActionGroup;
use Filament\Tables\Actions\CreateAction;
use Filament\Tables\Actions\DeleteBulkAction;
use Filament\Tables\Actions\EditAction;
use Filament\Tables\Actions\DeleteAction;
use Filament\Tables\Actions\ViewAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Enums\FiltersLayout;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Support\Facades\Auth;

class JadwalResource extends Resource
{
    protected static ?string $model = Jadwal::class;

    // protected static ?string $navigationIcon = 'heroicon-o-calendar-days';

    protected static ?string $navigationGroup = 'Master Data';
    protected static ?int $navigationSort = 1;

    protected static ?string $modelLabel = 'Jadwal';
    protected static ?string $navigationLabel  = 'Manajemen Jadwal';
    protected static ?string $pluralModelLabel = 'Daftar Jadwal';
    
    protected static ?string $slug = 'jadwal';

    protected static ?string $navigationBadgeTooltip = 'Jadwal baru hari ini';

    public static function getNavigationBadge(): ?string
    {
        $count = static::getModel()::whereDate('created_at', today())->count();
        return $count > 0 ? (string) $count : null;
    }

    public static function getNavigationBadgeColor(): ?string
    {
        return static::getModel()::whereDate('created_at', today())->exists() ? 'success' : null;
    }

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                Select::make('hari')
                    ->label('Hari')
                    ->prefixIconColor('primary')
                    ->prefixIcon('heroicon-o-calendar-days')
                    ->options([
                        'senin' => 'Senin',
                        'selasa' => 'Selasa',
                        'rabu' => 'Rabu',
                        'kamis' => 'Kamis',
                        'jumat' => 'Jumat',
                    ])
                    ->searchable()
                    ->required()
                    ->reactive(),
                Select::make('jam_ke')
                    ->label('Jam Ke')
                    ->prefixIconColor('primary')
                    ->prefixIcon('heroicon-o-clock')
                    ->options(function (callable $get) {
                        $max = $get('hari') === 'jumat' ? 9 : 10;
                        return array_combine(
                            $range = range(1, $max),
                            array_map(fn($n) => "Jam ke-$n", $range)
                        );
                    })
                    ->searchable()
                    ->required()
                    ->rules([
                        function (callable $get) {
                            return function (string $attribute, $value, \Closure $fail) use ($get) {
                                $hari = $get('hari');
                                $kelasId = $get('kelas_id');
                                
                                if (!$hari || !$kelasId) {
                                    return;
                                }

                                $query = Jadwal::query()
                                    ->where('hari', $hari)
                                    ->where('jam_ke', $value)
                                    ->where('kelas_id', $kelasId);
                                
                                if ($recordId = $get('id')) {
                                    $query->where('id', '!=', $recordId);
                                }
                                
                                if ($query->exists()) {
                                    $kelas = Kelas::find($kelasId)->nama_kelas ?? 'kelas ini';
                                    $fail("Jam ke-{$value} pada hari ".ucfirst($hari)." untuk kelas {$kelas} sudah ada.");
                                }
                            };
                        },
                    ])
                    ->reactive(),
                TextInput::make('waktu_mulai')
                    ->label('Waktu Mulai')
                    ->prefixIconColor('primary')
                    ->prefixIcon('heroicon-o-play')
                    ->mask('99:99')
                    ->placeholder('HH:MM')
                    ->regex('/^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/')
                    ->required(),
                TextInput::make('waktu_selesai')
                    ->label('Waktu Selesai')
                    ->prefixIconColor('primary')
                    ->prefixIcon('heroicon-o-stop')
                    ->mask('99:99')
                    ->placeholder('HH:MM')
                    ->regex('/^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/')
                    ->required(),
                Select::make('guru_id')
                    ->label('Guru')
                    ->prefixIconColor('primary')
                    ->prefixIcon('heroicon-o-user-circle')
                    ->options(Guru::all()->pluck('nama', 'id'))
                    ->required()
                    ->live()
                    ->searchable(),
                Select::make('mapel_id')
                    ->label('Mata Pelajaran')
                    ->prefixIconColor('primary')
                    ->prefixIcon('heroicon-o-book-open')
                    ->options(Mapel::all()->pluck('nama_mapel', 'id'))
                    ->required()
                    ->live()
                    ->searchable(),
                Select::make('kelas_id')
                    ->label('Kelas')
                    ->prefixIconColor('primary')
                    ->prefixIcon('heroicon-o-building-office-2')
                    ->options(Kelas::all()->pluck('nama_kelas', 'id'))
                    ->required()
                    ->reactive()
                    ->live()
                    ->searchable(),
            ]);
    }

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                TextColumn::make('hari')
                    ->label('Hari')
                    ->formatStateUsing(fn ($state) => ucfirst($state))
                    ->sortable(),
                TextColumn::make('jam_ke')
                    ->label('Jam Ke')
                    ->formatStateUsing(fn ($state) => "Jam ke-$state")
                    ->sortable(),
                TextColumn::make('waktu_mulai')
                    ->label('Waktu Mulai')
                    ->time('H:i'),
                TextColumn::make('waktu_selesai')
                    ->label('Waktu Selesai')
                    ->time('H:i'),
                TextColumn::make('waktu')
                    ->label('Waktu')
                    ->getStateUsing(function ($record) {
                        return $record->waktu_mulai->format('H:i') . ' - ' . $record->waktu_selesai->format('H:i');
                    }),
                TextColumn::make('guru.nama')
                    ->label('Nama Guru')
                    ->sortable()
                    ->searchable(),
                TextColumn::make('mapel.nama_mapel')
                    ->label('Mapel')
                    ->sortable()
                    ->searchable(),
                TextColumn::make('kelas.nama_kelas')
                    ->label('Kelas')
                    ->searchable(),
            ])
            ->filters([
                SelectFilter::make('hari')
                    ->label('Hari')
                    ->options([
                        'senin' => 'Senin',
                        'selasa' => 'Selasa',
                        'rabu' => 'Rabu',
                        'kamis' => 'Kamis',
                        'jumat' => 'Jumat',
                        'sabtu' => 'Sabtu',
                    ])
                    ->multiple(),
                SelectFilter::make('jam_ke')
                    ->label('Jam Ke')
                    ->options(
                        Jadwal::query()
                            ->orderBy('jam_ke')
                            ->get()
                            ->mapWithKeys(function ($jadwal) {
                                return [
                                    $jadwal->jam_ke => "Jam ke-{$jadwal->jam_ke}"
                                ];
                            })
                            ->unique()
                    )
                    ->multiple(),
                SelectFilter::make('kelas_id')
                    ->label('Kelas')
                    ->options(
                        Kelas::query()
                            ->orderBy('nama_kelas')
                            ->pluck('nama_kelas', 'id')
                    )
                    ->multiple()
                    ->native(false),
                SelectFilter::make('guru_id')
                    ->label('Nama Guru')
                    ->options(
                        Guru::query()
                            ->orderBy('nama')
                            ->pluck('nama', 'id')
                    )
                    ->multiple()
                    ->native(false),
                SelectFilter::make('mapel_id')
                    ->label('Mata Pelajaran')
                    ->options(
                        Mapel::query()
                            ->orderBy('nama_mapel')
                            ->pluck('nama_mapel', 'id')
                    )
                    ->multiple()
                    ->native(false),
            ])
            ->filtersLayout(FiltersLayout::Modal)
            ->filtersFormColumns(2)
            ->actions([
                ViewAction::make(),
                EditAction::make(),
                DeleteAction::make()
                    ->successNotification(null)
                    ->after(function ($records) {
                        $hari = ucfirst($records->hari);
                        $waktu_mulai = $records->jadwal->waktu_mulai->format('H:i');
                        $waktu_selesai = $records->jadwal->waktu_selesai->format('H:i');
                        $waktu = $records->jadwal->jam_ke . ' (' . $waktu_mulai . ' - ' . $waktu_selesai . ')';

                        Notification::make()
                            ->title('Data Jadwal Dihapus')
                            ->success()
                            ->body("Data jadwal pada hari {$hari} di jam ke-{$waktu} berhasil dihapus")
                            ->sendToDatabase(Auth::user());
                    }),
            ])
            ->bulkActions([
                BulkActionGroup::make([
                    DeleteBulkAction::make()
                        ->label('Hapus Data Terpilih')
                        ->successNotification(null)
                        ->after(function ($records) {
                            $count = $records->count();

                            Notification::make()
                                ->title('Data Jadwal Dihapus')
                                ->success()
                                ->body("{$count} jadwal berhasil dihapus")
                                ->sendToDatabase(Auth::user());
                        }),
                ]),
            ])
            ->emptyStateHeading('Belum ada data jadwal')
            ->emptyStateDescription('Klik tombol dibawah untuk membuat jadwal baru')
            ->emptyStateActions([
                CreateAction::make()
                    ->label('Buat Jadwal')
                    ->icon('heroicon-o-plus'),
            ])
            ->deferLoading();
    }

    public static function getRelations(): array
    {
        return [
            //
        ];
    }

    public static function getPages(): array
    {
        return [
            'index' => ListJadwals::route('/'),
            'create' => CreateJadwal::route('/create'),
            'edit' => EditJadwal::route('/{record}/edit'),
        ];
    }
}
