<?php

namespace App\Filament\Employee\Resources;

use App\Filament\Employee\Resources\MyCorrectionResource\Pages;
use App\Models\Attendance;
use App\Models\AttendanceCorrection;
use App\Models\EarlyLeaveRequest;
use App\Services\AttendanceCorrectionService;
use Carbon\Carbon;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Infolists;
use Filament\Infolists\Infolist;
use Filament\Notifications\Notification;
use Filament\Resources\Resource;
use Filament\Support\Enums\FontWeight;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;

class MyCorrectionResource extends Resource
{
    protected static ?string $model = AttendanceCorrection::class;

    protected static ?string $navigationIcon = 'heroicon-o-pencil-square';

    protected static ?string $navigationLabel = 'Koreksi & Izin Pulang Cepat';

    protected static ?string $modelLabel = 'Koreksi Absen';

    protected static ?string $pluralModelLabel = 'Koreksi Absen';

    protected static ?string $navigationGroup = 'Kehadiran Saya';

    protected static ?int $navigationSort = 3;

    public static function getNavigationBadge(): ?string
    {
        $user = auth()->user();
        return static::getModel()::where('user_id', $user?->id)
            ->where('status', 'pending')
            ->count() ?: null;
    }

    public static function getNavigationBadgeColor(): ?string
    {
        return 'warning';
    }

