<?php
/**
 * Admin UI for table reservations (bordsbokning).
 *
 * @package Maca_Menu_List
 */

if (!defined('ABSPATH')) {
    exit;
}

require_once MACA_MENULIST_PLUGIN_DIR . 'includes/admin-booking-seat-matrix.php';

/**
 * Table Reservations admin screen.
 */
class Maca_MenuList_Admin_Table_Bookings {

    /**
     * Constructor.
     */
    public function __construct() {
        add_action('maca_menulist_render_table_bookings_admin', array($this, 'render_page'));
        add_action('admin_menu', array($this, 'add_admin_menu'), 21);
        add_action('admin_init', array($this, 'handle_actions'));
        add_action('admin_enqueue_scripts', array($this, 'enqueue_assets'));
        add_action('wp_ajax_maca_admin_booking_floor', array($this, 'ajax_booking_floor'));
        add_action('wp_ajax_maca_admin_move_booking', array($this, 'ajax_move_booking'));
        add_action('wp_ajax_maca_admin_split_table_day', array($this, 'ajax_split_table_day'));
        add_action('wp_ajax_maca_admin_unsplit_table_day', array($this, 'ajax_unsplit_table_day'));
        add_action('wp_ajax_maca_admin_booking_seat_matrix', array($this, 'ajax_booking_seat_matrix'));
        add_action('wp_ajax_maca_admin_booking_availability', array($this, 'ajax_booking_availability'));
        add_action('wp_ajax_maca_admin_create_staff_booking', array($this, 'ajax_create_staff_booking'));
        add_action('wp_ajax_maca_admin_staff_booking_tables', array($this, 'ajax_staff_booking_tables'));

    }

    /**
     * Enqueue styles for the bookings admin screen.
     *
     * @param string $hook Current admin page hook.
     * @return void
     */
    public function enqueue_assets($hook) {
        if (!is_string($hook) || strpos($hook, 'maca-restu-bookings') === false) {
            return;
        }

        wp_enqueue_style(
            'maca-menulist-style',
            MACA_MENULIST_PLUGIN_URL . 'assets/css/style.css',
            array(),
            MACA_MENULIST_VERSION
        );

        $tab = isset($_GET['tab']) ? sanitize_key(wp_unslash($_GET['tab'])) : 'bookings';

        if ($tab === 'matrix') {
            $this->enqueue_matrix_assets();
            return;
        }

        if ($tab === 'availability') {
            $this->enqueue_availability_assets();
            return;
        }

        if ($tab !== 'floor') {
            return;
        }

        wp_enqueue_script(
            'maca-menulist-admin-booking-floor',
            MACA_MENULIST_PLUGIN_URL . 'assets/js/admin-booking-floor.js',
            array(),
            MACA_MENULIST_VERSION,
            true
        );

        $today = wp_date('Y-m-d');
        $advance_days = maca_menulist_table_booking_advance_days();
        $max_date = maca_menulist_wp_now_modify('+' . $advance_days . ' days');

        wp_localize_script(
            'maca-menulist-admin-booking-floor',
            'macaMenulistAdminBookingFloor',
            array(
                'ajaxUrl' => admin_url('admin-ajax.php'),
                'nonce' => wp_create_nonce('maca_admin_booking_floor'),
                'today' => $today,
                'minDate' => maca_menulist_wp_now_modify('-7 days'),
                'maxDate' => $max_date,
                'bookingUrl' => admin_url('admin.php?page=maca-restu-bookings&tab=bookings'),
                'bookingsListUrl' => admin_url('admin.php?page=maca-restu-bookings&tab=bookings'),
                'strings' => array(
                    'loading' => __('Laddar…', 'maca-restu-pro'),
                    'error' => __('Kunde inte ladda bordsstatus. Försök igen.', 'maca-restu-pro'),
                    'closed' => __('Stängt eller inga bokningsbara tider detta datum.', 'maca-restu-pro'),
                    'table' => __('Bord', 'maca-restu-pro'),
                    'seats' => __('platser', 'maca-restu-pro'),
                    'available' => __('Ledigt', 'maca-restu-pro'),
                    'occupied' => __('Upptaget', 'maca-restu-pro'),
                    'guests' => __('gäster', 'maca-restu-pro'),
                    'viewBooking' => __('Visa bokning', 'maca-restu-pro'),
                    'viewBookingsDay' => __('Visa bokningar för dagen', 'maca-restu-pro'),
                    /* translators: %d: booking slot duration in minutes */
                    'slotDuration' => __('Bokningsslot: %d minuter.', 'maca-restu-pro'),
                    /* translators: 1: free tables, 2: shareable tables, 3: full tables, 4: total tables */
                    'summary' => __('%1$d lediga · %2$d delbara · %3$d fulla · %4$d bord', 'maca-restu-pro'),
                    'dayOccupancyLabel' => __('Day occupancy', 'maca-restu-pro'),
                    /* translators: 1: occupancy percent, 2: booked guests, 3: peak capacity */
                    'dayOccupancy' => __('%1$d%% (%2$d / %3$d)', 'maca-restu-pro'),
                    'dayOccupancyUnavailable' => __('—', 'maca-restu-pro'),
                    'pending' => __('väntande', 'maca-restu-pro'),
                    'moveSuccess' => __('Bokningen placerades på valt bord.', 'maca-restu-pro'),
                    'noMoveTargets' => __('Inga andra bord med plats vid denna tid.', 'maca-restu-pro'),
                    'dragHint' => __('Dra till grönt (ledigt) eller orange (dela bord) bord.', 'maca-restu-pro'),
                    'queueTitle' => __('Pending & waitlist', 'maca-restu-pro'),
                    'queueHint' => __('Drag onto a green or orange table. Waitlist shows preferred time; set the slider to an available slot (e.g. 20:00) to place the guest there.', 'maca-restu-pro'),
                    'requestedTime' => __('Preferred time', 'maca-restu-pro'),
                    /* translators: %s: time from the floor slider, e.g. 20:00 */
                    'placeAtTime' => __('Place at %s (slider time)', 'maca-restu-pro'),
                    'waitlistPlaced' => __('Guest placed on table. Booking is now pending confirmation.', 'maca-restu-pro'),
                    'queueEmpty' => __('No pending or waitlist bookings for this view.', 'maca-restu-pro'),
                    'queueNoTables' => __('No free table at this time — try another time or split tables.', 'maca-restu-pro'),
                    'dropFailed' => __('Could not place the booking on that table. Choose a green or orange table at the selected time.', 'maca-restu-pro'),
                    'waitlist' => __('waitlist', 'maca-restu-pro'),
                    'dropHint' => __('Släpp här för att flytta bokningen', 'maca-restu-pro'),
                    'dropHintShare' => __('Släpp här för att lägga till på bordet', 'maca-restu-pro'),
                    'shareable' => __('Kan delas', 'maca-restu-pro'),
                    'moving' => __('Flyttar…', 'maca-restu-pro'),
                    /* translators: 1: occupied seats, 2: total seats */
                    'partialOccupied' => __('%1$d av %2$d upptagna', 'maca-restu-pro'),
                    /* translators: 1: current bookings, 2: max bookings */
                    'bookingCount' => __('%1$d/%2$d bokningar', 'maca-restu-pro'),
                    /* translators: %s: split layout label */
                    'splittableBadge' => __('Delningsbart %s', 'maca-restu-pro'),
                    'splitDay' => __('Dela för vald dag', 'maca-restu-pro'),
                    'updateDaySplit' => __('Uppdatera delning', 'maca-restu-pro'),
                    'unsplitDay' => __('Helt bord denna dag', 'maca-restu-pro'),
                    'daySplitLayout' => __('Delning för dagen', 'maca-restu-pro'),
                    /* translators: %s: day-split layout label */
                    'daySplitActive' => __('Idag: %s', 'maca-restu-pro'),
                    'splitDaySuccess' => __('Bordet är delat för vald dag.', 'maca-restu-pro'),
                    'unsplitDaySuccess' => __('Helt bord för vald dag (inga delar).', 'maca-restu-pro'),
                    'addBooking' => __('Lägg till bokning', 'maca-restu-pro'),
                    'addBookingTitle' => __('Manuell bokning (telefon / walk-in)', 'maca-restu-pro'),
                    'addBookingHelp' => __('Bokningen sparas som bekräftad direkt. Välj datum och tid ovan, eller samma som i reglaget.', 'maca-restu-pro'),
                    'guestName' => __('Namn', 'maca-restu-pro'),
                    'guestPhone' => __('Telefon', 'maca-restu-pro'),
                    'guestEmail' => __('E-post (valfritt)', 'maca-restu-pro'),
                    'partySize' => __('Antal gäster', 'maca-restu-pro'),
                    'table' => __('Bord', 'maca-restu-pro'),
                    'tableAuto' => __('Automatiskt ledigt bord', 'maca-restu-pro'),
                    'note' => __('Anteckning', 'maca-restu-pro'),
                    'sendEmail' => __('Skicka bekräftelse via e-post', 'maca-restu-pro'),
                    'saveBooking' => __('Spara bokning', 'maca-restu-pro'),
                    'cancel' => __('Avbryt', 'maca-restu-pro'),
                    'bookingSaved' => __('Bokningen är sparad.', 'maca-restu-pro'),
                    'noTables' => __('Inga lediga bord vid vald tid.', 'maca-restu-pro'),
                    'bookClickHint' => __('Klicka för att lägga bokning här', 'maca-restu-pro'),
                    'bookClickHintShare' => __('Klicka för att lägga till bokning på bordet', 'maca-restu-pro'),
                    'bookTableSelected' => __('Bord valt — fyll i gästuppgifter och spara.', 'maca-restu-pro'),
                ),
                'maxBookingsPerTable' => maca_menulist_admin_floor_max_bookings_per_table(),
            )
        );
    }

    /**
     * Enqueue seat matrix script.
     *
     * @return void
     */
    private function enqueue_matrix_assets() {
        wp_enqueue_script(
            'maca-menulist-admin-booking-matrix',
            MACA_MENULIST_PLUGIN_URL . 'assets/js/admin-booking-matrix.js',
            array(),
            MACA_MENULIST_VERSION,
            true
        );

        $advance_days = maca_menulist_table_booking_advance_days();

        wp_localize_script(
            'maca-menulist-admin-booking-matrix',
            'macaMenulistAdminBookingMatrix',
            array(
                'ajaxUrl'  => admin_url('admin-ajax.php'),
                'nonce'    => wp_create_nonce('maca_admin_booking_floor'),
                'today'    => wp_date('Y-m-d'),
                'minDate'  => maca_menulist_wp_now_modify('-7 days'),
                'maxDate'  => maca_menulist_wp_now_modify('+' . $advance_days . ' days'),
                'strings'  => array(
                    'loading'   => __('Laddar…', 'maca-restu-pro'),
                    'error'     => __('Kunde inte ladda platser. Försök igen.', 'maca-restu-pro'),
                    'closed'    => __('Stängt eller inga bokningsbara tider detta datum.', 'maca-restu-pro'),
                    'time'      => __('Tid', 'maca-restu-pro'),
                    'available' => __('Ledigt', 'maca-restu-pro'),
                    'occupied'  => __('Upptaget', 'maca-restu-pro'),
                ),
            )
        );
    }

    /**
     * Enqueue availability tab loader script.
     *
     * @return void
     */
    private function enqueue_availability_assets() {
        wp_enqueue_script(
            'maca-menulist-admin-booking-availability',
            MACA_MENULIST_PLUGIN_URL . 'assets/js/admin-booking-availability.js',
            array(),
            MACA_MENULIST_VERSION,
            true
        );

        wp_localize_script(
            'maca-menulist-admin-booking-availability',
            'macaMenulistAdminBookingAvailability',
            array(
                'ajaxUrl' => admin_url('admin-ajax.php'),
                'nonce'   => wp_create_nonce('maca_admin_booking_floor'),
                'strings' => array(
                    'loading' => __('Laddar lediga platser…', 'maca-restu-pro'),
                    'error'   => __('Kunde inte ladda lediga platser. Försök igen.', 'maca-restu-pro'),
                ),
            )
        );
    }

    /**
     * Register submenu when table reservation is enabled.
     */
    public function add_admin_menu() {
        if (!maca_menulist_pro_has_feature('table_bookings')) {
            return;
        }

        if (function_exists('maca_menulist_user_is_booking_host_only') && maca_menulist_user_is_booking_host_only()) {
            return;
        }

        add_submenu_page(
            'maca-restu',
            __('Bordsbokningar', 'maca-restu-pro'),
            __('Bordsbokningar', 'maca-restu-pro'),
            MACA_MENULIST_CAP_MANAGE_BOOKINGS,
            'maca-restu-bookings',
            array($this, 'render_page')
        );
    }

