exec( "CREATE TABLE IF NOT EXISTS movies ( id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(160) NOT NULL, genre VARCHAR(80) NOT NULL, duration_min INT NOT NULL, rating VARCHAR(10) NOT NULL, description TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4" ); $pdo->exec( "CREATE TABLE IF NOT EXISTS shows ( id INT AUTO_INCREMENT PRIMARY KEY, movie_id INT NOT NULL, screen VARCHAR(40) NOT NULL, show_time DATETIME NOT NULL, format_label VARCHAR(10) NOT NULL, price DECIMAL(8,2) NOT NULL DEFAULT 12.00, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (movie_id) REFERENCES movies(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4" ); $pdo->exec( "CREATE TABLE IF NOT EXISTS bookings ( id INT AUTO_INCREMENT PRIMARY KEY, show_id INT NOT NULL, customer_name VARCHAR(120) NOT NULL, customer_email VARCHAR(160) NOT NULL, seats VARCHAR(120) NOT NULL, total_price DECIMAL(8,2) NOT NULL, booking_code VARCHAR(20) NOT NULL UNIQUE, status VARCHAR(20) NOT NULL DEFAULT 'booked', checked_in TINYINT(1) NOT NULL DEFAULT 0, checked_in_at DATETIME NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (show_id) REFERENCES shows(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4" ); } function seed_data(): void { $pdo = db(); $count = (int)$pdo->query("SELECT COUNT(*) FROM movies")->fetchColumn(); if ($count > 0) { return; } $pdo->beginTransaction(); $stmt = $pdo->prepare("INSERT INTO movies (title, genre, duration_min, rating, description) VALUES (?, ?, ?, ?, ?)"); $stmt->execute([ 'Midnight Signal', 'Sci-Fi Thriller', 124, 'PG-13', 'A space relay operator uncovers a message that redefines humanity’s future.' ]); $stmt->execute([ 'Velvet Avenue', 'Drama', 108, 'PG', 'A fashion editor returns home to rebuild her family studio and identity.' ]); $movies = $pdo->query("SELECT id, title FROM movies")->fetchAll(); $now = new DateTimeImmutable('now'); $showStmt = $pdo->prepare("INSERT INTO shows (movie_id, screen, show_time, format_label, price) VALUES (?, ?, ?, ?, ?)"); foreach ($movies as $index => $movie) { $base = $now->modify('+' . ($index * 2 + 1) . ' hours'); $showStmt->execute([$movie['id'], 'Screen A', $base->format('Y-m-d H:i:s'), '2D', 11.50]); $showStmt->execute([$movie['id'], 'Screen B', $base->modify('+3 hours')->format('Y-m-d H:i:s'), 'IMAX', 15.00]); } $pdo->commit(); } function fetch_movies_with_shows(): array { $pdo = db(); $movies = $pdo->query("SELECT * FROM movies ORDER BY created_at DESC")->fetchAll(); $shows = $pdo->query( "SELECT s.*, m.title AS movie_title FROM shows s JOIN movies m ON m.id = s.movie_id ORDER BY s.show_time ASC" )->fetchAll(); $grouped = []; foreach ($shows as $show) { $grouped[$show['movie_id']][] = $show; } return [$movies, $grouped]; } function fetch_show(int $showId): ?array { $pdo = db(); $stmt = $pdo->prepare( "SELECT s.*, m.title, m.genre, m.duration_min, m.rating, m.description FROM shows s JOIN movies m ON m.id = s.movie_id WHERE s.id = ?" ); $stmt->execute([$showId]); $row = $stmt->fetch(); return $row ?: null; } function fetch_booked_seats(int $showId): array { $pdo = db(); $stmt = $pdo->prepare("SELECT seats FROM bookings WHERE show_id = ? AND status = 'booked'"); $stmt->execute([$showId]); $booked = []; foreach ($stmt->fetchAll() as $row) { $parts = array_filter(array_map('trim', explode(',', $row['seats']))); foreach ($parts as $seat) { $booked[$seat] = true; } } return array_keys($booked); } function generate_booking_code(PDO $pdo): string { do { $code = strtoupper(bin2hex(random_bytes(3))); $stmt = $pdo->prepare("SELECT COUNT(*) FROM bookings WHERE booking_code = ?"); $stmt->execute([$code]); } while ((int)$stmt->fetchColumn() > 0); return $code; } ensure_schema(); seed_data();