    public static function form(Form $form): Form
    {
        $user = auth()->user();
        $company = $user?->company;
        $correctionService = new AttendanceCorrectionService();
        $isBackdateMode = $company ? $correctionService->isBackdateMode($company) : false;

        // Calculate threshold
        $threshold = 0;
        if ($company?->work_start_time && $company?->work_end_time) {
            $workStart = Carbon::parse($company->work_start_time);
            $workEnd = Carbon::parse($company->work_end_time);
            $expectedDuration = $workStart->diffInMinutes($workEnd);
            $threshold = $expectedDuration - 45;
        }

        return $form
            ->schema([
                Forms\Components\Section::make('Pilih Jenis Pengajuan')
                    ->schema([
                        Forms\Components\Radio::make('form_purpose')
                            ->label('')
                            ->options([
                                'correction' => 'Koreksi Waktu',
                                'early_leave' => 'Izin Pulang Cepat',
                            ])
                            ->descriptions([
                                'correction' => 'Waktu absen tidak akurat (lupa absen, HP mati, aplikasi error)',
                                'early_leave' => 'Pulang lebih awal dengan izin (sakit, urusan keluarga)',
                            ])
                            ->inline()
                            ->required()
                            ->live()
                            ->default('correction'),
                    ]),

                Forms\Components\Section::make('Pilih Kehadiran')
                    ->schema([
                        Forms\Components\Select::make('attendance_id')
                            ->label('Tanggal Kehadiran')
                            ->options(function () use ($user, $threshold) {
                                return Attendance::where('user_id', $user->id)
                                    ->whereNotNull('work_duration')
                                    ->where('work_duration', '<', $threshold)
                                    // Mutual exclusion: exclude yang sudah ada di koreksi absen (pending)
                                    ->whereDoesntHave('corrections', function ($q) {
                                        $q->where('status', 'pending');
                                    })
                                    // Mutual exclusion: exclude yang sudah ada di early leave request (pending/approved/used)
                                    ->whereDoesntHave('earlyLeaveRequests', function ($q) {
                                        $q->whereIn('status', ['pending', 'approved', 'used']);
                                    })
                                    ->orderBy('date', 'desc')
                                    ->limit(30)
                                    ->get()
                                    ->mapWithKeys(function ($att) use ($threshold) {
                                        $shortage = $threshold - $att->work_duration;
                                        $hours = floor($shortage / 60);
                                        $mins = $shortage % 60;
                                        return [
                                            $att->id => $att->date->format('d M Y') . ' - ' .
                                                ($att->check_in_time?->format('H:i') ?? '-') . ' s/d ' .
                                                ($att->check_out_time?->format('H:i') ?? '-') .
                                                " (Kurang {$hours}j {$mins}m)"
                                        ];
                                    });
                            })
                            ->searchable()
                            ->required()
                            ->live()
                            ->afterStateUpdated(function ($state, Forms\Set $set) use ($user, $isBackdateMode, $company) {
                                if ($state) {
                                    $att = Attendance::find($state);
                                    if ($att) {
                                        $set('original_check_in', $att->check_in_time?->format('H:i'));
                                        $set('original_check_out', $att->check_out_time?->format('H:i'));
                                        $set('original_duration', $att->work_duration);

                                        // Analyze what needs to be corrected
                                        $workStart = $company?->work_start_time ? Carbon::parse($company->work_start_time) : Carbon::parse('08:00');
                                        $workEnd = $company?->work_end_time ? Carbon::parse($company->work_end_time) : Carbon::parse('17:00');
                                        $expectedDuration = $workStart->diffInMinutes($workEnd);

                                        $checkInLate = false;
                                        $checkOutEarly = false;

                                        if ($att->check_in_time) {
                                            // Check if check-in is late (more than 5 min after work start)
                                            $checkInLate = $att->check_in_time->format('H:i') > $workStart->copy()->addMinutes(5)->format('H:i');
                                        }

                                        if ($att->check_out_time) {
                                            // Check if check-out is early (more than 5 min before work end)
                                            $checkOutEarly = $att->check_out_time->format('H:i') < $workEnd->copy()->subMinutes(5)->format('H:i');
                                        }

                                        // Smart default for correction type
                                        if ($checkInLate && $checkOutEarly) {
                                            $set('correction_type', 'both');
                                        } elseif ($checkInLate) {
                                            $set('correction_type', 'check_in');
                                        } elseif ($checkOutEarly) {
                                            $set('correction_type', 'check_out');
                                        } else {
                                            $set('correction_type', 'both');
                                        }

                                        // Set default corrected times
                                        // Biarkan sesuai waktu yang tercatat dulu, biarkan user yang memutuskan apakah perlu diubah
                                        // Check-in: gunakan waktu yang tercatat (user bisa ubah jika perlu)
                                        if ($att->check_in_time) {
                                            $set('corrected_check_in', $att->check_in_time->format('H:i'));
                                        }

                                        // Check-out: gunakan waktu yang tercatat (user bisa ubah jika perlu)
                                        // Jangan otomatis ubah ke work_end_time karena akan langsung trigger early leave detection
                                        // Biarkan user yang memutuskan apakah ingin mengubahnya menjadi lebih awal atau lebih lambat
                                        if ($att->check_out_time) {
                                            $set('corrected_check_out', $att->check_out_time->format('H:i'));
                                        }

                                        // Set simulated_request_at default when in backdate mode
                                        if ($isBackdateMode) {
                                            // Default: same day as attendance, time after checkout or 17:30
                                            $defaultTime = $att->check_out_time
                                                ? $att->check_out_time->copy()->addMinutes(15)
                                                : $att->date->copy()->setTime(17, 30);

                                            // Cap at 19:30
                                            if ($defaultTime->hour >= 20) {
                                                $defaultTime->setTime(19, 30);
                                            }

                                            $set('simulated_request_at', $defaultTime);
                                        }
                                    }
                                }
                            }),

                        Forms\Components\Placeholder::make('original_times')
                            ->label('Waktu Tercatat')
                            ->content(function ($get) {
                                $checkIn = $get('original_check_in');
                                $checkOut = $get('original_check_out');
                                $duration = $get('original_duration');
                                
                                if (!$checkIn && !$checkOut) return '-';
                                
                                $durationText = '';
                                if ($duration) {
                                    $hours = floor($duration / 60);
                                    $mins = $duration % 60;
                                    $durationText = " ({$hours}j {$mins}m)";
                                }
                                
                                return ($checkIn ?? '-') . ' - ' . ($checkOut ?? '-') . $durationText;
                            })
                            ->visible(fn($get) => $get('attendance_id')),
                    ])
                    ->visible(fn($get) => $get('form_purpose')),

                // ============ FORM KOREKSI WAKTU ============
                Forms\Components\Section::make('Perbaiki Waktu Absensi')
                    ->schema([
                        Forms\Components\Select::make('correction_type')
                            ->label('Yang Perlu Dikoreksi')
                            ->options([
                                'check_in' => 'Jam Masuk',
                                'check_out' => 'Jam Pulang',
                                'both' => 'Masuk & Pulang',
                            ])
                            ->required()
                            ->live(),

                        Forms\Components\Grid::make(2)
                            ->schema([
                                Forms\Components\TimePicker::make('corrected_check_in')
                                    ->label('Jam Masuk yang Benar')
                                    ->seconds(false)
                                    ->required(fn($get) => in_array($get('correction_type'), ['check_in', 'both']))
                                    ->visible(fn($get) => in_array($get('correction_type'), ['check_in', 'both'])),

                                Forms\Components\TimePicker::make('corrected_check_out')
                                    ->label('Jam Pulang yang Benar')
                                    ->seconds(false)
                                    ->required(fn($get) => in_array($get('correction_type'), ['check_out', 'both']))
                                    ->visible(fn($get) => in_array($get('correction_type'), ['check_out', 'both']))
                                    ->live(),
                            ]),

                        Forms\Components\Select::make('reason_type')
                            ->label('Alasan Koreksi')
                            ->options(function ($get) {
                                $type = $get('correction_type');

                                // Alasan untuk Check In
                                $checkInReasons = [
                                    'checkin_lupa_absen' => 'Sudah hadir tepat waktu tapi lupa absen masuk',
                                    'checkin_antrian' => 'Sudah hadir tepat waktu tapi antri absen lama',
                                    'checkin_hp_error' => 'HP error/mati saat akan absen masuk',
                                    'checkin_sinyal' => 'Tidak ada sinyal/internet saat absen masuk',
                                    'checkin_lokasi' => 'GPS tidak akurat, harus pindah lokasi dulu',
                                    'checkin_meeting' => 'Langsung meeting pagi, absen setelah meeting selesai',
                                    'checkin_apps_error' => 'Aplikasi error/crash saat absen masuk',
                                    'checkin_briefing' => 'Ikut briefing pagi dulu, baru sempat absen',
                                ];

                                // Alasan untuk Check Out
                                $checkOutReasons = [
                                    'checkout_lupa' => 'Lupa checkout tepat waktu, baru ingat beberapa saat kemudian',
                                    'checkout_hp_mati' => 'HP mati/lowbat saat akan checkout',
                                    'checkout_sinyal' => 'Tidak ada sinyal/internet saat akan checkout',
                                    'checkout_apps_error' => 'Aplikasi error/crash saat checkout, harus retry beberapa kali',
                                    'checkout_meeting_lanjut' => 'Ikut meeting setelah jam kerja, checkout setelah meeting selesai',
                                    'checkout_lembur_lupa' => 'Lembur tapi lupa checkout di jam pulang normal',
                                    'checkout_tugas_mendadak' => 'Ada tugas mendadak setelah jam kerja, checkout tertunda',
                                    'checkout_diskusi' => 'Diskusi dengan rekan setelah jam kerja, lupa checkout',
                                    'checkout_keesokan' => 'Baru checkout keesokan hari karena lupa',
                                    'checkout_hp_tertinggal' => 'HP tertinggal di meja saat pulang, checkout dari rumah',
                                    'checkout_antar_rekan' => 'Mengantar rekan/atasan dulu, checkout setelah sampai',
                                    'checkout_parkiran' => 'Checkout dari parkiran/kendaraan setelah keluar kantor',
                                    'checkout_macet' => 'Terjebak macet di jalan, baru sempat checkout',
                                ];

                                // Alasan umum
                                $commonReasons = [
                                    'server_error' => 'Server/sistem absensi sedang down/maintenance',
                                    'perangkat_berganti' => 'Berganti perangkat/HP baru',
                                    'baterai_habis' => 'Baterai HP habis saat akan absen',
                                    'other' => 'Lainnya (jelaskan di keterangan)',
                                ];

                                if ($type === 'check_in') {
                                    return array_merge($checkInReasons, $commonReasons);
                                } elseif ($type === 'check_out') {
                                    return array_merge($checkOutReasons, $commonReasons);
                                } else {
                                    // both
                                    return [
                                        'Jam Masuk' => $checkInReasons,
                                        'Jam Pulang' => $checkOutReasons,
                                        'Umum' => $commonReasons,
                                    ];
                                }
                            })
                            ->required()
                            ->live()
                            ->searchable()
                            ->native(false),

                        Forms\Components\Textarea::make('reason_detail')
                            ->label('Keterangan Tambahan')
                            ->rows(3)
                            ->required(fn($get) => $get('reason_type') === 'other')
                            ->visible(fn($get) => $get('reason_type') === 'other'),

                        Forms\Components\Hidden::make('reason'),
                    ])
                    ->visible(fn($get) => $get('form_purpose') === 'correction' && $get('attendance_id')),

                // ============ FORM IZIN PULANG CEPAT ============
                Forms\Components\Section::make('Alasan Izin Pulang Cepat')
                    ->schema([
                        Forms\Components\Select::make('early_leave_reason_type')
                            ->label('Alasan Pulang Lebih Awal')
                            ->options(EarlyLeaveRequest::REASON_TYPES)
                            ->required()
                            ->native(false)
                            ->live(),

                        Forms\Components\Textarea::make('early_leave_reason_detail')
                            ->label('Keterangan Detail')
                            ->rows(3)
                            ->required(fn($get) => $get('early_leave_reason_type') === 'other')
                            ->visible(fn($get) => $get('early_leave_reason_type') === 'other'),

                        Forms\Components\Hidden::make('is_early_leave')
                            ->default(true),
                    ])
                    ->visible(fn($get) => $get('form_purpose') === 'early_leave' && $get('attendance_id')),

                // ============ BACKDATE MODE ============
                Forms\Components\Section::make('Pengaturan Backdate')
                    ->schema([
                        Forms\Components\DateTimePicker::make('simulated_request_at')
                            ->label('Waktu Pengajuan')
                            ->default(function ($get) {
                                $attendanceId = $get('attendance_id');
                                if (!$attendanceId) return now();

                                $att = Attendance::find($attendanceId);
                                if (!$att) return now();

                                // Default: same day as attendance, time after checkout or 17:30
                                $defaultTime = $att->check_out_time
                                    ? $att->check_out_time->copy()->addMinutes(15)
                                    : $att->date->copy()->setTime(17, 30);

                                // Cap at 19:30
                                if ($defaultTime->hour >= 20) {
                                    $defaultTime->setTime(19, 30);
                                }

                                return $defaultTime;
                            })
                            ->minDate(function ($get) {
                                $attendanceId = $get('attendance_id');
                                if (!$attendanceId) return now()->subDays(30);

                                $att = Attendance::find($attendanceId);
                                return $att?->date ?? now()->subDays(30);
                            })
                            ->maxDate(function ($get) {
                                $attendanceId = $get('attendance_id');
                                if (!$attendanceId) return now();

                                $att = Attendance::find($attendanceId);
                                if (!$att) return now();

                                $maxDate = $att->date->copy()->addDays(14);
                                $today = now();
                                return $maxDate->lt($today) ? $maxDate : $today;
                            })
                            ->required(),
                    ])
                    ->visible($isBackdateMode)
                    ->hidden(fn($get) => !$get('attendance_id')),

                // Hidden fields for storing original values
                Forms\Components\Hidden::make('original_check_in'),
                Forms\Components\Hidden::make('original_check_out'),
                Forms\Components\Hidden::make('original_duration'),
            ]);
    }

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                Tables\Columns\TextColumn::make('target_date')
                    ->label('Tanggal')
                    ->date('d M Y')
                    ->sortable(),