    /**
     * Handle admin POST actions.
     */
    public function handle_actions() {
        if (!isset($_POST['maca_bookings_action'])) {
            return;
        }

        if (!isset($_POST['maca_bookings_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['maca_bookings_nonce'])), 'maca_bookings')) {
            return;
        }

        if (!maca_menulist_pro_has_feature('table_bookings')) {
            return;
        }

        $action = sanitize_key(wp_unslash($_POST['maca_bookings_action']));
        $schedule_actions = array('save_exception', 'delete_exception', 'save_recurring_exception', 'delete_recurring_exception');
        $owner_only_actions = array('save_booking_settings');
        $booking_edit_actions = array(
            'confirm_booking',
            'move_booking',
            'update_booking',
            'update_party_size',
            'cancel_booking',
            'delete_booking',
            'save_table',
            'delete_table',
        );

        if (in_array($action, $schedule_actions, true)) {
            if (!maca_menulist_user_can_manage_booking_schedule()) {
                return;
            }
        } elseif (in_array($action, $owner_only_actions, true)) {
            if (!maca_menulist_user_can_manage_plugin()) {
                return;
            }
        } elseif (in_array($action, $booking_edit_actions, true)) {
            if (!maca_menulist_user_can_edit_bookings()) {
                return;
            }
        } elseif (!maca_menulist_user_can_manage_bookings()) {
            return;
        }

        switch ($action) {
            case 'confirm_booking':
                $this->handle_confirm_booking();
                break;
            case 'move_booking':
                $this->handle_move_booking();
                break;
            case 'update_booking':
                $this->handle_update_booking();
                break;
            case 'update_party_size':
                $this->handle_update_party_size();
                break;
            case 'cancel_booking':
                $this->handle_cancel_booking();
                break;
            case 'delete_booking':
                $this->handle_delete_booking();
                break;
            case 'save_table':
                $this->handle_save_table();
                break;
            case 'delete_table':
                $this->handle_delete_table();
                break;
            case 'save_booking_settings':
                $this->handle_save_booking_settings();
                break;
            case 'save_exception':
                $this->handle_save_exception();
                break;
            case 'delete_exception':
                $this->handle_delete_exception();
                break;
            case 'save_recurring_exception':
                $this->handle_save_recurring_exception();
                break;
            case 'delete_recurring_exception':
                $this->handle_delete_recurring_exception();
                break;
        }
    }

    /**
     * Confirm a pending booking.
     */
    private function handle_confirm_booking() {
        $booking_id = isset($_POST['booking_id']) ? absint(wp_unslash($_POST['booking_id'])) : 0;
        $table_id = isset($_POST['table_id']) ? absint(wp_unslash($_POST['table_id'])) : 0;

        if ($booking_id <= 0) {
            return;
        }

        $booking = maca_menulist_db_get_booking($booking_id);
        if (!$booking) {
            add_settings_error('maca_bookings', 'not_found', __('Booking not found.', 'maca-restu-pro'), 'error');
            return;
        }

        if ($table_id <= 0) {
            $table_id = (int) $booking->table_id;
        }

        if (!in_array($booking->status, array('pending', 'waitlist'), true)) {
            add_settings_error('maca_bookings', 'invalid_status', __('Only pending or waitlist bookings can be confirmed.', 'maca-restu-pro'), 'error');
            return;
        }

        if ($table_id <= 0) {
            add_settings_error('maca_bookings', 'no_table', __('Select a table before confirming.', 'maca-restu-pro'), 'error');
            return;
        }

        if (!maca_menulist_is_table_available($table_id, $booking->booking_date, $booking->booking_time, $booking_id)) {
            add_settings_error('maca_bookings', 'table_taken', __('The selected table is no longer available at this time.', 'maca-restu-pro'), 'error');
            return;
        }

        maca_menulist_db_update_booking_status($booking_id, 'confirmed', $table_id);
        maca_menulist_send_booking_email($booking_id, 'confirmed');

        if (function_exists('maca_menulist_booking_log_field_updates')) {
            maca_menulist_booking_log_field_updates(
                $booking_id,
                array(
                    'status' => (string) $booking->status,
                    'table_id' => (int) $booking->table_id,
                ),
                array(
                    'status' => 'confirmed',
                    'table_id' => $table_id,
                ),
                'confirmed'
            );
        }

        add_settings_error('maca_bookings', 'confirmed', __('Booking confirmed and guest notified by email.', 'maca-restu-pro'), 'success');
    }

    /**
     * Update booking guest details, date, time and party size.
     */
    private function handle_update_booking() {
        $booking_id = isset($_POST['booking_id']) ? absint(wp_unslash($_POST['booking_id'])) : 0;

        if ($booking_id <= 0) {
            return;
        }

        $result = maca_menulist_update_booking_details(
            $booking_id,
            array(
                'guest_name' => isset($_POST['guest_name']) ? wp_unslash($_POST['guest_name']) : '',
                'guest_phone' => isset($_POST['guest_phone']) ? wp_unslash($_POST['guest_phone']) : '',
                'guest_email' => isset($_POST['guest_email']) ? wp_unslash($_POST['guest_email']) : '',
                'guest_note' => isset($_POST['guest_note']) ? wp_unslash($_POST['guest_note']) : '',
                'booking_date' => isset($_POST['booking_date']) ? wp_unslash($_POST['booking_date']) : '',
                'booking_time' => isset($_POST['booking_time']) ? wp_unslash($_POST['booking_time']) : '',
                'party_size' => isset($_POST['party_size']) ? wp_unslash($_POST['party_size']) : 0,
            )
        );

        if (is_wp_error($result)) {
            $code = $result->get_error_code();
            $type = $code === 'unchanged' ? 'info' : 'error';
            add_settings_error('maca_bookings', 'booking_update_' . $code, $result->get_error_message(), $type);
            return;
        }

        add_settings_error('maca_bookings', 'booking_updated', __('Bokningen är uppdaterad.', 'maca-restu-pro'), 'success');
    }

    /**
     * Update party size on a booking (legacy form).
     */
    private function handle_update_party_size() {
        $booking_id = isset($_POST['booking_id']) ? absint(wp_unslash($_POST['booking_id'])) : 0;
        $party_size = isset($_POST['party_size']) ? max(1, (int) wp_unslash($_POST['party_size'])) : 0;

        if ($booking_id <= 0) {
            return;
        }

        $result = maca_menulist_update_booking_party_size($booking_id, $party_size);

        if (is_wp_error($result)) {
            $code = $result->get_error_code();
            if ($code === 'unchanged') {
                add_settings_error('maca_bookings', 'party_unchanged', $result->get_error_message(), 'info');
            } else {
                add_settings_error('maca_bookings', 'party_error', $result->get_error_message(), 'error');
            }
            return;
        }

        add_settings_error('maca_bookings', 'party_updated', __('Bokningen är uppdaterad.', 'maca-restu-pro'), 'success');
    }

    /**
     * Move a booking to another table (POST from booking detail).
     */
    private function handle_move_booking() {
        $booking_id = isset($_POST['booking_id']) ? absint(wp_unslash($_POST['booking_id'])) : 0;
        $table_id   = 0;
        $split_slot = '';

        if (isset($_POST['table_id'])) {
            $table_key = sanitize_text_field(wp_unslash($_POST['table_id']));
            if (strpos($table_key, ':') !== false) {
                $parts      = explode(':', $table_key, 2);
                $table_id   = isset($parts[0]) ? absint($parts[0]) : 0;
                $split_slot = isset($parts[1]) ? maca_menulist_normalize_split_slot($parts[1]) : '';
            } else {
                $table_id = absint($table_key);
            }
        }

        if ($booking_id <= 0) {
            return;
        }

        $result = maca_menulist_move_booking_to_table($booking_id, $table_id, $split_slot);

        if (is_wp_error($result)) {
            add_settings_error('maca_bookings', 'move_error', $result->get_error_message(), 'error');
            return;
        }

        add_settings_error(
            'maca_bookings',
            'moved',
            __('Booking moved to the selected table.', 'maca-restu-pro'),
            'success'
        );
    }

    /**
     * Cancel a booking.
     */
    private function handle_cancel_booking() {
        $booking_id = isset($_POST['booking_id']) ? absint(wp_unslash($_POST['booking_id'])) : 0;

        if ($booking_id <= 0) {
            return;
        }

        $booking = maca_menulist_db_get_booking($booking_id);
        maca_menulist_db_update_booking_status($booking_id, 'cancelled');
        maca_menulist_send_booking_email($booking_id, 'cancelled');

        if ($booking && function_exists('maca_menulist_booking_log_field_updates')) {
            $before_log = array(
                'status' => (string) $booking->status,
            );
            $after_log = array(
                'status' => 'cancelled',
            );

            if ((int) $booking->table_id > 0) {
                $before_log['table_id'] = (int) $booking->table_id;
                $after_log['table_id'] = 0;
            }

            $split_slot = isset($booking->split_slot) && function_exists('maca_menulist_normalize_split_slot')
                ? maca_menulist_normalize_split_slot((string) $booking->split_slot)
                : '';

            if ($split_slot !== '') {
                $before_log['split_slot'] = $split_slot;
                $after_log['split_slot'] = '';
            }

            maca_menulist_booking_log_field_updates(
                $booking_id,
                $before_log,
                $after_log,
                'cancelled'
            );
        }

        add_settings_error('maca_bookings', 'cancelled', __('Booking cancelled and guest notified by email.', 'maca-restu-pro'), 'success');
    }

    /**
     * Delete a booking permanently.
     */
    private function handle_delete_booking() {
        $booking_id = isset($_POST['booking_id']) ? absint(wp_unslash($_POST['booking_id'])) : 0;

        if ($booking_id <= 0) {
            return;
        }

        $booking = maca_menulist_db_get_booking($booking_id);
        if ($booking && function_exists('maca_menulist_booking_log_add')) {
            maca_menulist_booking_log_add(
                $booking_id,
                'deleted',
                array(
                    'summary' => sprintf(
                        /* translators: %s: guest name */
                        __('Bokning raderad permanent (%s).', 'maca-restu-pro'),
                        (string) $booking->guest_name
                    ),
                )
            );
        }

        maca_menulist_db_delete_booking($booking_id);
        add_settings_error('maca_bookings', 'deleted', __('Booking deleted.', 'maca-restu-pro'), 'success');
    }

    /**
     * Save a physical table.
     */
    private function handle_save_table() {
        $table_id = isset($_POST['table_id']) ? absint(wp_unslash($_POST['table_id'])) : 0;

        $split_layout_mode = isset($_POST['split_layout_mode'])
            ? sanitize_key(wp_unslash($_POST['split_layout_mode']))
            : 'uniform';
        $table_payload = array(
            'id' => $table_id,
            'table_number' => isset($_POST['table_number']) ? sanitize_text_field(wp_unslash($_POST['table_number'])) : '',
            'seats' => isset($_POST['seats']) ? absint(wp_unslash($_POST['seats'])) : 2,
            'is_splittable' => !empty($_POST['is_splittable']),
            'split_party_size' => isset($_POST['split_party_size']) ? absint(wp_unslash($_POST['split_party_size'])) : 2,
            'sort_order' => isset($_POST['sort_order']) ? (int) wp_unslash($_POST['sort_order']) : 0,
            'is_active' => !empty($_POST['is_active']),
        );

        if (!empty($_POST['is_splittable'])) {
            if ($split_layout_mode === 'custom') {
                $table_payload['split_slot_sizes'] = isset($_POST['split_slot_sizes'])
                    ? sanitize_text_field(wp_unslash($_POST['split_slot_sizes']))
                    : '';
            } else {
                $table_payload['split_slot_sizes'] = '';
            }
        }

        $saved = maca_menulist_db_save_booking_table($table_payload);

        if (is_wp_error($saved)) {
            add_settings_error('maca_bookings', 'table_error', $saved->get_error_message(), 'error');
        } elseif ($saved) {
            add_settings_error('maca_bookings', 'table_saved', __('Table saved.', 'maca-restu-pro'), 'success');
        } else {
            add_settings_error('maca_bookings', 'table_error', __('Could not save table. Check table number.', 'maca-restu-pro'), 'error');
        }
    }

    /**
     * Delete a physical table.
     */
    private function handle_delete_table() {
        $table_id = isset($_POST['table_id']) ? absint(wp_unslash($_POST['table_id'])) : 0;

        if ($table_id <= 0) {
            return;
        }

        maca_menulist_db_delete_booking_table($table_id);
        add_settings_error('maca_bookings', 'table_deleted', __('Table deleted.', 'maca-restu-pro'), 'success');
    }

    /**
     * Save table reservation settings from the bookings admin tab.
     */
    private function handle_save_booking_settings() {
        maca_menulist_save_table_booking_settings_from_post();
        add_settings_error('maca_bookings', 'booking_settings_saved', __('Table Reservation settings saved.', 'maca-restu-pro'), 'success');
        do_action('maca_menulist_site_chat_content_changed');
    }

    /**
     * Save a schedule exception.
     */
    private function handle_save_exception() {
        $exception_id = isset($_POST['exception_id']) ? absint(wp_unslash($_POST['exception_id'])) : 0;

        $saved = maca_menulist_db_save_booking_exception(
            array(
                'id' => $exception_id,
                'exception_date' => isset($_POST['exception_date']) ? sanitize_text_field(wp_unslash($_POST['exception_date'])) : '',
                'exception_type' => isset($_POST['exception_type']) ? sanitize_key(wp_unslash($_POST['exception_type'])) : 'closed',
                'time_start' => isset($_POST['time_start']) ? sanitize_text_field(wp_unslash($_POST['time_start'])) : '',
                'time_end' => isset($_POST['time_end']) ? sanitize_text_field(wp_unslash($_POST['time_end'])) : '',
                'note' => isset($_POST['note']) ? sanitize_text_field(wp_unslash($_POST['note'])) : '',
            )
        );

        if ($saved) {
            add_settings_error('maca_bookings', 'exception_saved', __('Exception saved.', 'maca-restu-pro'), 'success');
            do_action('maca_menulist_site_chat_content_changed');
        } else {
            add_settings_error('maca_bookings', 'exception_error', __('Could not save exception. Check the date.', 'maca-restu-pro'), 'error');
        }

        if (function_exists('maca_menulist_booking_exceptions_settings_redirect_url')) {
            wp_safe_redirect(maca_menulist_booking_exceptions_settings_redirect_url());
            exit;
        }
    }

    /**
     * Delete a schedule exception.
     */
    private function handle_delete_exception() {
        $exception_id = isset($_POST['exception_id']) ? absint(wp_unslash($_POST['exception_id'])) : 0;

        if ($exception_id <= 0) {
            return;
        }

        maca_menulist_db_delete_booking_exception($exception_id);
        add_settings_error('maca_bookings', 'exception_deleted', __('Exception deleted.', 'maca-restu-pro'), 'success');
        do_action('maca_menulist_site_chat_content_changed');

        if (function_exists('maca_menulist_booking_exceptions_settings_redirect_url')) {
            wp_safe_redirect(maca_menulist_booking_exceptions_settings_redirect_url());
            exit;
        }
    }

    /**
     * Save a recurring weekday schedule exception.
     */
    private function handle_save_recurring_exception() {
        $exception_id = isset($_POST['recurring_exception_id']) ? absint(wp_unslash($_POST['recurring_exception_id'])) : 0;
        $days_raw = isset($_POST['recurring_days_of_week']) ? wp_unslash($_POST['recurring_days_of_week']) : array();

        if (!is_array($days_raw)) {
            $days_raw = array();
        }

        $saved = maca_menulist_db_save_booking_recurring_exception(
            array(
                'id' => $exception_id,
                'date_from' => isset($_POST['recurring_date_from']) ? sanitize_text_field(wp_unslash($_POST['recurring_date_from'])) : '',
                'date_to' => isset($_POST['recurring_date_to']) ? sanitize_text_field(wp_unslash($_POST['recurring_date_to'])) : '',
                'days_of_week' => array_map('sanitize_text_field', $days_raw),
                'exception_type' => isset($_POST['recurring_exception_type']) ? sanitize_key(wp_unslash($_POST['recurring_exception_type'])) : 'custom_hours',
                'time_start' => isset($_POST['recurring_time_start']) ? sanitize_text_field(wp_unslash($_POST['recurring_time_start'])) : '',
                'time_end' => isset($_POST['recurring_time_end']) ? sanitize_text_field(wp_unslash($_POST['recurring_time_end'])) : '',
                'note' => isset($_POST['recurring_note']) ? sanitize_text_field(wp_unslash($_POST['recurring_note'])) : '',
            )
        );

        if ($saved) {
            add_settings_error('maca_bookings', 'recurring_exception_saved', __('Recurring exception saved.', 'maca-restu-pro'), 'success');
            do_action('maca_menulist_site_chat_content_changed');
        } else {
            add_settings_error('maca_bookings', 'recurring_exception_error', __('Could not save recurring exception. Check the period and weekdays.', 'maca-restu-pro'), 'error');
        }

        if (function_exists('maca_menulist_booking_exceptions_settings_redirect_url')) {
            wp_safe_redirect(maca_menulist_booking_exceptions_settings_redirect_url());
            exit;
        }
    }

    /**
     * Delete a recurring weekday schedule exception.
     */
    private function handle_delete_recurring_exception() {
        $exception_id = isset($_POST['recurring_exception_id']) ? absint(wp_unslash($_POST['recurring_exception_id'])) : 0;

        if ($exception_id <= 0) {
            return;
        }

        maca_menulist_db_delete_booking_recurring_exception($exception_id);
        add_settings_error('maca_bookings', 'recurring_exception_deleted', __('Recurring exception deleted.', 'maca-restu-pro'), 'success');
        do_action('maca_menulist_site_chat_content_changed');

        if (function_exists('maca_menulist_booking_exceptions_settings_redirect_url')) {
            wp_safe_redirect(maca_menulist_booking_exceptions_settings_redirect_url());
            exit;
        }
    }

    /**
     * Render admin page with tabs.
     */
    public function render_page() {
        if (!maca_menulist_user_can_manage_bookings()) {
            return;
        }

        if (!maca_menulist_pro_has_feature('table_bookings')) {
            echo maca_menulist_pro_locked_notice('table_bookings'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
            return;
        }

        $tab = isset($_GET['tab']) ? sanitize_key(wp_unslash($_GET['tab'])) : 'bookings';
        $valid_tabs = array('bookings', 'floor', 'matrix', 'availability', 'tables', 'log', 'settings');

        if ($tab === 'hours') {
            $tab = 'settings';
        }

        $is_booking_host = function_exists('maca_menulist_user_is_booking_host_only') && maca_menulist_user_is_booking_host_only();

        if ($tab === 'exceptions') {
            $exceptions_url = $is_booking_host
                ? admin_url('admin.php?page=maca-restu-booking-schedule&tab=exceptions')
                : admin_url('admin.php?page=maca-restu-settings&tab=exceptions');
            wp_safe_redirect($exceptions_url);
            exit;
        }

        if ($is_booking_host && $tab === 'settings') {
            wp_safe_redirect(admin_url('admin.php?page=maca-restu-bookings&tab=bookings'));
            exit;
        }

        if (!in_array($tab, $valid_tabs, true)) {
            $tab = 'bookings';
        }

        $base_url = admin_url('admin.php?page=maca-restu-bookings');
        ?>
        <div class="wrap maca-bookings-wrap">
            <h1><?php esc_html_e('Table Reservations', 'maca-restu-pro'); ?></h1>

            <?php settings_errors('maca_bookings'); ?>

            <?php if (!maca_menulist_table_booking_has_active_tables()) : ?>
                <div class="notice notice-warning inline">
                    <p>
                        <?php esc_html_e('No tables are configured yet. Guests cannot book until you add tables under the Tables tab.', 'maca-restu-pro'); ?>
                    </p>
                </div>
            <?php endif; ?>

            <nav class="nav-tab-wrapper">
                <a href="<?php echo esc_url($base_url . '&tab=bookings'); ?>" class="nav-tab <?php echo $tab === 'bookings' ? 'nav-tab-active' : ''; ?>">
                    <?php esc_html_e('Bookings', 'maca-restu-pro'); ?>
                </a>
                <a href="<?php echo esc_url($base_url . '&tab=floor'); ?>" class="nav-tab <?php echo $tab === 'floor' ? 'nav-tab-active' : ''; ?>">
                    <?php esc_html_e('Salongsöversikt', 'maca-restu-pro'); ?>
                </a>
                <a href="<?php echo esc_url($base_url . '&tab=matrix'); ?>" class="nav-tab <?php echo $tab === 'matrix' ? 'nav-tab-active' : ''; ?>">
                    <?php esc_html_e('Platsrutnät', 'maca-restu-pro'); ?>
                </a>
                <a href="<?php echo esc_url($base_url . '&tab=availability'); ?>" class="nav-tab <?php echo $tab === 'availability' ? 'nav-tab-active' : ''; ?>">
                    <?php esc_html_e('Availability', 'maca-restu-pro'); ?>
                </a>
                <a href="<?php echo esc_url($base_url . '&tab=tables'); ?>" class="nav-tab <?php echo $tab === 'tables' ? 'nav-tab-active' : ''; ?>">
                    <?php esc_html_e('Tables', 'maca-restu-pro'); ?>
                </a>
                <a href="<?php echo esc_url($base_url . '&tab=log'); ?>" class="nav-tab <?php echo $tab === 'log' ? 'nav-tab-active' : ''; ?>">
                    <?php esc_html_e('Händelselogg', 'maca-restu-pro'); ?>
                </a>
                <?php if ($is_booking_host && maca_menulist_user_can_manage_booking_schedule()) : ?>
                    <a href="<?php echo esc_url(admin_url('admin.php?page=maca-restu-booking-schedule&tab=hours')); ?>" class="nav-tab">
                        <?php esc_html_e('Opening hours & exceptions', 'maca-restu-pro'); ?>
                    </a>
                <?php endif; ?>
                <?php if (!$is_booking_host) : ?>
                <a href="<?php echo esc_url($base_url . '&tab=settings'); ?>" class="nav-tab <?php echo $tab === 'settings' ? 'nav-tab-active' : ''; ?>">
                    <?php esc_html_e('Table settings', 'maca-restu-pro'); ?>
                </a>
                <?php endif; ?>
            </nav>

            <div class="maca-bookings-tab-content">
                <?php
                switch ($tab) {
                    case 'floor':
                        $this->render_floor_tab();
                        break;
                    case 'matrix':
                        $this->render_matrix_tab();
                        break;
                    case 'availability':
                        $this->render_availability_tab();
                        break;
                    case 'tables':
                        $this->render_tables_tab();
                        break;
                    case 'log':
                        $this->render_log_tab();
                        break;
                    case 'settings':
                        maca_menulist_render_table_booking_settings_tab();
                        break;
                    default:
                        $this->render_bookings_tab();
                        break;
                }
                ?>
            </div>
        </div>
        <?php
    }

    /**
     * Render bookings list tab.
     */
    private function render_bookings_tab() {
        $view_id = isset($_GET['booking_id']) ? absint(wp_unslash($_GET['booking_id'])) : 0;
        $day_date = isset($_GET['booking_date']) ? sanitize_text_field(wp_unslash($_GET['booking_date'])) : wp_date('Y-m-d');

        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $day_date)) {
            $day_date = wp_date('Y-m-d');
        }

        if ($view_id > 0) {
            $this->render_booking_detail($view_id, $day_date);
            return;
        }

        $pending_bookings = maca_menulist_db_list_bookings(
            array(
                'status' => 'pending',
                'per_page' => 500,
                'paged' => 1,
            )
        );

        $waitlist_bookings = maca_menulist_table_booking_waitlist_enabled()
            ? maca_menulist_db_list_bookings(
                array(
                    'status' => 'waitlist',
                    'per_page' => 500,
                    'paged' => 1,
                )
            )
            : array();

        $day_bookings = maca_menulist_db_list_bookings(
            array(
                'status' => 'confirmed',
                'date_from' => $day_date,
                'date_to' => $day_date,
                'per_page' => 200,
                'paged' => 1,
            )
        );

        $base_url = admin_url('admin.php?page=maca-restu-bookings&tab=bookings');
        $day_url = add_query_arg('booking_date', $day_date, $base_url);
        $today = wp_date('Y-m-d');
        $day_label = maca_menulist_format_wp_date($day_date);
        ?>
        <p class="description">
            <?php esc_html_e('Shortcodes:', 'maca-restu-pro'); ?>
            <code>[maca_table_booking]</code>,
            <code>[maca_opening_hours]</code>
            <?php esc_html_e('or Gutenberg blocks "maca Table Reservation" and "maca Opening hours".', 'maca-restu-pro'); ?>
        </p>

        <section class="maca-bookings-section maca-bookings-section-pending">
            <h2 class="maca-bookings-section-title">
                <?php esc_html_e('Unanswered requests', 'maca-restu-pro'); ?>
                <span class="count">(<?php echo esc_html((string) count($pending_bookings)); ?>)</span>
            </h2>
            <p class="description"><?php esc_html_e('Pending booking requests waiting for your confirmation.', 'maca-restu-pro'); ?></p>
            <?php $this->render_bookings_table($pending_bookings, $day_url, 'pending'); ?>
        </section>

        <?php if (maca_menulist_table_booking_waitlist_enabled()) : ?>
        <section class="maca-bookings-section maca-bookings-section-waitlist">
            <h2 class="maca-bookings-section-title">
                <?php esc_html_e('Waitlist', 'maca-restu-pro'); ?>
                <span class="count">(<?php echo esc_html((string) count($waitlist_bookings)); ?>)</span>
            </h2>
            <p class="description"><?php esc_html_e('Guests waiting for a table. Assign a table and confirm when you have availability.', 'maca-restu-pro'); ?></p>
            <?php $this->render_bookings_table($waitlist_bookings, $day_url, 'waitlist'); ?>
        </section>
        <?php endif; ?>

        <section class="maca-bookings-section maca-bookings-section-day">
            <div class="maca-bookings-day-header">
                <h2 class="maca-bookings-section-title">
                    <?php
                    printf(
                        /* translators: %s: formatted date */
                        esc_html__('Bookings for %s', 'maca-restu-pro'),
                        esc_html($day_label)
                    );
                    ?>
                    <span class="count">(<?php echo esc_html((string) count($day_bookings)); ?>)</span>
                </h2>

                <div class="maca-bookings-day-actions">
                    <a
                        class="button button-secondary"
                        href="<?php echo esc_url(add_query_arg(array('tab' => 'floor', 'booking_date' => $day_date), admin_url('admin.php?page=maca-restu-bookings'))); ?>"
                    >
                        <?php esc_html_e('Salongsöversikt', 'maca-restu-pro'); ?>
                    </a>
                    <form method="get" action="<?php echo esc_url(admin_url('admin.php')); ?>" class="maca-bookings-day-filter">
                        <input type="hidden" name="page" value="maca-restu-bookings">
                        <input type="hidden" name="tab" value="bookings">
                        <label for="maca-bookings-day-date" class="screen-reader-text"><?php esc_html_e('Date', 'maca-restu-pro'); ?></label>
                        <input type="date" id="maca-bookings-day-date" name="booking_date" value="<?php echo esc_attr($day_date); ?>">
                        <?php submit_button(__('Show date', 'maca-restu-pro'), 'secondary', 'submit', false); ?>
                        <?php if ($day_date !== $today) : ?>
                            <a href="<?php echo esc_url(add_query_arg('booking_date', $today, $base_url)); ?>" class="button">
                                <?php esc_html_e('Today', 'maca-restu-pro'); ?>
                            </a>
                        <?php endif; ?>
                    </form>
                </div>
            </div>
            <p class="description"><?php esc_html_e('Confirmed bookings for the selected day.', 'maca-restu-pro'); ?></p>
            <?php $this->render_bookings_table($day_bookings, $day_url, 'day'); ?>
        </section>

        <p class="maca-bookings-archive-link">
            <a href="<?php echo esc_url(add_query_arg(array('tab' => 'bookings', 'archive' => 'cancelled'), admin_url('admin.php?page=maca-restu-bookings'))); ?>">
                <?php
                printf(
                    /* translators: %d: number of cancelled bookings */
                    esc_html__('View cancelled bookings (%d)', 'maca-restu-pro'),
                    (int) maca_menulist_db_count_bookings(array('status' => 'cancelled'))
                );
                ?>
            </a>
        </p>
        <?php

        if (isset($_GET['archive']) && sanitize_key(wp_unslash($_GET['archive'])) === 'cancelled') {
            $cancelled_bookings = maca_menulist_db_list_bookings(
                array(
                    'status' => 'cancelled',
                    'per_page' => 100,
                    'paged' => isset($_GET['paged']) ? max(1, absint(wp_unslash($_GET['paged']))) : 1,
                )
            );
            ?>
            <section class="maca-bookings-section maca-bookings-section-archive">
                <h2 class="maca-bookings-section-title"><?php esc_html_e('Cancelled bookings', 'maca-restu-pro'); ?></h2>
                <?php $this->render_bookings_table($cancelled_bookings, $day_url, 'archive'); ?>
            </section>
            <?php
        }
    }

    /**
     * AJAX: list bookable tables for staff manual booking.
     */
    public function ajax_staff_booking_tables() {
        if (!maca_menulist_verify_booking_management_ajax()) {
            maca_menulist_booking_management_ajax_deny();
        }

        $date = isset($_POST['booking_date']) ? sanitize_text_field(wp_unslash($_POST['booking_date'])) : '';
        $time = isset($_POST['booking_time']) ? sanitize_text_field(wp_unslash($_POST['booking_time'])) : '';
        $party_size = isset($_POST['party_size']) ? max(1, (int) wp_unslash($_POST['party_size'])) : 2;

        if ($date === '' || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {
            wp_send_json_error(array('message' => __('Invalid date.', 'maca-restu-pro')));
        }

        wp_send_json_success(
            array(
                'tables' => maca_menulist_get_staff_booking_table_options($date, $time, $party_size),
            )
        );
    }

    /**
     * AJAX: create a confirmed staff booking.
     */
    public function ajax_create_staff_booking() {
        if (!maca_menulist_verify_booking_management_ajax()) {
            maca_menulist_booking_management_ajax_deny();
        }

        $table_key = isset($_POST['table_key']) ? sanitize_text_field(wp_unslash($_POST['table_key'])) : '';
        $table_id = 0;
        $split_slot = '';

        if ($table_key !== '' && $table_key !== 'auto') {
            $parts = explode(':', $table_key, 2);
            $table_id = isset($parts[0]) ? absint($parts[0]) : 0;
            $split_slot = isset($parts[1]) ? maca_menulist_normalize_split_slot($parts[1]) : '';
        }

        $result = maca_menulist_create_staff_booking(
            array(
                'booking_date'  => isset($_POST['booking_date']) ? sanitize_text_field(wp_unslash($_POST['booking_date'])) : '',
                'booking_time'  => isset($_POST['booking_time']) ? sanitize_text_field(wp_unslash($_POST['booking_time'])) : '',
                'party_size'    => isset($_POST['party_size']) ? max(1, (int) wp_unslash($_POST['party_size'])) : 2,
                'guest_name'    => isset($_POST['guest_name']) ? sanitize_text_field(wp_unslash($_POST['guest_name'])) : '',
                'guest_phone'   => isset($_POST['guest_phone']) ? sanitize_text_field(wp_unslash($_POST['guest_phone'])) : '',
                'guest_email'   => isset($_POST['guest_email']) ? sanitize_email(wp_unslash($_POST['guest_email'])) : '',
                'guest_note'    => isset($_POST['guest_note']) ? sanitize_textarea_field(wp_unslash($_POST['guest_note'])) : '',
                'table_id'      => $table_id,
                'split_slot'    => $split_slot,
                'send_email'    => !empty($_POST['send_email']),
                'waitlist'      => !empty($_POST['waitlist']),
            )
        );

        if (is_wp_error($result)) {
            wp_send_json_error(array('message' => $result->get_error_message()));
        }

        $booking = maca_menulist_db_get_booking((int) $result);

        wp_send_json_success(
            array(
                'message'    => __('Bokningen är sparad.', 'maca-restu-pro'),
                'booking_id' => (int) $result,
                'booking_url' => $booking
                    ? add_query_arg(
                        array(
                            'tab' => 'bookings',
                            'booking_date' => $booking->booking_date,
                            'booking_id' => (int) $result,
                        ),
                        admin_url('admin.php?page=maca-restu-bookings')
                    )
                    : '',
            )
        );
    }

    /**
     * AJAX: move booking to another table.
     */
    public function ajax_move_booking() {
        if (!maca_menulist_verify_booking_management_ajax()) {
            maca_menulist_booking_management_ajax_deny();
        }

        $booking_id = isset($_POST['booking_id']) ? absint(wp_unslash($_POST['booking_id'])) : 0;
        $table_id = isset($_POST['table_id']) ? absint(wp_unslash($_POST['table_id'])) : 0;

        if ($booking_id <= 0) {
            wp_send_json_error(array('message' => __('Booking not found.', 'maca-restu-pro')));
        }

        $split_slot = isset($_POST['split_slot']) ? sanitize_text_field(wp_unslash($_POST['split_slot'])) : '';
        $floor_time = isset($_POST['floor_time']) ? sanitize_text_field(wp_unslash($_POST['floor_time'])) : '';
        $booking_before = maca_menulist_db_get_booking($booking_id);
        $from_waitlist = $booking_before && $booking_before->status === 'waitlist';
        $result = maca_menulist_move_booking_to_table($booking_id, $table_id, $split_slot, $floor_time);

        if (is_wp_error($result)) {
            wp_send_json_error(array('message' => $result->get_error_message()));
        }

        $booking = maca_menulist_db_get_booking($booking_id);
        $table_number = '';
        if ($booking && $booking->table_id) {
            $table_row = maca_menulist_db_get_booking_table((int) $booking->table_id);
            if ($table_row) {
                $slot = isset($booking->split_slot) ? maca_menulist_normalize_split_slot((string) $booking->split_slot) : '';
                $table_number = $slot !== ''
                    ? maca_menulist_format_split_table_number((string) $table_row->table_number, $slot)
                    : (string) $table_row->table_number;
            }
        }

        $message = $from_waitlist
            ? __('Guest placed on table at the selected time. Booking is now pending — confirm to notify the guest.', 'maca-restu-pro')
            : __('Bokningen placerades på valt bord.', 'maca-restu-pro');

        wp_send_json_success(
            array(
                'message' => $message,
                'table_number' => $table_number,
                'from_waitlist' => $from_waitlist,
            )
        );
    }

    /**
     * AJAX: split a splittable table for the selected day (floor overview).
     */
    public function ajax_split_table_day() {
        if (!maca_menulist_verify_booking_management_ajax()) {
            maca_menulist_booking_management_ajax_deny();
        }

        $table_id = isset($_POST['table_id']) ? absint(wp_unslash($_POST['table_id'])) : 0;
        $date = isset($_POST['booking_date']) ? sanitize_text_field(wp_unslash($_POST['booking_date'])) : '';

        $layout = isset($_POST['day_layout']) ? trim((string) wp_unslash($_POST['day_layout'])) : 'default';

        $result = maca_menulist_split_table_for_date($table_id, $date, $layout);

        if (is_wp_error($result)) {
            wp_send_json_error(array('message' => $result->get_error_message()));
        }

        $table = maca_menulist_db_get_booking_table($table_id);
        $layout_label = $table ? maca_menulist_table_split_layout_label($table, $date) : '';

        wp_send_json_success(
            array(
                'message' => $layout_label !== ''
                    ? sprintf(
                        /* translators: %s: layout e.g. 4+2 */
                        __('Bordet är delat för vald dag (%s).', 'maca-restu-pro'),
                        $layout_label
                    )
                    : __('Bordet är delat för vald dag.', 'maca-restu-pro'),
            )
        );
    }

    /**
     * AJAX: merge split table parts for the selected day.
     */
    public function ajax_unsplit_table_day() {
        if (!maca_menulist_verify_booking_management_ajax()) {
            maca_menulist_booking_management_ajax_deny();
        }

        $table_id = isset($_POST['table_id']) ? absint(wp_unslash($_POST['table_id'])) : 0;
        $date = isset($_POST['booking_date']) ? sanitize_text_field(wp_unslash($_POST['booking_date'])) : '';

        $result = maca_menulist_unsplit_table_for_date($table_id, $date);

        if (is_wp_error($result)) {
            wp_send_json_error(array('message' => $result->get_error_message()));
        }

        wp_send_json_success(array('message' => __('Bordet är ihopslaget för vald dag.', 'maca-restu-pro')));
    }

    /**
     * AJAX: admin floor overview (time slots and/or table status).
     */
    public function ajax_booking_floor() {
        if (!maca_menulist_verify_booking_management_ajax()) {
            maca_menulist_booking_management_ajax_deny();
        }

        $date = isset($_POST['booking_date']) ? sanitize_text_field(wp_unslash($_POST['booking_date'])) : '';
        if ($date === '' || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {
            wp_send_json_error(array('message' => __('Invalid date.', 'maca-restu-pro')));
        }

        $slots = maca_menulist_get_admin_booking_time_slots($date);
        $time = isset($_POST['booking_time']) ? sanitize_text_field(wp_unslash($_POST['booking_time'])) : '';

        $day_occupancy = maca_menulist_get_date_floor_day_occupancy($date);

        if (function_exists('maca_menulist_db_repair_cancelled_booking_table_assignments')) {
            maca_menulist_db_repair_cancelled_booking_table_assignments($date);
        }

        if ($time === '') {
            wp_send_json_success(
                array(
                    'slots'         => $slots,
                    'status'        => null,
                    'day_occupancy' => $day_occupancy,
                )
            );
        }

        wp_send_json_success(
            array(
                'slots'         => $slots,
                'status'        => maca_menulist_get_admin_booking_floor_status($date, $time),
                'day_occupancy' => $day_occupancy,
            )
        );
    }

    /**
     * AJAX: seat matrix for one date (times × bookable seats).
     */
    public function ajax_booking_seat_matrix() {
        if (!maca_menulist_verify_booking_management_ajax()) {
            maca_menulist_booking_management_ajax_deny();
        }

        $date = isset($_POST['booking_date']) ? sanitize_text_field(wp_unslash($_POST['booking_date'])) : '';
        if ($date === '' || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {
            wp_send_json_error(array('message' => __('Invalid date.', 'maca-restu-pro')));
        }

        wp_send_json_success(maca_menulist_get_admin_booking_seat_matrix($date));
    }

    /**
     * AJAX: availability overview table (computed on demand).
     */
    public function ajax_booking_availability() {
        if (!maca_menulist_verify_booking_management_ajax()) {
            maca_menulist_booking_management_ajax_deny();
        }

        ob_start();
        $this->render_availability_tab_content();
        wp_send_json_success(
            array(
                'html' => ob_get_clean(),
            )
        );
    }

    /**
     * Render seat matrix tab (times × seats, green/red).
     */
    private function render_matrix_tab() {
        $today = wp_date('Y-m-d');
        $matrix_date = isset($_GET['booking_date']) ? sanitize_text_field(wp_unslash($_GET['booking_date'])) : $today;

        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $matrix_date)) {
            $matrix_date = $today;
        }

        $floor_url = add_query_arg(
            array(
                'tab' => 'floor',
                'booking_date' => $matrix_date,
            ),
            admin_url('admin.php?page=maca-restu-bookings')
        );
        ?>
        <div class="maca-booking-matrix" id="maca-booking-matrix" data-initial-date="<?php echo esc_attr($matrix_date); ?>">
            <p class="description">
                <?php esc_html_e('Overview of every bookable seat for the selected day. Green = available, red = occupied at that time. Split table parts (e.g. 8a, 8b) appear as separate columns.', 'maca-restu-pro'); ?>
                <a href="<?php echo esc_url($floor_url); ?>"><?php esc_html_e('Open salon overview for one time', 'maca-restu-pro'); ?></a>
            </p>

            <div class="maca-booking-matrix-toolbar">
                <label for="maca-booking-matrix-date"><?php esc_html_e('Datum', 'maca-restu-pro'); ?></label>
                <input type="date" id="maca-booking-matrix-date" class="maca-booking-matrix-date" value="<?php echo esc_attr($matrix_date); ?>">
                <div class="maca-booking-matrix-legend" aria-hidden="true">
                    <span class="maca-booking-matrix-legend-item">
                        <span class="maca-booking-matrix-cell-inner maca-booking-matrix-cell-free"></span>
                        <?php esc_html_e('Ledigt', 'maca-restu-pro'); ?>
                    </span>
                    <span class="maca-booking-matrix-legend-item">
                        <span class="maca-booking-matrix-cell-inner maca-booking-matrix-cell-busy"></span>
                        <?php esc_html_e('Upptaget', 'maca-restu-pro'); ?>
                    </span>
                </div>
            </div>

            <p class="maca-booking-matrix-message" id="maca-booking-matrix-message" role="status"></p>
            <div class="maca-booking-matrix-table-wrap" id="maca-booking-matrix-table-wrap" aria-busy="true">
                <p class="maca-booking-matrix-loading"><?php esc_html_e('Laddar…', 'maca-restu-pro'); ?></p>
            </div>
        </div>
        <?php
    }

    /**
     * Render floor overview tab (table grid + timeline).
     */
    private function render_floor_tab() {
        $today = wp_date('Y-m-d');
        $floor_date = isset($_GET['booking_date']) ? sanitize_text_field(wp_unslash($_GET['booking_date'])) : $today;

        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $floor_date)) {
            $floor_date = $today;
        }

        $slot_duration = maca_menulist_table_booking_slot_duration();
        $day_occupancy = maca_menulist_get_date_floor_day_occupancy($floor_date);
        $day_occupancy_class = 'maca-booking-occupancy-low';
        if (($day_occupancy['level'] ?? '') === 'high') {
            $day_occupancy_class = 'maca-booking-occupancy-high';
        } elseif (($day_occupancy['level'] ?? '') === 'medium') {
            $day_occupancy_class = 'maca-booking-occupancy-medium';
        }
        $bookings_day_url = add_query_arg(
            array(
                'tab' => 'bookings',
                'booking_date' => $floor_date,
            ),
            admin_url('admin.php?page=maca-restu-bookings')
        );
        ?>
        <div class="maca-booking-floor" id="maca-booking-floor" data-initial-date="<?php echo esc_attr($floor_date); ?>">
            <div class="maca-booking-floor-top-links">
                <a
                    class="button button-secondary maca-booking-floor-link-bookings"
                    id="maca-booking-floor-link-bookings"
                    href="<?php echo esc_url($bookings_day_url); ?>"
                >
                    <?php esc_html_e('Visa bokningar för dagen', 'maca-restu-pro'); ?>
                </a>
                <button type="button" class="button button-primary" id="maca-booking-floor-add-toggle" aria-expanded="false" aria-controls="maca-booking-floor-add-panel">
                    <?php esc_html_e('Lägg till bokning', 'maca-restu-pro'); ?>
                </button>
            </div>

            <div class="maca-booking-floor-add-panel" id="maca-booking-floor-add-panel" hidden>
                <h3 class="maca-booking-floor-add-title"><?php esc_html_e('Manuell bokning (telefon / walk-in)', 'maca-restu-pro'); ?></h3>
                <p class="description maca-booking-floor-add-desc-confirmed"><?php esc_html_e('Bokningen sparas som bekräftad direkt. Datum och tid hämtas från verktygsraden ovan.', 'maca-restu-pro'); ?></p>
                <?php if (maca_menulist_table_booking_waitlist_enabled()) : ?>
                <p class="description maca-booking-floor-add-desc-waitlist" hidden><?php esc_html_e('Sparas på väntlistan utan bord. Skicka e-post om gästen har angivit adress och kryssat i Skicka e-post.', 'maca-restu-pro'); ?></p>
                <?php endif; ?>
                <form id="maca-booking-floor-add-form" class="maca-booking-floor-add-form">
                    <p>
                        <label for="maca-floor-add-name"><strong><?php esc_html_e('Namn', 'maca-restu-pro'); ?></strong></label><br>
                        <input type="text" id="maca-floor-add-name" name="guest_name" class="regular-text" required autocomplete="name">
                    </p>
                    <p>
                        <label for="maca-floor-add-phone"><strong><?php esc_html_e('Telefon', 'maca-restu-pro'); ?></strong></label><br>
                        <input type="tel" id="maca-floor-add-phone" name="guest_phone" class="regular-text" required autocomplete="tel">
                    </p>
                    <p>
                        <label for="maca-floor-add-email"><?php esc_html_e('E-post (valfritt)', 'maca-restu-pro'); ?></label><br>
                        <input type="email" id="maca-floor-add-email" name="guest_email" class="regular-text" autocomplete="email">
                    </p>
                    <p>
                        <label for="maca-floor-add-party"><strong><?php esc_html_e('Antal gäster', 'maca-restu-pro'); ?></strong></label><br>
                        <input type="number" id="maca-floor-add-party" name="party_size" min="1" max="99" value="2" class="small-text" required>
                    </p>
                    <?php if (maca_menulist_table_booking_waitlist_enabled()) : ?>
                    <p>
                        <label>
                            <input type="checkbox" id="maca-floor-add-waitlist" name="waitlist" value="1">
                            <?php esc_html_e('Spara som väntlista (inget bord)', 'maca-restu-pro'); ?>
                        </label>
                    </p>
                    <?php endif; ?>
                    <p class="maca-booking-floor-add-table-row">
                        <label for="maca-floor-add-table"><strong><?php esc_html_e('Bord', 'maca-restu-pro'); ?></strong></label><br>
                        <select id="maca-floor-add-table" name="table_key">
                            <option value="auto"><?php esc_html_e('Automatiskt ledigt bord', 'maca-restu-pro'); ?></option>
                        </select>
                    </p>
                    <p>
                        <label for="maca-floor-add-note"><?php esc_html_e('Anteckning', 'maca-restu-pro'); ?></label><br>
                        <input type="text" id="maca-floor-add-note" name="guest_note" class="large-text">
                    </p>
                    <p>
                        <label>
                            <input type="checkbox" id="maca-floor-add-send-email" name="send_email" value="1">
                            <span class="maca-floor-add-email-label-confirmed"><?php esc_html_e('Skicka bekräftelse via e-post', 'maca-restu-pro'); ?></span>
                            <span class="maca-floor-add-email-label-waitlist" hidden><?php esc_html_e('Skicka väntlista via e-post', 'maca-restu-pro'); ?></span>
                        </label>
                    </p>
                    <p class="maca-booking-floor-add-actions">
                        <button type="submit" class="button button-primary"><?php esc_html_e('Spara bokning', 'maca-restu-pro'); ?></button>
                        <button type="button" class="button" id="maca-booking-floor-add-cancel"><?php esc_html_e('Avbryt', 'maca-restu-pro'); ?></button>
                    </p>
                </form>
            </div>
            <p class="description">
                <?php
                esc_html_e(
                    'Se bord vid vald tid. Klicka ett grönt (ledigt) eller orange (delbart) bord för att boka där, eller använd Lägg till bokning. Delningsbara bord: Dela bord idag visar t.ex. 8a, 8b. Dra befintliga bokningar mellan delar. Gäster bokar hela bordet online.',
                    'maca-restu-pro'
                );
                ?>
            </p>
            <p class="description maca-booking-floor-slot-hint">
                <?php
                printf(
                    /* translators: %d: slot duration in minutes */
                    esc_html__('Bokningsslot: %d minuter.', 'maca-restu-pro'),
                    (int) $slot_duration
                );
                ?>
            </p>

            <div class="maca-booking-floor-toolbar">
                <div class="maca-booking-floor-field">
                    <label for="maca-booking-floor-date"><?php esc_html_e('Datum', 'maca-restu-pro'); ?></label>
                    <input type="date" id="maca-booking-floor-date" class="maca-booking-floor-date" value="<?php echo esc_attr($floor_date); ?>">
                </div>
                <div class="maca-booking-floor-field maca-booking-floor-field-time">
                    <label for="maca-booking-floor-time"><?php esc_html_e('Tid', 'maca-restu-pro'); ?></label>
                    <output id="maca-booking-floor-time-label" class="maca-booking-floor-time-label" for="maca-booking-floor-time"></output>
                    <input type="range" id="maca-booking-floor-time" class="maca-booking-floor-time" min="0" max="0" value="0" step="1" disabled>
                </div>
                <div class="maca-booking-floor-field maca-booking-floor-field-occupancy">
                    <span class="maca-booking-floor-occupancy-label"><?php esc_html_e('Day occupancy', 'maca-restu-pro'); ?></span>
                    <span
                        id="maca-booking-floor-day-occupancy"
                        class="maca-booking-floor-day-occupancy maca-booking-occupancy <?php echo esc_attr($day_occupancy_class); ?>"
                        aria-live="polite"
                        <?php if ((int) ($day_occupancy['peak_capacity'] ?? 0) > 0) : ?>
                            title="<?php
                            echo esc_attr(
                                sprintf(
                                    /* translators: 1: booked guests, 2: peak capacity */
                                    __('Day occupancy: %1$d / %2$d', 'maca-restu-pro'),
                                    (int) $day_occupancy['booked_seats'],
                                    (int) $day_occupancy['peak_capacity']
                                )
                            );
                            ?>"
                        <?php endif; ?>
                    >
                        <?php
                        if ((int) ($day_occupancy['peak_capacity'] ?? 0) <= 0) {
                            esc_html_e('—', 'maca-restu-pro');
                        } else {
                            echo esc_html(
                                sprintf(
                                    /* translators: 1: occupancy percent, 2: booked guests, 3: peak capacity */
                                    __('%1$d%% (%2$d / %3$d)', 'maca-restu-pro'),
                                    (int) $day_occupancy['percent'],
                                    (int) $day_occupancy['booked_seats'],
                                    (int) $day_occupancy['peak_capacity']
                                )
                            );
                        }
                        ?>
                    </span>
                </div>
                <div class="maca-booking-floor-legend" aria-hidden="true">
                    <span class="maca-booking-floor-legend-item maca-booking-floor-legend-available">
                        <span class="maca-booking-floor-seat maca-booking-floor-seat-available"></span>
                        <?php esc_html_e('Ledigt', 'maca-restu-pro'); ?>
                    </span>
                    <span class="maca-booking-floor-legend-item maca-booking-floor-legend-occupied">
                        <span class="maca-booking-floor-seat maca-booking-floor-seat-occupied"></span>
                        <?php esc_html_e('Upptaget', 'maca-restu-pro'); ?>
                    </span>
                    <span class="maca-booking-floor-legend-item maca-booking-floor-legend-shareable">
                        <span class="maca-booking-floor-seat maca-booking-floor-seat-shareable"></span>
                        <?php esc_html_e('Kan delas', 'maca-restu-pro'); ?>
                    </span>
                </div>
            </div>

            <p class="maca-booking-floor-summary" id="maca-booking-floor-summary" aria-live="polite"></p>
            <p class="maca-booking-floor-message" id="maca-booking-floor-message" role="status"></p>

            <div class="maca-booking-floor-layout">
                <aside class="maca-booking-floor-queue" id="maca-booking-floor-queue" aria-labelledby="maca-booking-floor-queue-title">
                    <h3 class="maca-booking-floor-queue-title" id="maca-booking-floor-queue-title"><?php esc_html_e('Pending & waitlist', 'maca-restu-pro'); ?></h3>
                    <p class="description maca-booking-floor-queue-hint"><?php esc_html_e('Drag onto a green or orange table. Waitlist shows preferred time; set the slider to an available slot (e.g. 20:00) to place the guest there.', 'maca-restu-pro'); ?></p>
                    <div class="maca-booking-floor-queue-list" id="maca-booking-floor-queue-list"></div>
                </aside>
                <div class="maca-booking-floor-grid" id="maca-booking-floor-grid" aria-busy="true">
                    <p class="maca-booking-floor-loading"><?php esc_html_e('Laddar…', 'maca-restu-pro'); ?></p>
                </div>
            </div>
        </div>
        <?php
    }

