<?php

namespace App\Filament\Resources;

use App\Exports\UsersExport;
use App\Filament\Resources\UserResource\Pages\CreateUser;
use App\Filament\Resources\UserResource\Pages\EditUser;
use App\Filament\Resources\UserResource\Pages\ListUsers;
use App\Models\Kelas;
use App\Models\User;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Notifications\Notification;
use Filament\Resources\Resource;
use Filament\Tables\Actions\BulkAction;
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\Columns\TextColumn;
use Filament\Tables\Enums\FiltersLayout;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\Rule;
use Maatwebsite\Excel\Facades\Excel;

class UserResource extends Resource
{
    protected static ?string $model = User::class;

    protected static ?string $recordTitleAttribute = 'name';

    public static function getGloballySearchableAttributes(): array
    {
        return [
            'name',
            'email',
            'guru.nip',
            'siswa.nis',
            'siswa.kelas.nama_kelas'
        ];
    }

    public static function getGlobalSearchResultDetails(Model $record): array
    {
        $details = [
            'Role' => match($record->role) {
                'admin' => 'Admin',
                'guru' => 'Guru',
                'siswa' => 'Siswa',
                default => ucfirst($record->role),
            },
            'Email' => $record->email,
        ];

        if ($record->role === 'guru') {
            $details['NIP'] = $record->guru?->nip ?? '-';
        } elseif ($record->role === 'siswa') {
            $details['NIS'] = $record->siswa?->nis ?? '-';
            $details['Kelas'] = $record->siswa?->kelas?->nama_kelas ?? '-';
        }

        return $details;
    }

    public static function getGlobalSearchEloquentQuery(): Builder
    {
        return parent::getGlobalSearchEloquentQuery()
            ->with([
                'guru',
                'siswa.kelas'
            ]);
    }

    protected static ?string $navigationIcon = 'heroicon-o-users';
    
    protected static ?string $modelLabel = 'Pengguna';
    protected static ?string $navigationLabel  = 'Manajemen Pengguna';
    protected static ?string $pluralModelLabel = 'Daftar Pengguna';
    
    protected static ?string $slug = 'pengguna';

