<?php

namespace Database\Seeders;

use App\Models\AttendanceLog;
use App\Models\AttendanceRecord;
use App\Models\FingerprintMachine;
use App\Models\Role;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class AttendanceSeeder extends Seeder
{
    public function run(): void
    {
        $machines = FingerprintMachine::orderBy('id')->get();
        if ($machines->isEmpty()) {
            return;
        }

        $siswaRoleId = Role::where('name', 'siswa')->value('id');
        $guruRoleId = Role::where('name', 'guru')->value('id');

        $users = User::whereIn('role_id', array_filter([$siswaRoleId, $guruRoleId]))
            ->where('is_active', true)
            ->where('student_status', 'aktif')
            ->get();

        if ($users->isEmpty()) {
            return;
        }

        $lobby = $machines->firstWhere('name', 'Mesin Fingerprint 1 - Lobby Utama') ?? $machines->first();
        $guruMachine = $machines->firstWhere('name', 'Mesin Fingerprint 2 - Ruang Guru & TU') ?? $machines->get(1, $lobby);

        $statusesCycle = ['Hadir', 'Hadir', 'Hadir', 'Terlambat', 'Hadir', 'Alpha', 'Hadir', 'Sakit', 'Hadir', 'Izin'];

        $schoolDays = [];
        $cursor = Carbon::today();
        while (count($schoolDays) < 14) {
            if (!$cursor->isWeekend()) {
                $schoolDays[] = $cursor->copy();
            }
            $cursor->subDay();
        }
        $schoolDays = array_reverse($schoolDays);

        $now = now()->toDateTimeString();
        $records = [];
        $logs = [];

        foreach ($users as $userIndex => $user) {
            $isTeacher = (int) $user->role_id === (int) $guruRoleId;
            $machineId = ($isTeacher ? $guruMachine : $lobby)->id;

            foreach ($schoolDays as $dayIndex => $day) {
                $status = $statusesCycle[($userIndex + $dayIndex) % count($statusesCycle)];

                if (!$isTeacher && $userIndex % 7 === 0 && $dayIndex >= 10) {
                    $status = 'Alpha';
                }

                $checkIn = null;
                $checkOut = null;

                if (in_array($status, ['Hadir', 'Terlambat'], true)) {
                    $checkIn = $status === 'Terlambat'
                        ? sprintf('07:%02d:00', 20 + ($userIndex % 25))
                        : sprintf('06:%02d:00', 40 + ($userIndex % 20));

                    $checkOut = $isTeacher
                        ? sprintf('15:%02d:00', 20 + ($userIndex % 20))
                        : sprintf('14:%02d:00', 45 + ($userIndex % 15));

                    $logs[] = [
                        'machine_id' => $machineId,
                        'raw_user_id' => $user->fingerprint_pin ?: $user->nip_nis,
                        'timestamp' => $day->copy()->setTimeFromTimeString($checkIn)->toDateTimeString(),
                        'is_processed' => true,
                        'created_at' => $now,
                        'updated_at' => $now,
                    ];

                    $logs[] = [
                        'machine_id' => $machineId,
                        'raw_user_id' => $user->fingerprint_pin ?: $user->nip_nis,
                        'timestamp' => $day->copy()->setTimeFromTimeString($checkOut)->toDateTimeString(),
                        'is_processed' => true,
                        'created_at' => $now,
                        'updated_at' => $now,
                    ];
                }

                $records[] = [
                    'user_id' => $user->id,
                    'date' => $day->toDateString(),
                    'check_in' => $checkIn,
                    'check_out' => $checkOut,
                    'status' => $status,
                    'created_at' => $now,
                    'updated_at' => $now,
                ];
            }
        }

        // Log belum diproses (antrian sync terbaru)
        foreach ($users->take(5)->values() as $i => $user) {
            $logs[] = [
                'machine_id' => $lobby->id,
                'raw_user_id' => $user->fingerprint_pin ?: $user->nip_nis,
                'timestamp' => now()->subMinutes(30 - $i)->toDateTimeString(),
                'is_processed' => false,
                'created_at' => $now,
                'updated_at' => $now,
            ];
        }

        AttendanceRecord::query()->delete();
        AttendanceLog::query()->delete();

        foreach (array_chunk($records, 200) as $chunk) {
            DB::table('attendance_records')->insert($chunk);
        }

        foreach (array_chunk($logs, 200) as $chunk) {
            DB::table('attendance_logs')->insert($chunk);
        }
    }
}
