<?php
// update_bed_process.php - Handles updating bed data in the database

// Enable full error reporting for debugging. REMOVE IN PRODUCTION!
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

require_once 'config.php'; // Include database configuration
header('Content-Type: application/json'); // Set header to return JSON response

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $input = file_get_contents('php://input');
    $data = json_decode($input, true);

    // Sanitize and validate input
    $bedId = filter_var($data['bed_id'] ?? '', FILTER_SANITIZE_NUMBER_INT);
    $roomId = filter_var($data['roomId'] ?? '', FILTER_SANITIZE_NUMBER_INT); // Room can be changed for a bed
    $bedNumber = filter_var($data['bedNumber'] ?? '', FILTER_SANITIZE_STRING);
    $isOccupied = filter_var($data['isOccupied'] ?? 0, FILTER_SANITIZE_NUMBER_INT); // 0 or 1

    // Server-side validation for required fields
    if (empty($bedId) || empty($roomId) || empty($bedNumber) || ($isOccupied !== 0 && $isOccupied !== 1)) {
        echo json_encode(['success' => false, 'message' => 'All required fields must be filled and valid.']);
        exit;
    }

    try {
        $pdo->beginTransaction(); // Start a transaction

        // Fetch current bed status and room_id to determine if occupancy needs updating
        $sqlGetCurrentBedStatus = "SELECT room_id, is_occupied FROM beds WHERE bed_id = :bed_id FOR UPDATE";
        $stmtGetCurrentBedStatus = $pdo->prepare($sqlGetCurrentBedStatus);
        $stmtGetCurrentBedStatus->bindParam(':bed_id', $bedId, PDO::PARAM_INT);
        $stmtGetCurrentBedStatus->execute();
        $currentBedInfo = $stmtGetCurrentBedStatus->fetch(PDO::FETCH_ASSOC);

        if (!$currentBedInfo) {
            $pdo->rollBack();
            echo json_encode(['success' => false, 'message' => 'Bed not found.']);
            exit;
        }

        $oldRoomId = $currentBedInfo['room_id'];
        $oldIsOccupied = $currentBedInfo['is_occupied'];

        // Update the bed details
        $sqlUpdateBed = "UPDATE beds SET
                            room_id = :room_id,
                            bed_number = :bed_number,
                            is_occupied = :is_occupied
                         WHERE bed_id = :bed_id";
        $stmtUpdateBed = $pdo->prepare($sqlUpdateBed);
        $stmtUpdateBed->bindParam(':room_id', $roomId, PDO::PARAM_INT);
        $stmtUpdateBed->bindParam(':bed_number', $bedNumber);
        $stmtUpdateBed->bindParam(':is_occupied', $isOccupied, PDO::PARAM_INT);
        $stmtUpdateBed->bindParam(':bed_id', $bedId, PDO::PARAM_INT);

        if ($stmtUpdateBed->execute()) {
            // Adjust room occupancy if room_id changed or is_occupied status changed
            if ($stmtUpdateBed->rowCount() > 0) {
                // If room_id changed, decrement old room's occupancy and increment new room's
                if ($oldRoomId != $roomId) {
                    // Decrement old room's occupancy if bed was occupied
                    if ($oldIsOccupied == 1) {
                        $sqlUpdateOldRoom = "UPDATE rooms SET current_occupancy = current_occupancy - 1 WHERE room_id = :old_room_id AND current_occupancy > 0";
                        $stmtUpdateOldRoom = $pdo->prepare($sqlUpdateOldRoom);
                        $stmtUpdateOldRoom->bindParam(':old_room_id', $oldRoomId, PDO::PARAM_INT);
                        $stmtUpdateOldRoom->execute();
                    }
                    // Increment new room's occupancy if bed is now occupied
                    if ($isOccupied == 1) {
                        $sqlUpdateNewRoom = "UPDATE rooms SET current_occupancy = current_occupancy + 1 WHERE room_id = :new_room_id AND current_occupancy < capacity";
                        $stmtUpdateNewRoom = $pdo->prepare($sqlUpdateNewRoom);
                        $stmtUpdateNewRoom->bindParam(':new_room_id', $roomId, PDO::PARAM_INT);
                        $stmtUpdateNewRoom->execute();
                    }
                }
                // If room_id did NOT change, but is_occupied status changed
                else if ($oldIsOccupied != $isOccupied) {
                    if ($isOccupied == 1 && $oldIsOccupied == 0) { // Became occupied
                        $sqlUpdateRoom = "UPDATE rooms SET current_occupancy = current_occupancy + 1 WHERE room_id = :room_id AND current_occupancy < capacity";
                        $stmtUpdateRoom = $pdo->prepare($sqlUpdateRoom);
                        $stmtUpdateRoom->bindParam(':room_id', $roomId, PDO::PARAM_INT);
                        $stmtUpdateRoom->execute();
                    } else if ($isOccupied == 0 && $oldIsOccupied == 1) { // Became available
                        $sqlUpdateRoom = "UPDATE rooms SET current_occupancy = current_occupancy - 1 WHERE room_id = :room_id AND current_occupancy > 0";
                        $stmtUpdateRoom = $pdo->prepare($sqlUpdateRoom);
                        $stmtUpdateRoom->bindParam(':room_id', $roomId, PDO::PARAM_INT);
                        $stmtUpdateRoom->execute();
                    }
                }
            }

            $pdo->commit(); // Commit the transaction
            echo json_encode(['success' => true, 'message' => 'Bed updated successfully!']);
        } else {
            $pdo->rollBack();
            echo json_encode(['success' => false, 'message' => 'Failed to update bed.']);
        }
    } catch (PDOException $e) {
        $pdo->rollBack(); // Ensure rollback on any exception
        if ($e->getCode() == 23000) { // Unique constraint violation (room_id, bed_number)
            echo json_encode(['success' => false, 'message' => 'This bed number already exists for the selected room.']);
        } else {
            error_log("Database error updating bed: " . $e->getMessage());
            echo json_encode(['success' => false, 'message' => 'A database error occurred. Please try again later.']);
        }
    }
} else {
    echo json_encode(['success' => false, 'message' => 'Invalid request method.']);
}

