<?php ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once('../../../' . $_REQUEST['tenant'] . '/config.php');

$client_id = (int)($_POST['client_id'] ?? 0);
$surveyor_id = (int)($_POST['surveyor_id'] ?? 0);
$appointment_date = (int)($_POST['appointment_date'] ?? 0); // Already a Unix timestamp from the JavaScript
$start_time = !empty($_POST['start_time']) ? (int)$_POST['start_time'] : null;
$end_time = !empty($_POST['end_time']) ? (int)$_POST['end_time'] : null;
$location_id = !empty($_POST['location_id']) ? (int)$_POST['location_id'] : null;
$asset_id = !empty($_POST['asset_id']) ? (int)$_POST['asset_id'] : null;
$notes = trim((string)($_POST['notes'] ?? ''));

function adminAssignmentColumnExists(mysqli $con, string $column): bool
{
    $stmt = $con->prepare("SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'admin_assignments' AND COLUMN_NAME = ? LIMIT 1");
    if (!$stmt) return false;
    $stmt->bind_param('s', $column);
    $stmt->execute();
    $stmt->store_result();
    $exists = $stmt->num_rows > 0;
    $stmt->close();
    return $exists;
}

$hasUpdatedAt = adminAssignmentColumnExists($con, 'updated_at');
$hasDiaryColumns = adminAssignmentColumnExists($con, 'start_time')
    && adminAssignmentColumnExists($con, 'end_time')
    && adminAssignmentColumnExists($con, 'notes')
    && adminAssignmentColumnExists($con, 'location_id')
    && adminAssignmentColumnExists($con, 'asset_id');

if ($client_id <= 0 || $surveyor_id <= 0 || $appointment_date <= 0) {
    echo 'error: Missing assignment details.';
    exit;
}

if ($start_time !== null && $end_time !== null && $end_time <= $start_time) {
    echo 'error: End time must be after start time.';
    exit;
}

$con->begin_transaction();