                Tables\Columns\TextColumn::make('correction_type')
                    ->label('Jenis')
                    ->formatStateUsing(fn($state) => match ($state) {
                        'check_in' => 'Jam Masuk',
                        'check_out' => 'Jam Pulang',
                        'both' => 'Keduanya',
                        'duration' => 'Durasi',
                        default => $state,
                    })
                    ->badge()
                    ->color('info'),

                Tables\Columns\TextColumn::make('original_duration')
                    ->label('Durasi Asli')
                    ->formatStateUsing(function ($state) {
                        if (!$state) return '-';
                        $hours = floor($state / 60);
                        $minutes = $state % 60;
                        return "{$hours}j {$minutes}m";
                    })
                    ->color('danger'),

                Tables\Columns\TextColumn::make('corrected_values')
                    ->label('Koreksi')
                    ->getStateUsing(function ($record) {
                        $parts = [];
                        if ($record->corrected_check_in) {
                            $parts[] = 'Masuk: ' . substr($record->corrected_check_in, 0, 5);
                        }
                        if ($record->corrected_check_out) {
                            $parts[] = 'Pulang: ' . substr($record->corrected_check_out, 0, 5);
                        }
                        return implode(', ', $parts) ?: '-';
                    }),

                Tables\Columns\TextColumn::make('status')
                    ->label('Status')
                    ->badge()
                    ->color(fn($state) => match ($state) {
                        'pending' => 'warning',
                        'approved' => 'success',
                        'rejected' => 'danger',
                        default => 'gray',
                    })
                    ->formatStateUsing(fn($state) => match ($state) {
                        'pending' => 'Menunggu',
                        'approved' => 'Disetujui',
                        'rejected' => 'Ditolak',
                        default => $state,
                    }),

