<?php
require_once __DIR__ . '/../includes/db.php';

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}
$_SESSION['company_id'] = 1;
$_SESSION['user_id'] = 1;
$company_id = $_SESSION['company_id'];

echo "========================================\n";
echo "Payroll Days Present Logic Test Suite\n";
echo "========================================\n";

try {
    // 1. Create a dummy employee
    $empName = "Test Candidate " . uniqid();
    query("INSERT INTO employees (company_id, name, hourly_rate, is_active, role_id) VALUES (?, ?, 10.00, 1, 1)", [$company_id, $empName]);
    $emp = fetch("SELECT * FROM employees WHERE name = ?", [$empName]);
    $empId = $emp['id'];

    // 2. Create a dummy shift with working_hours = 9.00 and minimum_working_hours = 8.00
    query("
        INSERT INTO shifts (company_id, name, start_time, end_time, working_hours, minimum_working_hours)
        VALUES (?, 'Test Shift', '08:00:00', '17:00:00', 9.00, 8.00)
    ", [$company_id]);
    $shift = fetch("SELECT * FROM shifts WHERE name = 'Test Shift' AND company_id = ?", [$company_id]);
    
    // Assign shift to employee
    query("UPDATE employees SET shift_id = ? WHERE id = ?", [$shift['id'], $empId]);

    // Define test periods
    $firstDay = "2026-06-01";
    $lastDay = "2026-06-03"; // 3 calendar days: June 1, 2, and 3

    // Clean any existing attendance and leave requests for the mock employee
    query("DELETE FROM attendance WHERE employee_id = ?", [$empId]);
    query("DELETE FROM leave_requests WHERE employee_id = ?", [$empId]);

    // Scenario A: June 1 -> Employee worked 9 hours (08:00 to 17:00) -> Exceeds min hours (8.00) -> SHOULD BE PRESENT
    query("INSERT INTO attendance (employee_id, company_id, date, clock_in, clock_out) VALUES (?, ?, '2026-06-01', '2026-06-01 08:00:00', '2026-06-01 17:00:00')", [$empId, $company_id]);

    // Scenario B: June 2 -> Employee worked 7 hours (08:00 to 15:00) -> Less than min hours (8.00), NO approved leave -> SHOULD NOT BE PRESENT (Absent)
    query("INSERT INTO attendance (employee_id, company_id, date, clock_in, clock_out) VALUES (?, ?, '2026-06-02', '2026-06-02 08:00:00', '2026-06-02 15:00:00')", [$empId, $company_id]);

    // Scenario C: June 3 -> Employee worked 4 hours (08:00 to 12:00) -> Less than min hours (8.00), but has APPROVED half-day leave -> SHOULD BE PRESENT
    query("INSERT INTO attendance (employee_id, company_id, date, clock_in, clock_out) VALUES (?, ?, '2026-06-03', '2026-06-03 08:00:00', '2026-06-03 12:00:00')", [$empId, $company_id]);
    query("
        INSERT INTO leave_requests (employee_id, company_id, duration_type, start_date, end_date, reason, status, leave_type)
        VALUES (?, ?, 'half_day', '2026-06-03', '2026-06-03', 'Doctor appointment', 'approved', 'casual')
    ", [$empId, $company_id]);

    // --- Execute calculation logic in a mock block similar to the API ---
    
    // Fetch employee shift details (working hours & minimum working hours)
    $empShift = fetch("
        SELECT s.working_hours, s.minimum_working_hours 
        FROM employees e
        LEFT JOIN shifts s ON e.shift_id = s.id
        WHERE e.id = ?
    ", [$empId]);
    $std_hours = $empShift && $empShift['working_hours'] !== null ? (float)$empShift['working_hours'] : 8.00;
    $min_hours = $empShift && $empShift['minimum_working_hours'] !== null ? (float)$empShift['minimum_working_hours'] : 0.00;

    // Fetch attendance sessions
    $sessions = fetchAll("
        SELECT clock_in, clock_out, date FROM attendance 
        WHERE employee_id = ? AND company_id = ? AND date BETWEEN ? AND ?
    ", [$empId, $company_id, $firstDay, $lastDay]);
    
    $dailySeconds = [];
    foreach ($sessions as $s) {
        if ($s['clock_out']) {
            $dt = $s['date'];
            if (!isset($dailySeconds[$dt])) {
                $dailySeconds[$dt] = 0;
            }
            $dailySeconds[$dt] += strtotime($s['clock_out']) - strtotime($s['clock_in']);
        }
    }
    
    $dailyWorkedHours = [];
    $regularHours = 0;
    foreach ($dailySeconds as $dt => $sec) {
        $dayHrs = round($sec / 3600, 2);
        $dailyWorkedHours[$dt] = $dayHrs;
        $regularHours += min($dayHrs, $std_hours);
    }
    
    // Fetch approved leaves
    $leaves = fetchAll("
        SELECT duration_type, start_date, end_date FROM leave_requests 
        WHERE employee_id = ? AND company_id = ? AND status = 'approved'
          AND (start_date <= ? AND end_date >= ?)
    ", [$empId, $company_id, $lastDay, $firstDay]);
    
    $leaveDates = [];
    foreach ($leaves as $l) {
        $lStart = new DateTime($l['start_date']);
        $lEnd = new DateTime($l['end_date']);
        $current = clone $lStart;
        while ($current <= $lEnd) {
            $dateStr = $current->format('Y-m-d');
            if ($dateStr >= $firstDay && $dateStr <= $lastDay) {
                $leaveDates[$dateStr] = true;
            }
            $current->modify('+1 day');
        }
    }
    
    // Determine unique days present (Worked >= Min Hours OR has Approved Leave)
    $presentDates = [];
    foreach ($dailyWorkedHours as $dt => $hrs) {
        if ($hrs >= $min_hours) {
            $presentDates[$dt] = true;
        }
    }
    foreach ($leaveDates as $dt => $val) {
        $presentDates[$dt] = true;
    }
    $daysPresent = count($presentDates);

    // --- Verify outcomes ---
    echo "Employee Shift Minimum Hours: " . $min_hours . "\n";
    echo "Daily Worked Hours: " . json_encode($dailyWorkedHours) . "\n";
    echo "Approved Leave Dates: " . json_encode(array_keys($leaveDates)) . "\n";
    echo "Calculated Days Present: " . $daysPresent . "\n";

    // June 1 and June 3 should count as present. June 2 should not. Total present should be exactly 2.
    if ($daysPresent === 2) {
        echo "[PASS] Days Present calculated correctly as 2 (June 1 & June 3).\n";
    } else {
        throw new Exception("Days Present calculation failed: expected 2, got " . $daysPresent);
    }

    if (isset($presentDates['2026-06-01'])) {
        echo "[PASS] June 1 (worked >= min hours) is present.\n";
    } else {
        throw new Exception("June 1 should be marked present.");
    }

    if (!isset($presentDates['2026-06-02'])) {
        echo "[PASS] June 2 (worked < min hours, no leave) is absent.\n";
    } else {
        throw new Exception("June 2 should be marked absent.");
    }

    if (isset($presentDates['2026-06-03'])) {
        echo "[PASS] June 3 (worked < min hours, but has approved leave) is present.\n";
    } else {
        throw new Exception("June 3 should be marked present.");
    }

    // Cleanup mock records
    query("DELETE FROM attendance WHERE employee_id = ?", [$empId]);
    query("DELETE FROM leave_requests WHERE employee_id = ?", [$empId]);
    query("DELETE FROM employees WHERE id = ?", [$empId]);
    query("DELETE FROM shifts WHERE id = ?", [$shift['id']]);
    echo "[PASS] Cleanup complete. All mock test records removed.\n";

    echo "========================================\n";
    echo "ALL TESTS PASSED SUCCESSFULLY!\n";
    echo "========================================\n";

} catch (Exception $e) {
    echo "[FAIL] Test failed: " . $e->getMessage() . "\n";
    // Cleanup if mock records exist
    if (isset($empId)) {
        query("DELETE FROM attendance WHERE employee_id = ?", [$empId]);
        query("DELETE FROM leave_requests WHERE employee_id = ?", [$empId]);
        query("DELETE FROM employees WHERE id = ?", [$empId]);
    }
    if (isset($shift['id'])) {
        query("DELETE FROM shifts WHERE id = ?", [$shift['id']]);
    }
    exit(1);
}
