<?php
require_auth();
$method = $_SERVER['REQUEST_METHOD'];
$d = input();
$id = (int)($d['id'] ?? 0);
$action = $d['action'] ?? null;

if ($method === 'GET') {
    require_permission('properties.view');
    if ($id) {
        $s = db()->prepare('SELECT r.*, rt.name AS room_type_name, rt.code AS room_type_code,
            rt.base_rate, rt.max_occupancy, p.name AS property_name,
            u.name AS last_cleaned_by_name
            FROM rooms r
            JOIN room_types rt ON rt.id = r.room_type_id
            JOIN properties p ON p.id = r.property_id
            LEFT JOIN users u ON u.id = r.last_cleaned_by
            WHERE r.id = ? AND r.deleted_at IS NULL');
        $s->execute([$id]);
        $room = $s->fetch();
        if (!$room) json_error('Not found', 404);
        json_ok($room);
    }
    $where = ['r.deleted_at IS NULL']; $params = [];
    if (!empty($d['property_id'])) { $where[] = 'r.property_id = ?'; $params[] = (int)$d['property_id']; }
    if (!empty($d['room_type_id'])) { $where[] = 'r.room_type_id = ?'; $params[] = (int)$d['room_type_id']; }
    if (!empty($d['floor'])) { $where[] = 'r.floor = ?'; $params[] = (string)$d['floor']; }
    if (!empty($d['housekeeping_status'])) { $where[] = 'r.housekeeping_status = ?'; $params[] = (string)$d['housekeeping_status']; }
    if (!empty($d['occupancy_status'])) { $where[] = 'r.occupancy_status = ?'; $params[] = (string)$d['occupancy_status']; }
    $sql = "SELECT r.id, r.property_id, r.room_type_id, r.room_number, r.floor, r.building,
                   r.housekeeping_status, r.occupancy_status, r.last_cleaned_at,
                   rt.name AS room_type_name, rt.code AS room_type_code, rt.base_rate, rt.max_occupancy
            FROM rooms r
            JOIN room_types rt ON rt.id = r.room_type_id
            WHERE " . implode(' AND ', $where) . "
            ORDER BY r.floor, LENGTH(r.room_number), r.room_number";
    $s = db()->prepare($sql); $s->execute($params);
    json_ok($s->fetchAll());
}

csrf_check();

if ($method === 'POST' && $action === 'bulk_create') {
    require_permission('properties.manage');
    $type_id = (int)($d['room_type_id'] ?? 0);
    $start = (int)($d['start_number'] ?? 0);
    $count = (int)($d['count'] ?? 0);
    $floor = $d['floor'] ?? null;
    $prefix = $d['prefix'] ?? '';
    if (!$type_id || $count < 1 || $count > 200) json_error('room_type_id + count (1-200) required', 422);
    $rt = db()->prepare('SELECT property_id FROM room_types WHERE id = ?');
    $rt->execute([$type_id]);
    $row = $rt->fetch();
    if (!$row) json_error('Room type not found', 404);
    $pid = (int)$row['property_id'];
    $created = 0; $skipped = 0;
    $ins = db()->prepare('INSERT IGNORE INTO rooms (property_id, room_type_id, room_number, floor) VALUES (?, ?, ?, ?)');
    for ($i = 0; $i < $count; $i++) {
        $num = $prefix . ($start + $i);
        $ins->execute([$pid, $type_id, $num, $floor]);
        if ($ins->rowCount()) $created++; else $skipped++;
    }
    db()->prepare('UPDATE properties SET total_rooms = (SELECT COUNT(*) FROM rooms WHERE property_id = ? AND deleted_at IS NULL) WHERE id = ?')->execute([$pid, $pid]);
    audit_log('rooms.bulk_create', 'room_type', $type_id, ['created' => $created, 'skipped' => $skipped]);
    json_ok(['created' => $created, 'skipped' => $skipped], "Created $created rooms");
}

if ($method === 'POST') {
    require_permission('properties.manage');
    $errors = v_required($d, ['property_id', 'room_type_id', 'room_number']);
    if ($errors) json_error('Validation failed', 422, $errors);
    try {
        db()->prepare('INSERT INTO rooms (property_id, room_type_id, room_number, floor, building, notes) VALUES (?, ?, ?, ?, ?, ?)')->execute([
            (int)$d['property_id'], (int)$d['room_type_id'], v_str($d, 'room_number', 20),
            $d['floor'] ?? null, $d['building'] ?? null, $d['notes'] ?? null,
        ]);
    } catch (PDOException $e) {
        if ($e->getCode() === '23000') json_error('Room number already exists', 409);
        throw $e;
    }
    $newId = (int)db()->lastInsertId();
    db()->prepare('UPDATE properties SET total_rooms = (SELECT COUNT(*) FROM rooms WHERE property_id = ? AND deleted_at IS NULL) WHERE id = ?')->execute([(int)$d['property_id'], (int)$d['property_id']]);
    audit_log('room.create', 'room', $newId);
    json_ok(['id' => $newId], 'Room created');
}

if (($method === 'PUT' || $method === 'PATCH') && $action === 'status') {
    require_permission('properties.manage');
    if (!$id) json_error('id required', 422);
    $hk = $d['housekeeping_status'] ?? null;
    $occ = $d['occupancy_status'] ?? null;
    $sets = []; $params = [];
    $hkAllowed = ['clean','dirty','inspected','maintenance','out_of_order'];
    $occAllowed = ['vacant','occupied','reserved','blocked'];
    if ($hk && in_array($hk, $hkAllowed, true)) {
        $sets[] = 'housekeeping_status = ?'; $params[] = $hk;
        if ($hk === 'clean' || $hk === 'inspected') {
            $sets[] = 'last_cleaned_at = NOW()';
            $sets[] = 'last_cleaned_by = ?'; $params[] = current_user()['id'];
        }
    }
    if ($occ && in_array($occ, $occAllowed, true)) {
        $sets[] = 'occupancy_status = ?'; $params[] = $occ;
    }
    if (!$sets) json_error('Nothing to update', 422);
    $params[] = $id;
    db()->prepare('UPDATE rooms SET ' . implode(', ', $sets) . ' WHERE id = ?')->execute($params);
    audit_log('room.status', 'room', $id, ['housekeeping' => $hk, 'occupancy' => $occ]);
    json_ok([], 'Room status updated');
}

if ($method === 'PUT' || $method === 'PATCH') {
    require_permission('properties.manage');
    if (!$id) json_error('id required', 422);
    $allowed = ['room_type_id','room_number','floor','building','notes'];
    $sets = []; $params = [];
    foreach ($allowed as $f) if (array_key_exists($f, $d)) { $sets[] = "$f = ?"; $params[] = $d[$f]; }
    if (!$sets) json_error('No fields to update', 422);
    $params[] = $id;
    db()->prepare('UPDATE rooms SET ' . implode(', ', $sets) . ' WHERE id = ?')->execute($params);
    audit_log('room.update', 'room', $id);
    json_ok([], 'Updated');
}

if ($method === 'DELETE') {
    require_permission('properties.manage');
    if (!$id) json_error('id required', 422);
    db()->prepare('UPDATE rooms SET deleted_at = NOW() WHERE id = ?')->execute([$id]);
    audit_log('room.delete', 'room', $id);
    json_ok([], 'Room deleted');
}

json_error('Method not allowed', 405);