                Tables\Columns\TextColumn::make('created_at')
                    ->label('Diajukan')
                    ->dateTime('d M Y H:i')
                    ->sortable(),

                Tables\Columns\TextColumn::make('approver.name')
                    ->label('Diproses Oleh')
                    ->placeholder('-')
                    ->toggleable(isToggledHiddenByDefault: true),
            ])
            ->filters([
                Tables\Filters\SelectFilter::make('status')
                    ->label('Status')
                    ->options([
                        'pending' => 'Menunggu',
                        'approved' => 'Disetujui',
                        'rejected' => 'Ditolak',
                    ])
                    ->native(false),
            ])
            ->actions([
                Tables\Actions\ViewAction::make()
                    ->icon('heroicon-o-eye'),

                Tables\Actions\Action::make('cancel')
                    ->label('Batalkan')
                    ->icon('heroicon-o-x-circle')
                    ->color('danger')
                    ->visible(fn($record) => $record->status === 'pending')
                    ->requiresConfirmation()
                    ->modalHeading('Batalkan Pengajuan')
                    ->modalDescription('Apakah Anda yakin ingin membatalkan pengajuan koreksi ini?')
                    ->action(function ($record) {
                        $record->delete();

                        Notification::make()
                            ->success()
                            ->title('Pengajuan Dibatalkan')
                            ->body('Pengajuan koreksi berhasil dibatalkan.')
                            ->send();
                    }),
            ])
            ->bulkActions([])
            ->defaultSort('created_at', 'desc')
            ->striped();
    }

    public static function infolist(Infolist $infolist): Infolist
    {
        return $infolist
            ->schema([
                Infolists\Components\Section::make('Informasi Koreksi')
                    ->schema([
                        Infolists\Components\TextEntry::make('target_date')
                            ->label('Tanggal')
                            ->date('d M Y'),
                        Infolists\Components\TextEntry::make('correction_type')
                            ->label('Jenis Koreksi')
                            ->formatStateUsing(fn($state) => match ($state) {
                                'check_in' => 'Jam Masuk',
                                'check_out' => 'Jam Pulang',
                                'both' => 'Keduanya',
                                'duration' => 'Durasi',
                                default => $state,
                            })
                            ->badge()
                            ->color('info'),
                        Infolists\Components\TextEntry::make('status')
                            ->label('Status')
                            ->badge()
                            ->color(fn($state) => match ($state) {
                                'pending' => 'warning',
                                'approved' => 'success',
                                'rejected' => 'danger',
                                default => 'gray',
                            })
                            ->formatStateUsing(fn($state) => match ($state) {
                                'pending' => 'Menunggu',
                                'approved' => 'Disetujui',
                                'rejected' => 'Ditolak',
                                default => $state,
                            }),
                    ])
                    ->columns(3),

                Infolists\Components\Section::make('Perbandingan Data')
                    ->schema([
                        Infolists\Components\Grid::make(2)
                            ->schema([
                                Infolists\Components\Fieldset::make('Data Asli')
                                    ->schema([
                                        Infolists\Components\TextEntry::make('original_check_in')
                                            ->label('Jam Masuk')
                                            ->formatStateUsing(fn($state) => $state ? substr($state, 0, 5) : '-')
                                            ->placeholder('-'),
                                        Infolists\Components\TextEntry::make('original_check_out')
                                            ->label('Jam Pulang')
                                            ->formatStateUsing(fn($state) => $state ? substr($state, 0, 5) : '-')
                                            ->placeholder('-'),
                                        Infolists\Components\TextEntry::make('original_duration')
                                            ->label('Durasi')
                                            ->formatStateUsing(function ($state) {
                                                if (!$state) return '-';
                                                $hours = floor($state / 60);
                                                $minutes = $state % 60;
                                                return "{$hours}j {$minutes}m";
                                            })
                                            ->color('danger'),
                                    ]),
                                Infolists\Components\Fieldset::make('Data Koreksi')
                                    ->schema([
                                        Infolists\Components\TextEntry::make('corrected_check_in')
                                            ->label('Jam Masuk')
                                            ->formatStateUsing(fn($state) => $state ? substr($state, 0, 5) : '-')
                                            ->placeholder('-'),
                                        Infolists\Components\TextEntry::make('corrected_check_out')
                                            ->label('Jam Pulang')
                                            ->formatStateUsing(fn($state) => $state ? substr($state, 0, 5) : '-')
                                            ->placeholder('-'),
                                        Infolists\Components\TextEntry::make('corrected_duration')
                                            ->label('Durasi')
                                            ->formatStateUsing(function ($state) {
                                                if (!$state) return '-';
                                                $hours = floor($state / 60);
                                                $minutes = $state % 60;
                                                return "{$hours}j {$minutes}m";
                                            })
                                            ->color('success'),
                                    ]),
                            ]),
                    ]),

                Infolists\Components\Section::make('Alasan Koreksi')
                    ->schema([
                        Infolists\Components\TextEntry::make('reason')
                            ->label('')
                            ->placeholder('-'),
                    ]),

                Infolists\Components\Section::make('Informasi Proses')
                    ->schema([
                        Infolists\Components\TextEntry::make('created_at')
                            ->label('Tanggal Pengajuan')
                            ->dateTime('d M Y H:i'),
                        Infolists\Components\TextEntry::make('approver.name')
                            ->label('Diproses Oleh')
                            ->placeholder('-'),
                        Infolists\Components\TextEntry::make('approved_at')
                            ->label('Tanggal Proses')
                            ->dateTime('d M Y H:i')
                            ->placeholder('-'),
                        Infolists\Components\TextEntry::make('rejection_reason')
                            ->label('Alasan Penolakan')
                            ->placeholder('-')
                            ->visible(fn($record) => $record->status === 'rejected')
                            ->columnSpanFull(),
                    ])
                    ->columns(3),
            ]);
    }

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

    public static function getPages(): array
    {
        return [
            'index' => Pages\ListMyCorrections::route('/'),
            'create' => Pages\CreateMyCorrection::route('/create'),
            'view' => Pages\ViewMyCorrection::route('/{record}'),
        ];
    }

    public static function getEloquentQuery(): Builder
    {
        $user = auth()->user();

        return parent::getEloquentQuery()
            ->with(['attendance', 'approver'])
            ->where('user_id', $user?->id)
            ->orderBy('created_at', 'desc');
    }
}
