<?php

namespace Tests\Unit;

use App\Enums\AttendanceStatusEnum;
use App\Models\AttendanceLog;
use App\Models\AttendanceRecord;
use App\Models\FingerprintMachine;
use App\Models\Shift;
use App\Models\User;
use App\Services\AttendanceProcessorService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class AttendanceProcessorServiceTest extends TestCase
{
    use RefreshDatabase;

    protected AttendanceProcessorService $processorService;

    protected function setUp(): void
    {
        parent::setUp();
        $this->seed();
        $this->processorService = app(AttendanceProcessorService::class);
    }

    public function test_user_checking_in_on_time_is_marked_hadir(): void
    {
        AttendanceLog::query()->where('is_processed', false)->delete();

        $guruShift = Shift::where('name', 'Shift Guru & Staf TU')->first()
            ?? Shift::where('name', 'Shift Guru')->first();
        $user = User::factory()->create([
            'nip_nis' => '199001012020011010',
            'shift_id' => $guruShift->id,
            'fingerprint_pin' => '991010',
        ]);

        $machine = FingerprintMachine::first();

        // Raw log at 06:55 AM (Shift Guru starts 07:00 AM)
        AttendanceLog::create([
            'machine_id' => $machine->id,
            'raw_user_id' => '991010',
            'timestamp' => '2026-07-28 06:55:00',
            'is_processed' => false,
        ]);

        $processed = $this->processorService->processUnprocessedLogs();

        $this->assertEquals(1, $processed);

        $record = AttendanceRecord::where('user_id', $user->id)->first();
        $this->assertNotNull($record);
        $this->assertEquals(AttendanceStatusEnum::HADIR->value, $record->status);
        $this->assertEquals('06:55:00', $record->check_in);
    }

    public function test_user_checking_in_late_is_marked_terlambat(): void
    {
        AttendanceLog::query()->where('is_processed', false)->delete();

        $guruShift = Shift::where('name', 'Shift Guru & Staf TU')->first()
            ?? Shift::where('name', 'Shift Guru')->first();
        $user = User::factory()->create([
            'nip_nis' => '199001012020011011',
            'shift_id' => $guruShift->id,
            'fingerprint_pin' => '991011',
        ]);

        $machine = FingerprintMachine::first();

        // Use 07:20 to be past grace of 15 minutes
        AttendanceLog::create([
            'machine_id' => $machine->id,
            'raw_user_id' => '991011',
            'timestamp' => '2026-07-28 07:20:00',
            'is_processed' => false,
        ]);

        $processed = $this->processorService->processUnprocessedLogs();

        $this->assertEquals(1, $processed);

        $record = AttendanceRecord::where('user_id', $user->id)->first();
        $this->assertNotNull($record);
        $this->assertEquals(AttendanceStatusEnum::TERLAMBAT->value, $record->status);
    }
}
