<?php

namespace App\Filament\Resources;

use App\Filament\Resources\RekapanSiswaResource\Pages\CreateRekapanSiswa;
use App\Filament\Resources\RekapanSiswaResource\Pages\EditRekapanSiswa;
use App\Filament\Resources\RekapanSiswaResource\Pages\ListRekapanSiswas;
use App\Models\Guru;
use App\Models\Jadwal;
use App\Models\Kelas;
use App\Models\Mapel;
use App\Models\RekapanSiswa;
use App\Models\User;
use Carbon\Carbon;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Forms\Set;
use Filament\Notifications\Notification;
use Filament\Resources\Resource;
use Filament\Tables\Actions\BulkActionGroup;
use Filament\Tables\Actions\CreateAction;
use Filament\Tables\Actions\DeleteAction;
use Filament\Tables\Actions\DeleteBulkAction;
use Filament\Tables\Actions\EditAction;
use Filament\Tables\Actions\ViewAction;
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 Illuminate\Support\Facades\Auth;

class RekapanSiswaResource extends Resource
{
    protected static ?string $model = RekapanSiswa::class;

    // protected static ?string $navigationIcon = 'heroicon-o-clipboard-document-list';

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

    protected static ?string $modelLabel = 'Rekapan Siswa';
    protected static ?string $navigationLabel  = 'Manajemen Rekapan Siswa';
    protected static ?string $pluralModelLabel = 'Daftar Rekapan Siswa';
    
    protected static ?string $slug = 'rekapan-siswa';