try {
    if ($hasDiaryColumns && $start_time !== null && $end_time !== null) {
        $sql_overlap = "SELECT id FROM admin_assignments
                        WHERE surveyor_id = ?
                          AND status IN (0, 1)
                          AND start_time IS NOT NULL
                          AND end_time IS NOT NULL
                          AND start_time < ?
                          AND end_time > ?
                        LIMIT 1";
        $stmt_overlap = $con->prepare($sql_overlap);
        if (!$stmt_overlap) {
            throw new Exception('Error preparing overlap check: ' . $con->error);
        }
        $stmt_overlap->bind_param('iii', $surveyor_id, $end_time, $start_time);
        $stmt_overlap->execute();
        $stmt_overlap->store_result();
        if ($stmt_overlap->num_rows > 0) {
            echo 'error: Appointment overlaps with another job for this surveyor.';
            $stmt_overlap->close();
            $con->rollback();
            return;
        }
        $stmt_overlap->close();
    }

    // Step 1: Check if the surveyor already has an all-day assignment in admin_assignments.
    // Timed diary entries are protected by the overlap check above instead.
    $sql_check_admin = $hasDiaryColumns && $start_time !== null
        ? "SELECT 1 FROM admin_assignments WHERE client_id = ? AND surveyor_id = ? AND appointment_date = ? AND start_time = ?"
        : "SELECT 1 FROM admin_assignments WHERE client_id = ? AND surveyor_id = ? AND appointment_date = ?";
    $stmt_check_admin = $con->prepare($sql_check_admin);
    if (!$stmt_check_admin) {
        throw new Exception('Error preparing statement for admin_assignments check: ' . $con->error);
    }
    if ($hasDiaryColumns && $start_time !== null) {
        $stmt_check_admin->bind_param('iiii', $client_id, $surveyor_id, $appointment_date, $start_time);
    } else {
        $stmt_check_admin->bind_param('iii', $client_id, $surveyor_id, $appointment_date);
    }
    $stmt_check_admin->execute();
    $stmt_check_admin->store_result();

    if ($stmt_check_admin->num_rows > 0) {
        // Admin assignment already exists, return message
        echo 'error: Assignment already exists for this surveyor at this client on this date.';
        $con->rollback(); // Rollback transaction
        return;
    } else {
        // Step 2: Insert assignment into admin_assignments table
        if ($hasDiaryColumns) {
            $startSql = $start_time !== null ? (string)$start_time : "NULL";
            $endSql = $end_time !== null ? (string)$end_time : "NULL";
            $locationSql = $location_id !== null ? (string)$location_id : "NULL";
            $assetSql = $asset_id !== null ? (string)$asset_id : "NULL";
            $notesSql = "'" . $con->real_escape_string($notes) . "'";
            $updatedColumn = $hasUpdatedAt ? ", updated_at" : "";
            $updatedValue = $hasUpdatedAt ? ", UNIX_TIMESTAMP()" : "";
            $sql_admin = "INSERT INTO admin_assignments
                          (client_id, surveyor_id, appointment_date, start_time, end_time, notes, location_id, asset_id, date_assigned{$updatedColumn})
                          VALUES (?, ?, ?, {$startSql}, {$endSql}, {$notesSql}, {$locationSql}, {$assetSql}, UNIX_TIMESTAMP(){$updatedValue})";
        } else {
            $sql_admin = "INSERT INTO admin_assignments (client_id, surveyor_id, appointment_date, date_assigned)
                          VALUES (?, ?, ?, UNIX_TIMESTAMP())";
        }
        $stmt_admin = $con->prepare($sql_admin);
        if (!$stmt_admin) {
            throw new Exception('Error preparing statement for admin_assignments: ' . $con->error);
        }
        $stmt_admin->bind_param('iii', $client_id, $surveyor_id, $appointment_date);

        if (!$stmt_admin->execute()) {
            throw new Exception('Error inserting into admin_assignments: ' . $stmt_admin->error);
        }
    }

    // Step 3: Check if surveyor is already assigned in surveyor_assignments table
    $sql_check_surveyor = "SELECT status FROM surveyor_assignments WHERE surveyor = ? AND client_id = ?";
    $stmt_check_surveyor = $con->prepare($sql_check_surveyor);
    if (!$stmt_check_surveyor) {
        throw new Exception('Error preparing statement for surveyor_assignments check: ' . $con->error);
    }
    $stmt_check_surveyor->bind_param('ii', $surveyor_id, $client_id);
    $stmt_check_surveyor->execute();
    $stmt_check_surveyor->store_result();

    if ($stmt_check_surveyor->num_rows > 0) {
        // Surveyor is already assigned
        $stmt_check_surveyor->bind_result($status);
        $stmt_check_surveyor->fetch();

        if ($status == 1) {
            echo 'success: Assignment successful, surveyor already has access permissions.';
        } else {
            // Update the status to 1
            $sql_update_status = "UPDATE surveyor_assignments SET status = 1 WHERE surveyor = ? AND client_id = ?";
            $stmt_update_status = $con->prepare($sql_update_status);
            if (!$stmt_update_status) {
                throw new Exception('Error preparing statement for status update: ' . $con->error);
            }
            $stmt_update_status->bind_param('ii', $surveyor_id, $client_id);
            if (!$stmt_update_status->execute()) {
                throw new Exception('Error updating status in surveyor_assignments: ' . $stmt_update_status->error);
            }

            echo 'success: Assignment successful, permissions have been reinstated.';
        }
    } else {
        // Assign the surveyor to all active sites of the client
        $sql_locations = "SELECT locnumber FROM locations WHERE clientnumber = ? AND statuslive = 1";
        $stmt_locations = $con->prepare($sql_locations);
        if (!$stmt_locations) {
            throw new Exception('Error preparing statement for locations: ' . $con->error);
        }
        $stmt_locations->bind_param('i', $client_id);
        $stmt_locations->execute();
        $result_locations = $stmt_locations->get_result();

        $sql_surveyor_assign = "INSERT INTO surveyor_assignments (surveyor, client_id, site_id, asset_id, date_assigned, date_expired, status)
                                VALUES (?, ?, ?, 0, UNIX_TIMESTAMP(), 0, 1)";
        $stmt_surveyor_assign = $con->prepare($sql_surveyor_assign);
        if (!$stmt_surveyor_assign) {
            throw new Exception('Error preparing statement for surveyor_assignments: ' . $con->error);
        }

        while ($row = $result_locations->fetch_assoc()) {
            $site_id = $row['locnumber'];
            $stmt_surveyor_assign->bind_param('iii', $surveyor_id, $client_id, $site_id);
            if (!$stmt_surveyor_assign->execute()) {
                throw new Exception('Error inserting into surveyor_assignments: ' . $stmt_surveyor_assign->error);
            }
        }

        echo 'success: Assignment successful, permissions given for the surveyor to access the full schedule.';
    }

    // Commit the transaction if everything is successful
    $con->commit();
} catch (Exception $e) {
    // Rollback the transaction if any error occurs
    $con->rollback();
    echo 'error: ' . $e->getMessage();
}

// Close the statements and connection
if (isset($stmt_admin) && $stmt_admin instanceof mysqli_stmt) $stmt_admin->close();
if (isset($stmt_check_admin) && $stmt_check_admin instanceof mysqli_stmt) $stmt_check_admin->close();
if (isset($stmt_check_surveyor) && $stmt_check_surveyor instanceof mysqli_stmt) $stmt_check_surveyor->close();
if (isset($stmt_update_status)) $stmt_update_status->close();
if (isset($stmt_surveyor_assign)) $stmt_surveyor_assign->close();
$con->close();