    protected static ?string $navigationBadgeTooltip = 'Pengguna 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([
                TextInput::make('name')
                    ->label('Nama')
                    ->prefixIconColor('primary')
                    ->prefixIcon('heroicon-o-user')
                    ->required()
                    ->maxLength(255)
                    ->afterStateUpdated(function ($state, $set, $get) {
                        if ($get('role') === 'siswa' && $get('siswa.nama')) {
                            $set('siswa.nama', $state);
                        } elseif ($get('role') === 'guru' && $get('guru.nama')) {
                            $set('guru.nama', $state);
                        }
                    }),
                TextInput::make('email')
                    ->label('Email')
                    ->prefixIconColor('primary')
                    ->prefixIcon('heroicon-o-envelope')
                    ->email()
                    ->required()
                    ->maxLength(255)
                    ->unique(ignoreRecord: true)
                    ->rule('email:rfc,dns')
                    ->validationMessages([
                        'unique' => 'Email ini sudah terdaftar, Silakan gunakan email lain.',
                        'email' => 'Format email tidak valid.',
                    ]),
                TextInput::make('password')
                    ->label('Password')
                    ->prefixIcon('heroicon-o-lock-closed')
                    ->prefixIconColor('primary')
                    ->password()
                    ->revealable()
                    ->placeholder(fn ($operation) => $operation === 'edit' ? '••••••••' : '')
                    ->required(fn ($operation) => $operation === 'create')
                    ->maxLength(255)
                    ->dehydrated(fn ($state) => filled($state))
                    ->dehydrateStateUsing(fn ($state) => bcrypt($state)),
                Select::make('role')
                    ->label('Role')
                    ->prefixIconColor('primary')
                    ->prefixIcon('heroicon-o-user-circle')
                    ->options([
                        'admin' => 'Admin',
                        'guru' => 'Guru',
                        'siswa' => 'Siswa',
                    ])
                    ->searchable()
                    ->required()
                    ->live()
                    ->afterStateUpdated(function ($state, $set) {
                        $set('nip', null);
                        $set('nis', null);
                        $set('kelas_id', null);
                    }),
                TextInput::make('nip')
                    ->label('NIP')
                    ->prefixIconColor('primary')
                    ->prefixIcon('heroicon-o-identification')
                    ->required()
                    ->maxLength(255)
                    ->visible(fn (Get $get): bool => $get('role') === 'guru')
                    ->rules([
                        function (?User $record) {
                            return Rule::unique('gurus', 'nip')->ignore(
                                $record?->guru?->id
                            );
                        }
                    ])
                    ->validationMessages([
                        'unique' => 'NIP ini sudah terdaftar. Silakan periksa kembali.',
                    ])
                    ->default(function ($operation, ?User $record) {
                        return $operation === 'edit' && $record->isGuru() 
                            ? $record->guru->nip 
                            : null;
                    }),
                TextInput::make('nis')
                    ->label('NIS')
                    ->prefixIconColor('primary')
                    ->prefixIcon('heroicon-o-academic-cap')
                    ->required()
                    ->maxLength(255)
                    ->visible(fn (Get $get): bool => $get('role') === 'siswa')
                    ->rules([
                        function (?User $record) {
                            return Rule::unique('siswas', 'nis')->ignore(
                                $record?->siswa?->id
                            );
                        }
                    ])
                    ->validationMessages([
                        'unique' => 'NIS ini sudah terdaftar. Silakan periksa kembali.',
                    ])
                    ->default(function ($operation, ?User $record) {
                        return $operation === 'edit' && $record->isSiswa() 
                            ? $record->siswa->nis 
                            : null;
                    }),
                Select::make('kelas_id')
                    ->label('Kelas')
                    ->prefixIconColor(function ($get) {
                        $kelasId = $get('kelas_id');
                        if (!$kelasId) return 'gray';
                        
                        $kelas = Kelas::find($kelasId);
                        if (!$kelas) return 'gray';
                        
                        return match ($kelas->jurusan) {
                            'akuntansi' => 'primary',
                            'manajemen_perkantoran' => 'warning',
                            default => 'gray',
                        };
                    })
                    ->prefixIcon(function ($get) {
                        $kelasId = $get('kelas_id');
                        if (!$kelasId) return 'heroicon-o-question-mark-circle';
                        
                        $kelas = Kelas::find($kelasId);
                        if (!$kelas) return 'heroicon-o-question-mark-circle';
                        
                        return match ($kelas->jurusan) {
                            'akuntansi' => 'heroicon-o-calculator',
                            'manajemen_perkantoran' => 'heroicon-o-briefcase',
                            default => 'heroicon-o-question-mark-circle',
                        };
                    })
                    ->options(function () {
                        return Kelas::all()->pluck('nama_kelas', 'id');
                    })
                    ->searchable()
                    ->preload()
                    ->required()
                    ->live()
                    ->visible(fn (Get $get): bool => $get('role') === 'siswa')
                    ->default(function ($operation, ?User $record) {
                        return $operation === 'edit' && $record->isSiswa() 
                            ? $record->siswa->kelas_id 
                            : null;
                    }),
            ]);
    }

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                TextColumn::make('name')
                    ->searchable(),
                TextColumn::make('email')
                    ->searchable(),
                TextColumn::make('role')
                    ->badge()
                    ->formatStateUsing(fn (string $state): string => match ($state) {
                        'admin' => 'Admin',
                        'guru' => 'Guru',
                        'siswa' => 'Siswa',
                        default => ucfirst(str_replace('_', ' ', $state)),
                    })
                    ->color(fn (string $state): string => match ($state) {
                        'admin' => 'danger',
                        'guru' => 'warning',
                        'siswa' => 'success',
                    }),
                TextColumn::make('guru.nip')
                    ->label('NIP')
                    ->getStateUsing(function ($record) {
                        return $record->guru?->nip ?? '-';
                    }),
                TextColumn::make('siswa.nis')
                    ->label('NIS')
                    ->getStateUsing(function ($record) {
                        return $record->siswa?->nis ?? '-';
                    }),
                TextColumn::make('siswa.kelas.nama_kelas')
                    ->label('Kelas')
                    ->getStateUsing(function ($record) {
                        return $record->siswa?->kelas?->nama_kelas ?? '-';
                    }),
            ])
            ->filters([
                SelectFilter::make('role')
                    ->options([
                        'admin' => 'Admin',
                        'guru' => 'Guru',
                        'siswa' => 'Siswa',
                    ])
                    ->multiple(),
                SelectFilter::make('kelas_id')
                    ->label('Kelas')
                    ->options(
                        Kelas::query()
                            ->orderBy('nama_kelas')
                            ->pluck('nama_kelas', 'id')
                    )
                    ->multiple()
                    ->query(function (Builder $query, array $data) {
                        if (!empty($data['values'])) {
                            $query->whereHas('siswa', fn($q) => $q->whereIn('kelas_id', $data['values']));
                        }
                    }),
            ])
            ->filtersLayout(FiltersLayout::Modal)
            ->filtersFormColumns(2)
            ->actions([
                EditAction::make(),
                DeleteAction::make()
                    ->successNotification(null)
                    ->after(function ($record) {
                        Notification::make()
                            ->title('Data Pengguna Dihapus')
                            ->success()
                            ->body("Data pengguna {$record->name} 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 Pengguna Dihapus')
                                ->success()
                                ->body("{$count} pengguna berhasil dihapus")
                                ->sendToDatabase(Auth::user());
                        }),
                    BulkAction::make('export')
                        ->label('Export Data Terpilih')
                        ->icon('heroicon-o-arrow-down-tray')
                        ->action(function ($records) {
                            $fileName = 'Export_Pengguna_Terpilih_' . date('Ymd_His') . '.xlsx';
                            
                            return Excel::download(new UsersExport($records), $fileName);
                        })
                        ->requiresConfirmation()
                ]),
            ])
            ->emptyStateHeading('Belum ada data pengguna')
            ->emptyStateDescription('Klik tombol dibawah untuk membuat pengguna baru')
            ->emptyStateActions([
                CreateAction::make()
                    ->label('Buat Pengguna')
                    ->icon('heroicon-o-plus'),
            ])
            ->deferLoading();
    }

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

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