<?php
declare(strict_types=1);

namespace CronJobs;

use App\Core\Database;
use App\Core\Logger;

/**
 * Daily (midnight): auto-closes attendance records where employee checked in but never checked out.
 * Sets check_out to end of scheduled shift or 8 hours after check_in, whichever is earlier.
 */
class HrAttendanceAutoCloseJob
{
    private Database $db;
    public function __construct(Database $db) { $this->db = $db; }

    public function shouldRun(): bool
    {
        return true; // Runs daily
    }

    public function run(): array
    {
        $yesterday = date('Y-m-d', strtotime('-1 day'));
        $closed = 0;

        // Find attendance records from yesterday (or older) with check_in but no check_out
        $openRecords = $this->db->select(
            "SELECT a.id, a.employee_profile_id, a.attendance_date, a.check_in_time,
                    es.schedule_id,
                    ws.days_config_json
             FROM hr_attendance a
             LEFT JOIN hr_employee_schedules es ON es.employee_profile_id = a.employee_profile_id
                  AND es.is_active = 1
             LEFT JOIN hr_work_schedules ws ON ws.id = es.schedule_id AND ws.is_archived = 0
             WHERE a.check_in_time IS NOT NULL
               AND a.check_out_time IS NULL
               AND a.attendance_date <= ?
               AND a.is_archived = 0",
            [$yesterday]
        );

        foreach ($openRecords as $rec) {
            $checkIn = $rec['check_in_time'];
            $attDate = $rec['attendance_date'];

            // Determine check_out time: try schedule end time, fallback to 8 hours after check_in
            $checkOut = null;
            if (!empty($rec['days_config_json'])) {
                $daysConfig = json_decode($rec['days_config_json'], true);
                if (is_array($daysConfig)) {
                    $dayOfWeek = (int) date('w', strtotime($attDate)); // 0=Sun, 6=Sat
                    $dayKey = ['sunday','monday','tuesday','wednesday','thursday','friday','saturday'][$dayOfWeek] ?? '';
                    if (isset($daysConfig[$dayKey]['end_time'])) {
                        $checkOut = $daysConfig[$dayKey]['end_time'];
                    }
                }
            }

            if (!$checkOut) {
                // Fallback: 8 hours after check_in
                $checkOut = date('H:i:s', strtotime($checkIn) + (8 * 3600));
            }

            // Calculate actual hours
            $inTime = strtotime($attDate . ' ' . $checkIn);
            $outTime = strtotime($attDate . ' ' . $checkOut);
            if ($outTime <= $inTime) {
                $outTime = $inTime + (8 * 3600); // Prevent negative/zero hours
            }
            $actualHours = round(($outTime - $inTime) / 3600, 2);

            $this->db->update('hr_attendance', [
                'check_out_time' => $checkOut,
                'actual_hours' => $actualHours,
                'notes'        => 'تم إغلاق الحضور تلقائياً - لم يسجل الموظف انصرافه',
                'updated_at'   => date('Y-m-d H:i:s'),
            ], '`id` = ?', [(int) $rec['id']]);
            $closed++;
        }

        if ($closed > 0) {
            Logger::info("HR Attendance Auto-Close Job: {$closed} records auto-closed for {$yesterday} and earlier");
        }

        return ['closed' => $closed];
    }
}
