<?php

namespace App\Modules\HR\Attendance\Services\ExceptionDetection;

use App\Modules\HR\Attendance\Contracts\AttendanceExceptionDetectionRule;
use App\Modules\HR\Attendance\Models\AttendanceRecord;
use App\Modules\HR\Attendance\Repositories\AttendanceExceptionRepository;
use App\Modules\HR\Attendance\Support\AttendanceExceptionDedupeKey;
use App\Modules\HR\Attendance\Support\AttendanceExceptionSeverity;
use App\Modules\HR\Attendance\Support\AttendanceExceptionType;
use Carbon\CarbonImmutable;

class SuspiciousAttendanceExceptionRule implements AttendanceExceptionDetectionRule
{
    public function __construct(
        private readonly AttendanceExceptionRepository $exceptions,
    ) {}

    public function run(int $tenantId, CarbonImmutable $from, CarbonImmutable $to): int
    {
        $maxMin = (int) config('attendance.suspicious_duration_max_minutes', 15);
        $created = 0;

        AttendanceRecord::query()
            ->where('tenant_id', $tenantId)
            ->whereBetween('attendance_date', [$from->toDateString(), $to->toDateString()])
            ->whereNotNull('check_in_at')
            ->whereNotNull('check_out_at')
            ->chunkById(500, function ($chunk) use ($tenantId, $maxMin, &$created): void {
                foreach ($chunk as $record) {
                    $mins = $record->check_in_at->diffInMinutes($record->check_out_at);
                    if ($mins > $maxMin) {
                        continue;
                    }
                    $dayKey = $record->attendance_date->toDateString();
                    $key = AttendanceExceptionDedupeKey::forRecordType(
                        $tenantId,
                        (int) $record->employee_id,
                        (int) $record->id,
                        AttendanceExceptionType::SUSPICIOUS_ATTENDANCE,
                        $dayKey,
                    );
                    $created += (int) $this->exceptions->tryInsert(
                        $tenantId,
                        (int) $record->employee_id,
                        (int) $record->id,
                        AttendanceExceptionType::SUSPICIOUS_ATTENDANCE,
                        AttendanceExceptionSeverity::LOW,
                        $key,
                        ['duration_minutes' => $mins],
                    );
                }
            });

        return $created;
    }
}