    /**
     * Render date availability overview tab (loads data via AJAX).
     */
    private function render_availability_tab() {
        ?>
        <div class="maca-bookings-availability" id="maca-bookings-availability" aria-busy="true">
            <div class="maca-bookings-availability-loading" id="maca-bookings-availability-loading" role="status">
                <span class="spinner is-active" aria-hidden="true"></span>
                <span><?php esc_html_e('Laddar lediga platser…', 'maca-restu-pro'); ?></span>
            </div>
            <div class="maca-bookings-availability-content" id="maca-bookings-availability-content" hidden></div>
            <p class="maca-bookings-availability-message" id="maca-bookings-availability-message" role="alert" hidden></p>
        </div>
        <?php
    }

    /**
     * Render availability table HTML (used by AJAX).
     */
    private function render_availability_tab_content() {
        $rows = maca_menulist_get_booking_availability_overview();
        $bookings_url = admin_url('admin.php?page=maca-restu-bookings&tab=bookings');
        $today = wp_date('Y-m-d');
        ?>
        <p class="description">
            <?php esc_html_e('Peak capacity = bookable seats × sittings. Sittings = opening hours ÷ booking duration (e.g. 16:00–20:00 with 120 min bookings = 2 sittings). Occupancy = confirmed + pending guests ÷ peak capacity.', 'maca-restu-pro'); ?>
        </p>

        <table class="wp-list-table widefat fixed striped maca-bookings-availability-table">
            <thead>
                <tr>
                    <th><?php esc_html_e('Date', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Status', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Peak capacity', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Remaining capacity', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Occupancy', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Confirmed guests', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Pending guests', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Waitlist guests', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Actions', 'maca-restu-pro'); ?></th>
                </tr>
            </thead>
            <tbody>
                <?php if (empty($rows)) : ?>
                    <tr><td colspan="9"><?php esc_html_e('No dates in the booking window.', 'maca-restu-pro'); ?></td></tr>
                <?php else : ?>
                    <?php foreach ($rows as $row) : ?>
                        <?php
                        $status = $row['status'];
                        $is_today = ($row['date'] === $today);
                        ?>
                        <tr<?php echo $is_today ? ' class="maca-bookings-availability-today"' : ''; ?>>
                            <td>
                                <strong><?php echo esc_html($row['date_label']); ?></strong>
                                <br>
                                <span class="description"><?php echo esc_html($row['weekday']); ?></span>
                                <?php if ($is_today) : ?>
                                    <br><span class="maca-bookings-today-badge"><?php esc_html_e('Today', 'maca-restu-pro'); ?></span>
                                <?php endif; ?>
                            </td>
                            <td>
                                <span class="maca-booking-availability-status maca-booking-availability-status-<?php echo esc_attr($status['key']); ?>">
                                    <?php echo esc_html($status['label']); ?>
                                </span>
                            </td>
                            <td>
                                <?php
                                echo esc_html((string) (int) $row['peak_capacity']);
                                if (!empty($row['seats_per_sitting']) && !empty($row['sitting_count'])) {
                                    echo '<br><span class="description">';
                                    echo esc_html(
                                        sprintf(
                                            /* translators: 1: seats per sitting, 2: number of sittings */
                                            __('%1$d seats × %2$d sittings', 'maca-restu-pro'),
                                            (int) $row['seats_per_sitting'],
                                            (int) $row['sitting_count']
                                        )
                                    );
                                    echo '</span>';
                                }
                                ?>
                            </td>
                            <td>
                                <strong><?php echo esc_html((string) (int) $row['available_seats']); ?></strong>
                                <?php if (isset($row['max_free_slot']) && (int) $row['max_free_slot'] > 0) : ?>
                                    <br><span class="description">
                                        <?php
                                        echo esc_html(
                                            sprintf(
                                                /* translators: %d: free seats in the best time slot */
                                                __('Max %d free in one sitting', 'maca-restu-pro'),
                                                (int) $row['max_free_slot']
                                            )
                                        );
                                        ?>
                                    </span>
                                <?php endif; ?>
                            </td>
                            <td>
                                <?php
                                $occupancy = (int) $row['occupancy_percent'];
                                $occupancy_class = 'maca-booking-occupancy-low';

                                if ($occupancy >= 90) {
                                    $occupancy_class = 'maca-booking-occupancy-high';
                                } elseif ($occupancy >= 70) {
                                    $occupancy_class = 'maca-booking-occupancy-medium';
                                }
                                ?>
                                <span class="maca-booking-occupancy <?php echo esc_attr($occupancy_class); ?>">
                                    <?php echo esc_html($occupancy . '%'); ?>
                                </span>
                            </td>
                            <td><?php echo esc_html((string) (int) $row['confirmed_guests']); ?></td>
                            <td><?php echo esc_html((string) (int) $row['pending_guests']); ?></td>
                            <td><?php echo esc_html((string) (int) $row['waitlist_guests']); ?></td>
                            <td>
                                <a href="<?php echo esc_url(add_query_arg('booking_date', $row['date'], $bookings_url)); ?>" class="button button-small">
                                    <?php esc_html_e('View bookings', 'maca-restu-pro'); ?>
                                </a>
                            </td>
                        </tr>
                    <?php endforeach; ?>
                <?php endif; ?>
            </tbody>
        </table>
        <?php
    }