    protected static ?string $navigationBadgeTooltip = 'Rekapan Siswa 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('siswa_id')
                    ->label('Siswa')
                    ->prefixIconColor('primary')
                    ->prefixIcon('heroicon-o-user-circle')
                    ->options(
                        User::where('role', 'siswa')
                            ->pluck('name', 'id')
                    )
                    ->required()
                    ->searchable(),
                Select::make('kelas_id')
                    ->label('Kelas')
                    ->prefixIconColor('primary')
                    ->prefixIcon('heroicon-o-building-office-2')
                    ->options(Kelas::all()->pluck('nama_kelas', 'id'))
                    ->required()
                    ->reactive()
                    ->searchable(),
                Select::make('mapel_id')
                    ->label('Mata Pelajaran')
                    ->prefixIconColor('primary')
                    ->prefixIcon('heroicon-o-book-open')
                    ->options(Mapel::all()->pluck('nama_mapel', 'id'))
                    ->required()
                    ->searchable(),
                Select::make('guru_id')
                    ->label('Guru')
                    ->prefixIconColor('primary')
                    ->prefixIcon('heroicon-o-academic-cap')
                    ->options(Guru::all()->pluck('nama', 'id'))
                    ->required()
                    ->reactive()
                    ->searchable(),
                Select::make('jadwal_id')
                    ->label('Jadwal Pengajar')
                    ->prefixIconColor('primary')
                    ->prefixIcon('heroicon-o-clock')
                    ->options(Jadwal::all()->map(function ($jadwal) {
                        return [
                            'id' => $jadwal->id,
                            'label' => ucfirst($jadwal->hari) . ' | Jam ke-' . $jadwal->jam_ke . 
                                    ' (' . Carbon::parse($jadwal->waktu_mulai)->format('H:i') . ' - ' . 
                                    Carbon::parse($jadwal->waktu_selesai)->format('H:i') . ')'
                        ];
                    })->pluck('label', 'id'))
                    ->searchable()
                    ->required(),
                DatePicker::make('tanggal')
                    ->label('Tanggal')
                    ->prefixIconColor('primary')
                    ->prefixIcon('heroicon-o-calendar')
                    ->required()
                    ->default(now()),
                Select::make('status')
                    ->label('Status')
                    ->prefixIconColor(function ($state) {
                        return match ($state) {
                            'hadir_mengajar' => 'primary',
                            'tidak_mengajar' => 'danger',
                            'hadir_digantikan' => 'warning',
                            default => 'gray',
                        };
                    })
                    ->prefixIcon(function ($state) {
                        return match ($state) {
                            'hadir_mengajar' => 'heroicon-o-check-circle',
                            'tidak_mengajar' => 'heroicon-o-x-circle',
                            'hadir_digantikan' => 'heroicon-o-arrow-path',
                            default => 'heroicon-o-question-mark-circle',
                        };
                    })
                    ->options([
                        'hadir_mengajar' => 'Hadir Mengajar',
                        'tidak_mengajar' => 'Tidak Mengajar',
                        'hadir_digantikan' => 'Hadir Digantikan',
                    ])
                    ->searchable()
                    ->required()
                    ->live()
                    ->default('hadir_mengajar')
                    ->afterStateUpdated(function ($state, Set $set) {
                        $set('jurusan', $state);
                    }),
                TextInput::make('komputer')
                    ->label('Komputer')
                    ->prefixIconColor('primary')
                    ->prefixIcon('heroicon-o-computer-desktop')
                    ->required()
                    ->numeric()
                    ->minValue(0),
                Textarea::make('keterangan')
                    ->label('Keterangan')
                    ->placeholder('Contoh: Guru digantikan oleh Bu Ani karena sakit')
                    ->nullable()
                    ->columnSpanFull(),
            ]);
    }

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                TextColumn::make('siswa.nama')
                    ->label('Nama Siswa')
                    ->sortable()
                    ->searchable(),
                TextColumn::make('guru.nama')
                    ->label('Nama Guru')
                    ->searchable()
                    ->sortable(),
                TextColumn::make('mapel.nama_mapel')
                    ->label('Mapel')
                    ->sortable()
                    ->searchable(),
                TextColumn::make('kelas.nama_kelas')
                    ->label('Kelas')
                    ->searchable(),
                TextColumn::make('jadwal.hari')
                    ->label('Hari')
                    ->formatStateUsing(fn (string $state): string => ucfirst($state))
                    ->searchable(),
                TextColumn::make('tanggal')
                    ->label('Tanggal')
                    ->date('d F Y')
                    ->sortable(),
                TextColumn::make('jadwal.jam_ke')
                    ->label('Jam Ke')
                    ->formatStateUsing(fn ($state): string => "Jam ke-$state"),
                TextColumn::make('jadwal.waktu_mulai')
                    ->label('Mulai')
                    ->date('H:i'),
                TextColumn::make('jadwal.waktu_selesai')
                    ->label('Selesai')
                    ->date('H:i'),
                TextColumn::make('keterangan')
                    ->label('Keterangan')
                    ->limit(30)
                    ->placeholder('-')
                    ->tooltip(function (RekapanSiswa $record): ?string {
                        return $record->keterangan ?? '-';
                    }),
                TextColumn::make('komputer')
                    ->label('Komputer')
                    ->numeric(),
                TextColumn::make('status')
                    ->label('Status')
                    ->badge()
                    ->formatStateUsing(fn (string $state): string => match ($state) {
                        'hadir_mengajar' => 'Hadir Mengajar',
                        'tidak_mengajar' => 'Tidak Mengajar',
                        'hadir_digantikan' => 'Hadir Digantikan',
                        default => ucfirst(str_replace('_', ' ', $state)),
                    })
                    ->color(fn (string $state): string => match ($state) {
                        'hadir_mengajar' => 'success',
                        'tidak_mengajar' => 'danger',
                        'hadir_digantikan' => 'warning',
                    }),
            ])
            ->filters([
                SelectFilter::make('status')
                    ->options([
                        'hadir_mengajar' => 'Hadir Mengajar',
                        'tidak_mengajar' => 'Tidak Mengajar',
                        'hadir_digantikan' => 'Hadir Digantikan',
                    ])
                    ->multiple()
                    ->native(),
                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()
                    ->native(false)
                    ->query(function (Builder $query, array $data) {
                        if (!empty($data['values'])) {
                            $query->whereHas('jadwal', fn($q) => $q->whereIn('jam_ke', $data['values']));
                        }
                    }),
                SelectFilter::make('kelas_id')
                    ->label('Kelas')
                    ->options(
                        Kelas::query()
                            ->orderBy('nama_kelas')
                            ->pluck('nama_kelas', 'id')
                    )
                    ->multiple()
                    ->native()
                    ->query(function (Builder $query, array $data) {
                        if (!empty($data['values'])) {
                            $query->whereHas('jadwal', fn($q) => $q->whereIn('kelas_id', $data['values']));
                        }
                    }),
                SelectFilter::make('guru_id')
                    ->label('Nama Guru')
                    ->options(
                        Guru::query()
                            ->orderBy('nama')
                            ->pluck('nama', 'id')
                    )
                    ->multiple()
                    ->native(),
                SelectFilter::make('mapel_id')
                    ->label('Mata Pelajaran')
                    ->options(
                        Mapel::query()
                            ->orderBy('nama_mapel')
                            ->pluck('nama_mapel', 'id')
                    )
                    ->multiple()
                    ->native(),
                SelectFilter::make('hari')
                    ->label('Hari')
                    ->options([
                        'senin' => 'Senin',
                        'selasa' => 'Selasa',
                        'rabu' => 'Rabu',
                        'kamis' => 'Kamis',
                        'jumat' => 'Jumat',
                        'sabtu' => 'Sabtu',
                    ])
                    ->multiple()
                    ->native(false)
                    ->query(function (Builder $query, array $data) {
                        if (!empty($data['values'])) {
                            $query->whereHas('jadwal', fn($q) => $q->whereIn('hari', $data['values']));
                        }
                    }),
                Filter::make('dari_tanggal')
                    ->form([
                        DatePicker::make('dari_tanggal')
                            ->label('Dari Tanggal')
                            ->placeholder('Pilih tanggal awal')
                            ->prefixIcon('heroicon-o-calendar')
                            ->displayFormat('d/m/Y')
                            ->format('d/m/Y')
                            ->native(false)
                    ])
                    ->query(function (Builder $query, array $data): Builder {
                        return $query
                            ->when(
                                $data['dari_tanggal'],
                                fn (Builder $query, $date): Builder => $query->whereDate('tanggal', '>=', $date),
                            );
                    }),
                Filter::make('sampai_tanggal')
                    ->form([
                        DatePicker::make('sampai_tanggal')
                            ->label('Sampai Tanggal')
                            ->placeholder('Pilih tanggal akhir')
                            ->prefixIcon('heroicon-o-calendar')
                            ->displayFormat('d/m/Y')
                            ->format('d/m/Y')
                            ->native(false)
                    ])
                    ->query(function (Builder $query, array $data): Builder {
                        return $query
                            ->when(
                                $data['sampai_tanggal'],
                                fn (Builder $query, $date): Builder => $query->whereDate('tanggal', '<=', $date),
                            );
                    }),
            ])
            ->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 Rekapan Siswa Dihapus')
                            ->success()
                            ->body("Data rekapan siswa {$records->siswa->nama} yang diajar guru {$records->guru->nama} pada mapel {$records->mapel->nama_mapel} di kelas {$records->kelas->nama_kelas} 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 Rekapan Siswa Dihapus')
                                ->success()
                                ->body("{$count} rekapan siswa berhasil dihapus")
                                ->sendToDatabase(Auth::user());
                        }),
                ]),
            ])
            ->emptyStateHeading('Belum ada data rekapan siswa')
            ->emptyStateDescription('Klik tombol dibawah untuk membuat rekapan siswa baru')
            ->emptyStateActions([
                CreateAction::make()
                    ->label('Buat Rekapan Siswa')
                    ->icon('heroicon-o-plus'),
            ])
            ->deferLoading();
    }

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

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