<?php
require_once '../../config/config.php';
require_once '../helper/audit_log.php';

header('Content-Type: application/json');

// Include the invigilator assignment function with consecutive day prevention
function assignInvigilatorsToHall($pdo, $timetableId, $hallId, $numStudents) {
    try {
        // Clear existing invigilation duties for this hall and timetable
        $clearStmt = $pdo->prepare("DELETE FROM invigilation_duty WHERE timetable_id = ? AND hall_id = ?");
        $clearStmt->execute([$timetableId, $hallId]);

        // Get available invigilators (staff with role 'Invigilator' and status 'Active')
        $invigilatorsStmt = $pdo->prepare("
            SELECT staff_id, first_name, last_name, staff_code 
            FROM staff 
            WHERE role = 'Invigilator' AND status = 'Active' 
            ORDER BY RAND()
        ");
        $invigilatorsStmt->execute();
        $invigilators = $invigilatorsStmt->fetchAll(PDO::FETCH_ASSOC);

        if (empty($invigilators)) {
            error_log("No active invigilators found");
            return 0;
        }

        // Calculate number of invigilators needed based on hall capacity
        // Rule: 1 invigilator per 30 students, minimum 1, maximum 3
        $invigilatorsNeeded = max(1, min(3, ceil($numStudents / 30)));
        
        // Select invigilators (avoid duplicates and consecutive day assignments)
        $selectedInvigilators = [];
        $usedInvigilators = [];
        
        // Get invigilators already assigned to other halls in same timetable
        $usedStmt = $pdo->prepare("
            SELECT DISTINCT staff_id 
            FROM invigilation_duty 
            WHERE timetable_id = ? AND hall_id != ?
        ");
        $usedStmt->execute([$timetableId, $hallId]);
        $usedInvigilators = $usedStmt->fetchAll(PDO::FETCH_COLUMN);
        
        // Get invigilators assigned to same hall on consecutive days (previous day)
        $consecutiveDayStmt = $pdo->prepare("
            SELECT DISTINCT id.staff_id 
            FROM invigilation_duty id
            JOIN exam_timetable et ON id.timetable_id = et.timetable_id
            JOIN exam_timetable current_et ON current_et.timetable_id = ?
            WHERE id.hall_id = ? 
            AND et.exam_date = DATE_SUB(current_et.exam_date, INTERVAL 1 DAY)
            AND et.session = current_et.session
        ");
        $consecutiveDayStmt->execute([$timetableId, $hallId]);
        $consecutiveDayInvigilators = $consecutiveDayStmt->fetchAll(PDO::FETCH_COLUMN);
        
        // Combine both exclusion lists
        $excludedInvigilators = array_unique(array_merge($usedInvigilators, $consecutiveDayInvigilators));

        foreach ($invigilators as $invigilator) {
            if (count($selectedInvigilators) >= $invigilatorsNeeded) break;
            
            // Skip if already assigned to another hall in same timetable OR same hall on consecutive day
            if (in_array($invigilator['staff_id'], $excludedInvigilators)) continue;
            
            $selectedInvigilators[] = $invigilator;
        }

        // If we don't have enough unique invigilators, assign any available ones
        // (This fallback may include consecutive day assignments if no other options)
        if (count($selectedInvigilators) < $invigilatorsNeeded) {
            foreach ($invigilators as $invigilator) {
                if (count($selectedInvigilators) >= $invigilatorsNeeded) break;
                if (!in_array($invigilator['staff_id'], array_column($selectedInvigilators, 'staff_id'))) {
                    $selectedInvigilators[] = $invigilator;
                }
            }
        }

        // Assign invigilators to the hall
        $dutyStmt = $pdo->prepare("
            INSERT INTO invigilation_duty (staff_id, timetable_id, hall_id, role, status) 
            VALUES (?, ?, ?, ?, 'Assigned')
        ");

        foreach ($selectedInvigilators as $index => $invigilator) {
            $role = ($index === 0) ? 'Chief Invigilator' : 'Invigilator';
            $dutyStmt->execute([
                $invigilator['staff_id'],
                $timetableId,
                $hallId,
                $role
            ]);
        }

        error_log("Assigned " . count($selectedInvigilators) . " invigilators to hall $hallId for timetable $timetableId");

        // Log invigilator assignment
        write_audit_log($pdo, [
            'module' => 'Hall Allocations & Invigilation',
            'action' => 'create',
            'entity_table' => 'invigilation_duty',
            'entity_id' => 'hall_' . $hallId . '_timetable_' . $timetableId,
            'after_data' => [
                'hall_id' => $hallId,
                'timetable_id' => $timetableId,
                'num_students' => $numStudents,
                'invigilators_assigned' => count($selectedInvigilators),
                'invigilators' => $selectedInvigilators,
                'consecutive_day_prevention' => count($consecutiveDayInvigilators) > 0,
                'excluded_consecutive_invigilators' => count($consecutiveDayInvigilators)
            ],
            'message' => 'Assigned invigilators to hall allocation (with consecutive day prevention)'
        ]);

        return count($selectedInvigilators);

    } catch (Exception $e) {
        error_log("Error assigning invigilators: " . $e->getMessage());
        return 0;
    }
}

try {
    $allocationId = (int)($_POST['allocation_id'] ?? 0);
    
    if ($allocationId <= 0) {
        throw new Exception('Valid allocation ID is required');
    }

    // Get allocation details
    $allocationStmt = $pdo->prepare("
        SELECT 
            ha.allocation_id,
            ha.timetable_id,
            ha.hall_id,
            ha.num_students,
            h.hall_name,
            et.exam_date,
            et.session,
            sub.subject_code,
            sub.subject_name
        FROM hall_allocations ha
        JOIN halls h ON ha.hall_id = h.hall_id
        JOIN exam_timetable et ON ha.timetable_id = et.timetable_id
        JOIN exam_subjects es ON et.exam_subject_id = es.exam_subject_id
        JOIN subjects sub ON es.subject_id = sub.subject_id
        WHERE ha.allocation_id = ?
    ");
    
    $allocationStmt->execute([$allocationId]);
    $allocation = $allocationStmt->fetch(PDO::FETCH_ASSOC);

    if (!$allocation) {
        throw new Exception('Hall allocation not found');
    }

    // Update invigilators for this allocation
    $invigilatorsAssigned = updateInvigilatorsForAllocation(
        $pdo, 
        (int)$allocation['timetable_id'], 
        (int)$allocation['hall_id'], 
        (int)$allocation['num_students']
    );

    // Log the single allocation update
    write_audit_log($pdo, [
        'module' => 'Hall Allocations & Invigilation',
        'action' => 'update',
        'entity_table' => 'invigilation_duty',
        'entity_id' => 'allocation_' . $allocationId,
        'after_data' => [
            'allocation_id' => $allocationId,
            'hall_name' => $allocation['hall_name'],
            'invigilators_assigned' => $invigilatorsAssigned,
            'num_students' => $allocation['num_students'],
            'exam_details' => [
                'subject' => $allocation['subject_code'] . ' - ' . $allocation['subject_name'],
                'date' => $allocation['exam_date'],
                'session' => $allocation['session']
            ]
        ],
        'message' => 'Updated invigilators for single hall allocation'
    ]);

    echo json_encode([
        'status' => 'success',
        'message' => 'Invigilators updated successfully for this allocation',
        'allocation_id' => $allocationId,
        'hall_name' => $allocation['hall_name'],
        'invigilators_assigned' => $invigilatorsAssigned,
        'num_students' => $allocation['num_students'],
        'exam_details' => [
            'subject' => $allocation['subject_code'] . ' - ' . $allocation['subject_name'],
            'date' => $allocation['exam_date'],
            'session' => $allocation['session']
        ]
    ]);

} catch (Exception $e) {
    http_response_code(500);
    echo json_encode([
        'status' => 'error',
        'message' => $e->getMessage()
    ]);
}

/**
 * Update invigilators for a specific hall allocation
 * @param PDO $pdo Database connection
 * @param int $timetableId Timetable ID
 * @param int $hallId Hall ID
 * @param int $numStudents Number of students in the hall
 * @return int Number of invigilators assigned
 */
function updateInvigilatorsForAllocation($pdo, $timetableId, $hallId, $numStudents) {
    try {
        // Clear existing invigilation duties for this hall and timetable
        $clearStmt = $pdo->prepare("DELETE FROM invigilation_duty WHERE timetable_id = ? AND hall_id = ?");
        $clearStmt->execute([$timetableId, $hallId]);

        // Get available invigilators (staff with role 'Invigilator')
        $invigilatorsStmt = $pdo->prepare("
            SELECT staff_id, first_name, last_name, staff_code
            FROM staff 
            WHERE role = 'Invigilator' AND status = 'Active'
            ORDER BY RAND()
        ");
        $invigilatorsStmt->execute();
        $invigilators = $invigilatorsStmt->fetchAll(PDO::FETCH_ASSOC);

        if (empty($invigilators)) {
            error_log("No invigilators available for hall $hallId");
            return 0;
        }

        // Calculate number of invigilators needed based on hall capacity
        // Rule: 1 invigilator per 30 students, minimum 1, maximum 3
        $invigilatorsNeeded = max(1, min(3, ceil($numStudents / 30)));
        
        // Select invigilators (avoid duplicates by checking existing duties for same timetable)
        $selectedInvigilators = [];
        $usedInvigilators = [];
        
        // Get invigilators already assigned to other halls in same timetable
        $usedStmt = $pdo->prepare("
            SELECT DISTINCT staff_id 
            FROM invigilation_duty 
            WHERE timetable_id = ? AND hall_id != ?
        ");
        $usedStmt->execute([$timetableId, $hallId]);
        $usedInvigilators = $usedStmt->fetchAll(PDO::FETCH_COLUMN);

        foreach ($invigilators as $invigilator) {
            if (count($selectedInvigilators) >= $invigilatorsNeeded) break;
            
            // Skip if already assigned to another hall in same timetable
            if (in_array($invigilator['staff_id'], $usedInvigilators)) continue;
            
            $selectedInvigilators[] = $invigilator;
        }

        // If we don't have enough unique invigilators, assign any available ones
        if (count($selectedInvigilators) < $invigilatorsNeeded) {
            foreach ($invigilators as $invigilator) {
                if (count($selectedInvigilators) >= $invigilatorsNeeded) break;
                if (!in_array($invigilator['staff_id'], array_column($selectedInvigilators, 'staff_id'))) {
                    $selectedInvigilators[] = $invigilator;
                }
            }
        }

        // Assign invigilators to the hall
        $dutyStmt = $pdo->prepare("
            INSERT INTO invigilation_duty (staff_id, timetable_id, hall_id, role, status) 
            VALUES (?, ?, ?, ?, 'Assigned')
        ");

        foreach ($selectedInvigilators as $index => $invigilator) {
            $role = ($index === 0) ? 'Chief Invigilator' : 'Invigilator';
            $dutyStmt->execute([
                $invigilator['staff_id'],
                $timetableId,
                $hallId,
                $role
            ]);
        }

        error_log("Updated invigilators for hall $hallId: " . count($selectedInvigilators) . " invigilators assigned");
        return count($selectedInvigilators);

    } catch (Exception $e) {
        error_log("Error updating invigilators for hall $hallId: " . $e->getMessage());
        return 0;
    }
}
?>