    /**
     * Render a bookings table.
     *
     * @param array<int, object> $bookings   Booking rows.
     * @param string             $base_url   Base URL for view links.
     * @param string             $context    pending|day|archive.
     */
    private function render_bookings_table($bookings, $base_url, $context = 'day') {
        $empty_messages = array(
            'pending' => __('No unanswered booking requests right now.', 'maca-restu-pro'),
            'waitlist' => __('No one on the waitlist right now.', 'maca-restu-pro'),
            'day' => __('No confirmed bookings on this date.', 'maca-restu-pro'),
            'archive' => __('No cancelled bookings found.', 'maca-restu-pro'),
        );
        $empty_message = isset($empty_messages[$context]) ? $empty_messages[$context] : __('No bookings found.', 'maca-restu-pro');
        ?>
        <table class="wp-list-table widefat fixed striped maca-bookings-list-table">
            <thead>
                <tr>
                    <th><?php esc_html_e('Date & time', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Guest', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Guests', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Table', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Status', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Actions', 'maca-restu-pro'); ?></th>
                </tr>
            </thead>
            <tbody>
                <?php if (empty($bookings)) : ?>
                    <tr><td colspan="6"><?php echo esc_html($empty_message); ?></td></tr>
                <?php else : ?>
                    <?php foreach ($bookings as $booking) : ?>
                        <tr>
                            <td><?php echo esc_html(maca_menulist_format_booking_datetime($booking)); ?></td>
                            <td>
                                <strong><?php echo esc_html($booking->guest_name); ?></strong><br>
                                <a href="mailto:<?php echo esc_attr($booking->guest_email); ?>"><?php echo esc_html($booking->guest_email); ?></a>
                                <?php if (!empty($booking->guest_phone)) : ?>
                                    <br><?php echo esc_html($booking->guest_phone); ?>
                                <?php endif; ?>
                            </td>
                            <td><?php echo esc_html((string) $booking->party_size); ?></td>
                            <td>
                                <?php
                                $display_table = function_exists('maca_menulist_get_booking_display_table_number')
                                    ? maca_menulist_get_booking_display_table_number($booking)
                                    : (string) $booking->table_number;
                                echo $display_table !== ''
                                    ? esc_html(sprintf(/* translators: %s: table number */ __('Table %s', 'maca-restu-pro'), $display_table))
                                    : esc_html__('—', 'maca-restu-pro');
                                ?>
                            </td>
                            <td>
                                <span class="maca-booking-status maca-booking-status-<?php echo esc_attr($booking->status); ?>">
                                    <?php echo esc_html(maca_menulist_get_booking_status_label($booking->status)); ?>
                                </span>
                            </td>
                            <td>
                                <a href="<?php echo esc_url($base_url . '&booking_id=' . (int) $booking->id); ?>" class="button button-small">
                                    <?php
                                    echo in_array($context, array('pending', 'waitlist'), true)
                                        ? esc_html__('Review', 'maca-restu-pro')
                                        : esc_html__('View', 'maca-restu-pro');
                                    ?>
                                </a>
                            </td>
                        </tr>
                    <?php endforeach; ?>
                <?php endif; ?>
            </tbody>
        </table>
        <?php
    }

    /**
     * Render single booking detail.
     *
     * @param int    $booking_id Booking ID.
     * @param string $day_date   Selected day filter for back link.
     */
    private function render_booking_detail($booking_id, $day_date = '') {
        $booking = maca_menulist_db_get_booking($booking_id);
        $back_url = admin_url('admin.php?page=maca-restu-bookings&tab=bookings');

        if ($day_date !== '' && preg_match('/^\d{4}-\d{2}-\d{2}$/', $day_date)) {
            $back_url = add_query_arg('booking_date', $day_date, $back_url);
        }

        $detail_url = add_query_arg(
            array(
                'page' => 'maca-restu-bookings',
                'tab' => 'bookings',
                'booking_id' => $booking_id,
            ),
            admin_url('admin.php')
        );
        if ($day_date !== '' && preg_match('/^\d{4}-\d{2}-\d{2}$/', $day_date)) {
            $detail_url = add_query_arg('booking_date', $day_date, $detail_url);
        }

        if (!$booking) {
            echo '<p>' . esc_html__('Booking not found.', 'maca-restu-pro') . '</p>';
            return;
        }

        settings_errors('maca_bookings');

        $available_tables = maca_menulist_get_available_tables(
            $booking->booking_date,
            substr($booking->booking_time, 0, 5),
            (int) $booking->party_size,
            (int) $booking->id
        );

        if (!empty($booking->table_id)) {
            $current_table = maca_menulist_db_get_booking_table((int) $booking->table_id);
            if ($current_table) {
                $found = false;
                foreach ($available_tables as $table) {
                    if ((int) $table->id === (int) $current_table->id) {
                        $found = true;
                        break;
                    }
                }
                if (!$found) {
                    $available_tables[] = $current_table;
                }
            }
        }
        ?>
        <p>
            <a href="<?php echo esc_url($back_url); ?>">&larr; <?php esc_html_e('Back to list', 'maca-restu-pro'); ?></a>
            <?php if (function_exists('maca_menulist_booking_log_list')) : ?>
                | <a href="<?php echo esc_url(maca_menulist_booking_log_admin_url(array('log_booking_id' => (int) $booking->id))); ?>">
                    <?php esc_html_e('Visa händelselogg', 'maca-restu-pro'); ?>
                </a>
            <?php endif; ?>
        </p>

        <h2><?php echo esc_html(maca_menulist_format_booking_datetime($booking)); ?></h2>

        <?php
        $display_table = function_exists('maca_menulist_get_booking_display_table_number')
            ? maca_menulist_get_booking_display_table_number($booking)
            : (string) $booking->table_number;
        $booking_time_value = substr((string) $booking->booking_time, 0, 5);
        $guest_email_display = (string) $booking->guest_email;
        if ($guest_email_display === maca_menulist_staff_booking_placeholder_email()) {
            $guest_email_display = '';
        }
        $can_edit_booking = in_array($booking->status, array('pending', 'confirmed', 'waitlist'), true);
        ?>

        <table class="form-table maca-booking-detail-summary">
            <tr>
                <th><?php esc_html_e('Status', 'maca-restu-pro'); ?></th>
                <td><?php echo esc_html(maca_menulist_get_booking_status_label($booking->status)); ?></td>
            </tr>
            <tr>
                <th><?php esc_html_e('Table', 'maca-restu-pro'); ?></th>
                <td>
                    <?php
                    echo $display_table !== ''
                        ? esc_html(sprintf(/* translators: %s: table number */ __('Table %s', 'maca-restu-pro'), $display_table))
                        : esc_html__('Not assigned', 'maca-restu-pro');
                    ?>
                </td>
            </tr>
        </table>

        <?php if ($can_edit_booking) : ?>
            <form method="post" class="maca-booking-edit-form" action="<?php echo esc_url($detail_url); ?>">
                <?php wp_nonce_field('maca_bookings', 'maca_bookings_nonce'); ?>
                <input type="hidden" name="maca_bookings_action" value="update_booking">
                <input type="hidden" name="booking_id" value="<?php echo esc_attr((string) $booking->id); ?>">

                <h3><?php esc_html_e('Redigera bokning', 'maca-restu-pro'); ?></h3>

                <table class="form-table">
                    <tr>
                        <th><label for="maca_edit_guest_name"><?php esc_html_e('Guest', 'maca-restu-pro'); ?></label></th>
                        <td>
                            <input type="text" id="maca_edit_guest_name" name="guest_name" class="regular-text" required value="<?php echo esc_attr((string) $booking->guest_name); ?>">
                        </td>
                    </tr>
                    <tr>
                        <th><label for="maca_edit_guest_phone"><?php esc_html_e('Telefon', 'maca-restu-pro'); ?></label></th>
                        <td>
                            <input type="tel" id="maca_edit_guest_phone" name="guest_phone" class="regular-text" required value="<?php echo esc_attr((string) $booking->guest_phone); ?>">
                        </td>
                    </tr>
                    <tr>
                        <th><label for="maca_edit_guest_email"><?php esc_html_e('E-post', 'maca-restu-pro'); ?></label></th>
                        <td>
                            <input type="email" id="maca_edit_guest_email" name="guest_email" class="regular-text" value="<?php echo esc_attr($guest_email_display); ?>">
                            <p class="description"><?php esc_html_e('Valfritt. Lämna tomt om gästen inte har e-post.', 'maca-restu-pro'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th><label for="maca_edit_booking_date"><?php esc_html_e('Date', 'maca-restu-pro'); ?></label></th>
                        <td>
                            <input type="date" id="maca_edit_booking_date" name="booking_date" required value="<?php echo esc_attr((string) $booking->booking_date); ?>">
                        </td>
                    </tr>
                    <tr>
                        <th><label for="maca_edit_booking_time"><?php esc_html_e('Tid', 'maca-restu-pro'); ?></label></th>
                        <td>
                            <input type="time" id="maca_edit_booking_time" name="booking_time" required value="<?php echo esc_attr($booking_time_value); ?>" step="1800">
                        </td>
                    </tr>
                    <tr>
                        <th><label for="maca_edit_party_size"><?php esc_html_e('Party size', 'maca-restu-pro'); ?></label></th>
                        <td>
                            <input type="number" id="maca_edit_party_size" name="party_size" min="1" max="99" required value="<?php echo esc_attr((string) (int) $booking->party_size); ?>" class="small-text">
                        </td>
                    </tr>
                    <tr>
                        <th><label for="maca_edit_guest_note"><?php esc_html_e('Note', 'maca-restu-pro'); ?></label></th>
                        <td>
                            <textarea id="maca_edit_guest_note" name="guest_note" class="large-text" rows="3"><?php echo esc_textarea((string) $booking->guest_note); ?></textarea>
                        </td>
                    </tr>
                </table>

                <p class="description">
                    <?php esc_html_e('Om bokningen har ett bord måste datum, tid och antal gäster fortfarande passa vid det bordet. Byt bord nedan om du behöver flytta bokningen.', 'maca-restu-pro'); ?>
                </p>

                <?php submit_button(__('Spara ändringar', 'maca-restu-pro'), 'primary'); ?>
            </form>
        <?php else : ?>
            <table class="form-table">
                <tr>
                    <th><?php esc_html_e('Guest', 'maca-restu-pro'); ?></th>
                    <td>
                        <?php echo esc_html($booking->guest_name); ?><br>
                        <?php if ($guest_email_display !== '') : ?>
                            <a href="mailto:<?php echo esc_attr($guest_email_display); ?>"><?php echo esc_html($guest_email_display); ?></a><br>
                        <?php endif; ?>
                        <?php if (!empty($booking->guest_phone)) : ?>
                            <?php echo esc_html($booking->guest_phone); ?>
                        <?php endif; ?>
                    </td>
                </tr>
                <tr>
                    <th><?php esc_html_e('Party size', 'maca-restu-pro'); ?></th>
                    <td><?php echo esc_html((string) $booking->party_size); ?></td>
                </tr>
                <?php if (!empty($booking->guest_note)) : ?>
                <tr>
                    <th><?php esc_html_e('Note', 'maca-restu-pro'); ?></th>
                    <td><?php echo esc_html($booking->guest_note); ?></td>
                </tr>
                <?php endif; ?>
            </table>
        <?php endif; ?>

        <?php if (in_array($booking->status, array('pending', 'waitlist'), true)) : ?>
            <form method="post" style="margin-top:1em;" action="<?php echo esc_url($detail_url); ?>">
                <?php wp_nonce_field('maca_bookings', 'maca_bookings_nonce'); ?>
                <input type="hidden" name="maca_bookings_action" value="confirm_booking">
                <input type="hidden" name="booking_id" value="<?php echo esc_attr((string) $booking->id); ?>">

                <?php if ($booking->status === 'waitlist') : ?>
                    <p class="description"><?php esc_html_e('Confirming moves the guest from the waitlist to a confirmed booking and sends a confirmation email.', 'maca-restu-pro'); ?></p>
                <?php endif; ?>

                <table class="form-table">
                    <tr>
                        <th><label for="confirm_table_id"><?php esc_html_e('Assign table', 'maca-restu-pro'); ?></label></th>
                        <td>
                            <select name="table_id" id="confirm_table_id" required>
                                <option value=""><?php esc_html_e('Select table', 'maca-restu-pro'); ?></option>
                                <?php foreach ($available_tables as $table) : ?>
                                    <option value="<?php echo esc_attr((string) $table->id); ?>" <?php selected((int) $booking->table_id, (int) $table->id); ?>>
                                        <?php
                                        echo esc_html(
                                            sprintf(
                                                /* translators: 1: table number, 2: seats */
                                                __('Table %1$s (%2$d seats)', 'maca-restu-pro'),
                                                $table->table_number,
                                                (int) $table->seats
                                            )
                                        );
                                        ?>
                                    </option>
                                <?php endforeach; ?>
                            </select>
                        </td>
                    </tr>
                </table>

                <?php submit_button(__('Confirm booking', 'maca-restu-pro'), 'primary'); ?>
            </form>
        <?php endif; ?>

        <?php
        $move_targets = maca_menulist_get_booking_move_targets((int) $booking->id);
        if (in_array($booking->status, array('pending', 'confirmed', 'waitlist'), true) && !empty($move_targets)) :
            ?>
            <form method="post" style="margin-top:1em;" action="<?php echo esc_url($detail_url); ?>">
                <?php wp_nonce_field('maca_bookings', 'maca_bookings_nonce'); ?>
                <input type="hidden" name="maca_bookings_action" value="move_booking">
                <input type="hidden" name="booking_id" value="<?php echo esc_attr((string) $booking->id); ?>">

                <h3><?php esc_html_e('Change table', 'maca-restu-pro'); ?></h3>
                <p class="description">
                    <?php esc_html_e('Move this booking to another free table at the same date and time (for example to free up a larger table).', 'maca-restu-pro'); ?>
                </p>

                <table class="form-table">
                    <tr>
                        <th><label for="move_table_id"><?php esc_html_e('Move to', 'maca-restu-pro'); ?></label></th>
                        <td>
                            <select name="table_id" id="move_table_id" required>
                                <option value=""><?php esc_html_e('Select table', 'maca-restu-pro'); ?></option>
                                <?php foreach ($move_targets as $table) : ?>
                                    <?php
                                    $move_value = (string) (int) $table['id'];
                                    if (!empty($table['split_slot'])) {
                                        $move_value .= ':' . maca_menulist_normalize_split_slot((string) $table['split_slot']);
                                    }
                                    ?>
                                    <option value="<?php echo esc_attr($move_value); ?>">
                                        <?php
                                        echo esc_html(
                                            sprintf(
                                                /* translators: 1: table number, 2: seats */
                                                __('Table %1$s (%2$d seats)', 'maca-restu-pro'),
                                                $table['table_number'],
                                                (int) $table['seats']
                                            )
                                        );
                                        ?>
                                    </option>
                                <?php endforeach; ?>
                            </select>
                        </td>
                    </tr>
                </table>

                <?php submit_button(__('Move booking', 'maca-restu-pro'), 'secondary'); ?>
            </form>
        <?php elseif (in_array($booking->status, array('pending', 'confirmed'), true) && !empty($booking->table_id)) : ?>
            <p class="description" style="margin-top:1em;">
                <?php esc_html_e('No other free tables at this booking time.', 'maca-restu-pro'); ?>
            </p>
        <?php endif; ?>

        <?php if (in_array($booking->status, array('pending', 'confirmed', 'waitlist'), true)) : ?>
            <form method="post" style="display:inline-block;margin-right:8px;" action="<?php echo esc_url($detail_url); ?>">
                <?php wp_nonce_field('maca_bookings', 'maca_bookings_nonce'); ?>
                <input type="hidden" name="maca_bookings_action" value="cancel_booking">
                <input type="hidden" name="booking_id" value="<?php echo esc_attr((string) $booking->id); ?>">
                <?php submit_button(__('Cancel booking', 'maca-restu-pro'), 'secondary', 'submit', false); ?>
            </form>
        <?php endif; ?>

        <form method="post" style="display:inline-block;" action="<?php echo esc_url($detail_url); ?>" onsubmit="return confirm('<?php echo esc_js(__('Delete this booking permanently?', 'maca-restu-pro')); ?>');">
            <?php wp_nonce_field('maca_bookings', 'maca_bookings_nonce'); ?>
            <input type="hidden" name="maca_bookings_action" value="delete_booking">
            <input type="hidden" name="booking_id" value="<?php echo esc_attr((string) $booking->id); ?>">
            <?php submit_button(__('Delete', 'maca-restu-pro'), 'delete', 'submit', false); ?>
        </form>
        <?php
    }

    /**
     * Render booking audit log tab.
     */
    private function render_log_tab() {
        if (!function_exists('maca_menulist_booking_log_list')) {
            echo '<p>' . esc_html__('Händelseloggen är inte tillgänglig.', 'maca-restu-pro') . '</p>';
            return;
        }

        $filter_booking_id = isset($_GET['log_booking_id']) ? absint(wp_unslash($_GET['log_booking_id'])) : 0;
        $log_paged = isset($_GET['log_paged']) ? max(1, absint(wp_unslash($_GET['log_paged']))) : 1;
        $log_per_page = isset($_GET['log_per_page'])
            ? maca_menulist_booking_log_normalize_per_page(absint(wp_unslash($_GET['log_per_page'])))
            : 100;

        $list_args = array(
            'booking_id' => $filter_booking_id,
            'per_page' => $log_per_page,
            'paged' => $log_paged,
        );
        $total = maca_menulist_booking_log_count(array('booking_id' => $filter_booking_id));
        $total_pages = $total > 0 ? (int) ceil($total / $log_per_page) : 1;
        if ($log_paged > $total_pages) {
            $log_paged = $total_pages;
            $list_args['paged'] = $log_paged;
        }

        $entries = maca_menulist_booking_log_list($list_args);

        $url_args = array(
            'log_per_page' => $log_per_page,
        );
        if ($filter_booking_id > 0) {
            $url_args['log_booking_id'] = $filter_booking_id;
        }
        $base_url = maca_menulist_booking_log_admin_url($url_args);
        $from_row = $total > 0 ? (($log_paged - 1) * $log_per_page) + 1 : 0;
        $to_row = min($log_paged * $log_per_page, $total);
        ?>
        <p class="description">
            <?php esc_html_e('Alla ändringar på bokningar (skapad, uppdaterad, bekräftad, flyttad, avbokad, raderad) med tid och vem som gjorde det. Bläddra mellan sidor för äldre händelser.', 'maca-restu-pro'); ?>
        </p>

        <form method="get" class="maca-booking-log-filter" style="margin:16px 0;">
            <input type="hidden" name="page" value="maca-restu-bookings">
            <input type="hidden" name="tab" value="log">
            <label for="maca-log-booking-id"><strong><?php esc_html_e('Boknings-ID', 'maca-restu-pro'); ?></strong></label>
            <input type="number" id="maca-log-booking-id" name="log_booking_id" min="0" step="1" value="<?php echo $filter_booking_id > 0 ? esc_attr((string) $filter_booking_id) : ''; ?>" class="small-text" style="margin:0 8px;">
            <label for="maca-log-per-page" style="margin-left:12px;"><strong><?php esc_html_e('Per sida', 'maca-restu-pro'); ?></strong></label>
            <select id="maca-log-per-page" name="log_per_page" style="margin:0 8px;">
                <?php foreach (maca_menulist_booking_log_per_page_options() as $option) : ?>
                    <option value="<?php echo esc_attr((string) $option); ?>" <?php selected($log_per_page, $option); ?>>
                        <?php echo esc_html((string) $option); ?>
                    </option>
                <?php endforeach; ?>
            </select>
            <?php submit_button(__('Filtrera', 'maca-restu-pro'), 'secondary', 'submit', false); ?>
            <?php if ($filter_booking_id > 0) : ?>
                <a href="<?php echo esc_url(maca_menulist_booking_log_admin_url(array('log_per_page' => $log_per_page))); ?>" class="button"><?php esc_html_e('Visa alla', 'maca-restu-pro'); ?></a>
            <?php endif; ?>
        </form>

        <?php if ($total > 0) : ?>
            <p class="maca-booking-log-summary description">
                <?php
                echo esc_html(
                    sprintf(
                        /* translators: 1: first row number, 2: last row number, 3: total count, 4: current page, 5: total pages */
                        __('Visar %1$d–%2$d av %3$d händelser (sida %4$d av %5$d).', 'maca-restu-pro'),
                        (int) $from_row,
                        (int) $to_row,
                        (int) $total,
                        (int) $log_paged,
                        (int) $total_pages
                    )
                );
                ?>
            </p>
        <?php endif; ?>

        <table class="wp-list-table widefat fixed striped">
            <thead>
                <tr>
                    <th style="width:150px;"><?php esc_html_e('Tid', 'maca-restu-pro'); ?></th>
                    <th style="width:90px;"><?php esc_html_e('Bokning', 'maca-restu-pro'); ?></th>
                    <th style="width:110px;"><?php esc_html_e('Händelse', 'maca-restu-pro'); ?></th>
                    <th style="width:140px;"><?php esc_html_e('Utförd av', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Detaljer', 'maca-restu-pro'); ?></th>
                </tr>
            </thead>
            <tbody>
                <?php if (empty($entries)) : ?>
                    <tr>
                        <td colspan="5"><?php esc_html_e('Inga händelser hittades.', 'maca-restu-pro'); ?></td>
                    </tr>
                <?php else : ?>
                    <?php foreach ($entries as $entry) : ?>
                        <?php
                        $booking_label = '';
                        if ($filter_booking_id <= 0 && isset($entry->guest_name)) {
                            $booking_label = (string) $entry->guest_name;
                            if (!empty($entry->booking_date) && !empty($entry->booking_time)) {
                                $booking_label .= ' · ' . substr((string) $entry->booking_time, 0, 5);
                            }
                        }
                        $detail_url = add_query_arg(
                            array(
                                'page' => 'maca-restu-bookings',
                                'tab' => 'bookings',
                                'booking_id' => (int) $entry->booking_id,
                            ),
                            admin_url('admin.php')
                        );
                        $changes_html = maca_menulist_booking_log_format_changes_html($entry);
                        ?>
                        <tr>
                            <td><?php echo esc_html(maca_menulist_format_wp_datetime((string) $entry->created_at, get_option('date_format') . ' H:i')); ?></td>
                            <td>
                                <a href="<?php echo esc_url($detail_url); ?>">#<?php echo esc_html((string) $entry->booking_id); ?></a>
                                <?php if ($booking_label !== '') : ?>
                                    <br><span class="description"><?php echo esc_html($booking_label); ?></span>
                                <?php endif; ?>
                            </td>
                            <td><?php echo esc_html(maca_menulist_booking_log_action_label((string) $entry->action)); ?></td>
                            <td><?php echo esc_html((string) ($entry->actor_label !== '' && $entry->actor_label !== null ? $entry->actor_label : '—')); ?></td>
                            <td><?php echo wp_kses_post($changes_html); ?></td>
                        </tr>
                    <?php endforeach; ?>
                <?php endif; ?>
            </tbody>
        </table>

        <?php if ($total_pages > 1) : ?>
            <div class="tablenav bottom">
                <div class="tablenav-pages">
                    <span class="displaying-num">
                        <?php
                        echo esc_html(
                            sprintf(
                                /* translators: %d: number of log entries */
                                _n('%d händelse', '%d händelser', $total, 'maca-restu-pro'),
                                (int) $total
                            )
                        );
                        ?>
                    </span>
                    <span class="pagination-links">
                        <?php if ($log_paged > 1) : ?>
                            <a class="button" href="<?php echo esc_url(maca_menulist_booking_log_admin_url(array_merge($url_args, array('log_paged' => 1)))); ?>">&laquo; <?php esc_html_e('Första', 'maca-restu-pro'); ?></a>
                            <a class="button" href="<?php echo esc_url(maca_menulist_booking_log_admin_url(array_merge($url_args, array('log_paged' => $log_paged - 1)))); ?>"><?php esc_html_e('Nyare', 'maca-restu-pro'); ?></a>
                        <?php endif; ?>
                        <?php if ($log_paged < $total_pages) : ?>
                            <a class="button" href="<?php echo esc_url(maca_menulist_booking_log_admin_url(array_merge($url_args, array('log_paged' => $log_paged + 1)))); ?>"><?php esc_html_e('Äldre', 'maca-restu-pro'); ?></a>
                            <a class="button" href="<?php echo esc_url(maca_menulist_booking_log_admin_url(array_merge($url_args, array('log_paged' => $total_pages)))); ?>"><?php esc_html_e('Sista', 'maca-restu-pro'); ?> &raquo;</a>
                        <?php endif; ?>
                    </span>
                </div>
            </div>
        <?php endif; ?>
        <?php
    }

    /**
     * Render tables management tab.
     */
    private function render_tables_tab() {
        $edit_id = isset($_GET['edit_table']) ? absint(wp_unslash($_GET['edit_table'])) : 0;
        $edit_table = $edit_id > 0 ? maca_menulist_db_get_booking_table($edit_id) : null;
        $tables = maca_menulist_db_get_booking_tables(false);
        $base_url = admin_url('admin.php?page=maca-restu-bookings&tab=tables');
        ?>
        <h2><?php echo $edit_table ? esc_html__('Edit table', 'maca-restu-pro') : esc_html__('Add table', 'maca-restu-pro'); ?></h2>

        <form method="post">
            <?php wp_nonce_field('maca_bookings', 'maca_bookings_nonce'); ?>
            <input type="hidden" name="maca_bookings_action" value="save_table">
            <input type="hidden" name="table_id" value="<?php echo esc_attr($edit_table ? (string) $edit_table->id : '0'); ?>">

            <table class="form-table">
                <tr>
                    <th><label for="table_number"><?php esc_html_e('Table number', 'maca-restu-pro'); ?></label></th>
                    <td><input type="text" id="table_number" name="table_number" class="regular-text" required value="<?php echo esc_attr($edit_table ? $edit_table->table_number : ''); ?>"></td>
                </tr>
                <tr>
                    <th><label for="seats"><?php esc_html_e('Seats', 'maca-restu-pro'); ?></label></th>
                    <td><input type="number" id="seats" name="seats" min="1" max="50" value="<?php echo esc_attr($edit_table ? (string) $edit_table->seats : '2'); ?>"></td>
                </tr>
                <tr>
                    <th><?php esc_html_e('Delningsbart bord', 'maca-restu-pro'); ?></th>
                    <td>
                        <label>
                            <input type="checkbox" name="is_splittable" id="maca_table_is_splittable" value="1" <?php checked($edit_table && !empty($edit_table->is_splittable)); ?>>
                            <?php esc_html_e('Visa i salongsöversikt som delningsbart (flera bokningar vid samma tid)', 'maca-restu-pro'); ?>
                        </label>
                        <p class="description"><?php esc_html_e('T.ex. ett 8-bord som personalen delar i fyra 2-platser. Delning görs per dag i salongsöversikten; samma dag kan gäster välja del (t.ex. 8a, 8b) vid bordsbeställning/QR. Gäller inte gästbokning online.', 'maca-restu-pro'); ?></p>
                    </td>
                </tr>
                <?php
                $split_custom_sizes = '';
                $split_layout_mode = 'uniform';
                if ($edit_table && !empty($edit_table->is_splittable) && function_exists('maca_menulist_decode_split_slot_sizes')) {
                    $decoded_sizes = maca_menulist_decode_split_slot_sizes($edit_table);
                    if (!empty($decoded_sizes)) {
                        $split_layout_mode = 'custom';
                        $split_custom_sizes = implode(',', $decoded_sizes);
                    }
                }
                ?>
                <tr class="maca-table-split-row" id="maca-table-split-row">
                    <th scope="row"><?php esc_html_e('Delning av bord', 'maca-restu-pro'); ?></th>
                    <td>
                        <fieldset>
                            <p>
                                <label>
                                    <input type="radio" name="split_layout_mode" value="uniform" <?php checked($split_layout_mode, 'uniform'); ?>>
                                    <?php esc_html_e('Jämn delning (samma antal platser i varje del)', 'maca-restu-pro'); ?>
                                </label>
                            </p>
                            <p class="maca-table-split-uniform" style="margin-left:22px;">
                                <label for="split_party_size"><?php esc_html_e('Platser per del', 'maca-restu-pro'); ?></label>
                                <input type="number" id="split_party_size" name="split_party_size" min="1" max="20" value="<?php echo esc_attr($edit_table ? (string) (int) ($edit_table->split_party_size ?? 2) : '2'); ?>" class="small-text">
                                <span class="description"><?php esc_html_e('T.ex. 6 platser och 2 per del → 3×2 (8a, 8b, 8c).', 'maca-restu-pro'); ?></span>
                            </p>
                            <p style="margin-top:12px;">
                                <label>
                                    <input type="radio" name="split_layout_mode" value="custom" <?php checked($split_layout_mode, 'custom'); ?>>
                                    <?php esc_html_e('Egen fördelning (olika delstorlekar)', 'maca-restu-pro'); ?>
                                </label>
                            </p>
                            <p class="maca-table-split-custom" style="margin-left:22px;">
                                <label for="split_slot_sizes"><?php esc_html_e('Platser per del', 'maca-restu-pro'); ?></label>
                                <input type="text" id="split_slot_sizes" name="split_slot_sizes" class="regular-text" value="<?php echo esc_attr($split_custom_sizes); ?>" placeholder="<?php esc_attr_e('4,2', 'maca-restu-pro'); ?>">
                                <span class="description"><?php esc_html_e('Kommaseparerat; summan måste bli antal platser på bordet. T.ex. 6 platser → 4,2 ger 8a (4) och 8b (2).', 'maca-restu-pro'); ?></span>
                            </p>
                        </fieldset>
                        <p class="description" id="maca-table-split-preview" style="margin-top:10px;">
                            <?php
                            if ($edit_table && !empty($edit_table->is_splittable) && function_exists('maca_menulist_table_split_layout_label')) {
                                echo esc_html(
                                    sprintf(
                                        /* translators: %s: layout e.g. 4+2 or 3×2 */
                                        __('Layout i salongsöversikt: %s', 'maca-restu-pro'),
                                        maca_menulist_table_split_layout_label($edit_table)
                                    )
                                );
                            }
                            ?>
                        </p>
                    </td>
                </tr>
                <tr>
                    <th><label for="sort_order"><?php esc_html_e('Sort order', 'maca-restu-pro'); ?></label></th>
                    <td><input type="number" id="sort_order" name="sort_order" value="<?php echo esc_attr($edit_table ? (string) $edit_table->sort_order : '0'); ?>"></td>
                </tr>
                <tr>
                    <th><?php esc_html_e('Active', 'maca-restu-pro'); ?></th>
                    <td>
                        <label>
                            <input type="checkbox" name="is_active" value="1" <?php checked(!$edit_table || !empty($edit_table->is_active)); ?>>
                            <?php esc_html_e('Available for booking', 'maca-restu-pro'); ?>
                        </label>
                    </td>
                </tr>
            </table>

            <?php submit_button($edit_table ? __('Update table', 'maca-restu-pro') : __('Add table', 'maca-restu-pro')); ?>
            <?php if ($edit_table) : ?>
                <a href="<?php echo esc_url($base_url); ?>" class="button"><?php esc_html_e('Cancel', 'maca-restu-pro'); ?></a>
            <?php endif; ?>
        </form>
        <script>
        (function () {
            var cb = document.getElementById('maca_table_is_splittable');
            var row = document.getElementById('maca-table-split-row');
            var seats = document.getElementById('seats');
            var split = document.getElementById('split_party_size');
            var customInput = document.getElementById('split_slot_sizes');
            var modeRadios = document.querySelectorAll('input[name="split_layout_mode"]');
            var previewPrefix = '<?php echo esc_js(__('Layout i salongsöversikt:', 'maca-restu-pro')); ?> ';
            if (!cb || !row) {
                return;
            }
            function isCustomMode() {
                var radio = document.querySelector('input[name="split_layout_mode"]:checked');
                return radio && radio.value === 'custom';
            }
            function toggleModeFields() {
                var custom = isCustomMode();
                var uniformWrap = document.querySelector('.maca-table-split-uniform');
                var customWrap = document.querySelector('.maca-table-split-custom');
                if (uniformWrap) {
                    uniformWrap.style.opacity = custom ? '0.45' : '1';
                }
                if (customWrap) {
                    customWrap.style.opacity = custom ? '1' : '0.45';
                }
            }
            function parseCustomParts(raw) {
                return String(raw || '')
                    .split(/[\s,++]+/)
                    .map(function (part) {
                        return parseInt(part, 10);
                    })
                    .filter(function (n) {
                        return !isNaN(n) && n > 0;
                    });
            }
            function toggle() {
                row.style.display = cb.checked ? '' : 'none';
            }
            function preview() {
                var previewEl = document.getElementById('maca-table-split-preview');
                if (!previewEl || !cb.checked || !seats) {
                    return;
                }
                var total = parseInt(seats.value, 10) || 0;
                if (total < 1) {
                    return;
                }
                if (isCustomMode() && customInput) {
                    var parts = parseCustomParts(customInput.value);
                    var sum = parts.reduce(function (acc, n) {
                        return acc + n;
                    }, 0);
                    if (parts.length < 1) {
                        previewEl.textContent = '';
                        return;
                    }
                    previewEl.textContent =
                        previewPrefix +
                        parts.join('+') +
                        (sum !== total ? ' (<?php echo esc_js(__('summan måste bli', 'maca-restu-pro')); ?> ' + total + ')' : '');
                    return;
                }
                var per = split ? parseInt(split.value, 10) || 0 : 0;
                if (per < 1) {
                    return;
                }
                var slots = Math.floor(total / per);
                previewEl.textContent =
                    slots > 0 ? previewPrefix + slots + '×' + per : '';
            }
            cb.addEventListener('change', toggle);
            if (seats) {
                seats.addEventListener('input', preview);
            }
            if (split) {
                split.addEventListener('input', preview);
            }
            if (customInput) {
                customInput.addEventListener('input', preview);
            }
            modeRadios.forEach(function (radio) {
                radio.addEventListener('change', function () {
                    toggleModeFields();
                    preview();
                });
            });
            toggle();
            toggleModeFields();
            preview();
        })();
        </script>

        <h2><?php esc_html_e('All tables', 'maca-restu-pro'); ?></h2>
        <table class="wp-list-table widefat fixed striped">
            <thead>
                <tr>
                    <th><?php esc_html_e('Table', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Seats', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Delning', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Sort', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Status', 'maca-restu-pro'); ?></th>
                    <th><?php esc_html_e('Actions', 'maca-restu-pro'); ?></th>
                </tr>
            </thead>
            <tbody>
                <?php if (empty($tables)) : ?>
                    <tr><td colspan="6"><?php esc_html_e('No tables yet. Add your first table above.', 'maca-restu-pro'); ?></td></tr>
                <?php else : ?>
                    <?php foreach ($tables as $table) : ?>
                        <tr>
                            <td><strong><?php echo esc_html($table->table_number); ?></strong></td>
                            <td><?php echo esc_html((string) $table->seats); ?></td>
                            <td>
                                <?php
                                if (!empty($table->is_splittable) && function_exists('maca_menulist_table_split_layout_label')) {
                                    echo esc_html(maca_menulist_table_split_layout_label($table));
                                } else {
                                    echo '—';
                                }
                                ?>
                            </td>
                            <td><?php echo esc_html((string) $table->sort_order); ?></td>
                            <td>
                                <?php echo !empty($table->is_active)
                                    ? esc_html__('Active', 'maca-restu-pro')
                                    : esc_html__('Inactive', 'maca-restu-pro'); ?>
                            </td>
                            <td>
                                <a href="<?php echo esc_url($base_url . '&edit_table=' . (int) $table->id); ?>" class="button button-small"><?php esc_html_e('Edit', 'maca-restu-pro'); ?></a>
                                <form method="post" style="display:inline;" onsubmit="return confirm('<?php echo esc_js(__('Delete this table?', 'maca-restu-pro')); ?>');">
                                    <?php wp_nonce_field('maca_bookings', 'maca_bookings_nonce'); ?>
                                    <input type="hidden" name="maca_bookings_action" value="delete_table">
                                    <input type="hidden" name="table_id" value="<?php echo esc_attr((string) $table->id); ?>">
                                    <button type="submit" class="button button-small button-link-delete"><?php esc_html_e('Delete', 'maca-restu-pro'); ?></button>
                                </form>
                            </td>
                        </tr>
                    <?php endforeach; ?>
                <?php endif; ?>
            </tbody>
        </table>
        <?php
    }

}

/**
 * Render the table reservations admin page (shared by main menu and booking host menu).
 *
 * @return void
 */
function maca_menulist_admin_render_table_bookings_page() {
    do_action('maca_menulist_render_table_bookings_admin');
}
