<?php

use App\Enums\UserType;
use App\Models\BusinessSetting;
use App\Models\Department;
use App\Models\EmployeeProfile;
use App\Models\LeaveType;
use App\Models\User;
use App\Services\AttendanceService;
use App\Services\LeaveService;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

test('leave requests without reporting manager are sent directly to admin queue', function () {
    $department = Department::factory()->create();
    $manager = User::factory()->create(['type' => UserType::ADMIN]);
    $employeeWithManager = User::factory()->create(['type' => UserType::ADMIN]);
    $employeeWithoutManager = User::factory()->create(['type' => UserType::ADMIN]);

    EmployeeProfile::factory()->create([
        'user_id' => $employeeWithManager->id,
        'department_id' => $department->id,
        'manager_id' => $manager->id,
    ]);

    EmployeeProfile::factory()->create([
        'user_id' => $employeeWithoutManager->id,
        'department_id' => $department->id,
        'manager_id' => null,
    ]);

    $leaveType = LeaveType::query()->create([
        'name' => 'Annual',
        'color' => '#3b82f6',
        'icon' => 'Calendar',
        'is_paid' => true,
        'default_allowance' => 10,
        'status' => true,
    ]);

    /** @var LeaveService $leaveService */
    $leaveService = app(LeaveService::class);

    $directRequest = $leaveService->createRequest([
        'leave_type_id' => $leaveType->id,
        'start_date' => now()->toDateString(),
        'end_date' => now()->toDateString(),
        'reason' => 'Medical checkup',
    ], $employeeWithoutManager);

    expect($directRequest->status)->toBe('pending_admin');
    expect($directRequest->manager_id)->toBeNull();

    $managerFlowRequest = $leaveService->createRequest([
        'leave_type_id' => $leaveType->id,
        'start_date' => now()->toDateString(),
        'end_date' => now()->toDateString(),
        'reason' => 'Family event',
    ], $employeeWithManager);

    expect($managerFlowRequest->status)->toBe('pending_manager');
    expect($managerFlowRequest->manager_id)->toBe($manager->id);
});

test('attendance anomalies without reporting manager are sent directly to admin queue', function () {
    $department = Department::factory()->create();
    $manager = User::factory()->create(['type' => UserType::ADMIN]);
    $employeeWithManager = User::factory()->create(['type' => UserType::ADMIN]);
    $employeeWithoutManager = User::factory()->create(['type' => UserType::ADMIN]);

    EmployeeProfile::factory()->create([
        'user_id' => $employeeWithManager->id,
        'department_id' => $department->id,
        'manager_id' => $manager->id,
    ]);

    EmployeeProfile::factory()->create([
        'user_id' => $employeeWithoutManager->id,
        'department_id' => $department->id,
        'manager_id' => null,
    ]);

    BusinessSetting::query()->updateOrCreate(['key' => 'shift_start_time'], ['value' => now()->subHour()->format('H:i'), 'type' => 'string']);
    BusinessSetting::query()->updateOrCreate(['key' => 'shift_end_time'], ['value' => now()->addHours(8)->format('H:i'), 'type' => 'string']);
    BusinessSetting::query()->updateOrCreate(['key' => 'timezone'], ['value' => config('app.timezone'), 'type' => 'string']);

    /** @var AttendanceService $attendanceService */
    $attendanceService = app(AttendanceService::class);

    $attendanceWithoutManager = $attendanceService->clockIn($employeeWithoutManager);
    $attendanceWithManager = $attendanceService->clockIn($employeeWithManager);

    expect($attendanceWithoutManager->fresh()->anomaly_status)->toBe('pending_admin');
    expect($attendanceWithManager->fresh()->anomaly_status)->toBe('pending_manager');
});
