<?php
/**
 * Plugin Name: Nazar Kebap MVP
 * Description: Restaurant landing page styling and simple table reservation workflow for Nazar Kebap - Gasthaus.
 * Version: 1.2.0
 * Author: OpenAI Codex
 */

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

class Nazar_Kebap_MVP {
    const POST_TYPE = 'nazar_reservation';
    const STATUS_META = '_reservation_status';
    const AVAILABILITY_NONCE = 'nazar_reservation_availability';
    const OPENING_TIME = '09:00';
    const LAST_BOOKING_TIME = '23:30';
    const TIME_STEP_MINUTES = 5;

    public function __construct() {
        add_action('init', [$this, 'register_post_type']);
        add_action('init', [$this, 'register_shortcodes']);
        add_action('wp_enqueue_scripts', [$this, 'enqueue_assets']);
        add_action('admin_post_nazar_reserve_table', [$this, 'handle_reservation']);
        add_action('admin_post_nopriv_nazar_reserve_table', [$this, 'handle_reservation']);
        add_action('wp_ajax_nazar_get_available_times', [$this, 'ajax_get_available_times']);
        add_action('wp_ajax_nopriv_nazar_get_available_times', [$this, 'ajax_get_available_times']);
        add_filter('body_class', [$this, 'body_classes']);

        add_filter('manage_' . self::POST_TYPE . '_posts_columns', [$this, 'admin_columns']);
        add_action('manage_' . self::POST_TYPE . '_posts_custom_column', [$this, 'render_admin_columns'], 10, 2);
        add_action('add_meta_boxes', [$this, 'add_meta_boxes']);
        add_action('save_post_' . self::POST_TYPE, [$this, 'save_reservation_meta']);
    }

    public function register_post_type() {
        register_post_type(self::POST_TYPE, [
            'labels' => [
                'name' => 'Reservierungen',
                'singular_name' => 'Reservierung',
                'menu_name' => 'Reservierungen',
                'add_new_item' => 'Neue Reservierung',
                'edit_item' => 'Reservierung bearbeiten',
                'view_item' => 'Reservierung ansehen',
                'search_items' => 'Reservierungen suchen',
            ],
            'public' => false,
            'show_ui' => true,
            'show_in_menu' => true,
            'menu_icon' => 'dashicons-calendar-alt',
            'supports' => ['title'],
            'map_meta_cap' => true,
        ]);
    }

    public function register_shortcodes() {
        add_shortcode('nazar_reservation_form', [$this, 'reservation_form_shortcode']);
    }

    public function enqueue_assets() {
        $plugin_url = plugin_dir_url(__FILE__);
        $plugin_path = plugin_dir_path(__FILE__);

        wp_enqueue_style(
            'nazar-kebap-mvp',
            $plugin_url . 'assets/site.css',
            [],
            filemtime($plugin_path . 'assets/site.css')
        );

        wp_enqueue_script(
            'nazar-kebap-reservations',
            $plugin_url . 'assets/reservation.js',
            [],
            filemtime($plugin_path . 'assets/reservation.js'),
            true
        );

        wp_localize_script('nazar-kebap-reservations', 'nazarReservationData', [
            'ajaxUrl' => admin_url('admin-ajax.php'),
            'nonce' => wp_create_nonce(self::AVAILABILITY_NONCE),
            'messages' => [
                'chooseDateAndParty' => 'Bitte wählen Sie zuerst Datum und Personenzahl.',
                'loading' => 'Verfügbare Uhrzeiten werden geladen …',
                'empty' => 'Für diese Auswahl ist aktuell keine freie Uhrzeit verfügbar.',
                'error' => 'Die verfügbaren Uhrzeiten konnten gerade nicht geladen werden. Bitte versuchen Sie es erneut.',
            ],
        ]);
    }

    public function body_classes($classes) {
        $classes[] = 'nazar-site';
        return $classes;
    }

    public function reservation_form_shortcode() {
        $status = isset($_GET['reservation']) ? sanitize_key(wp_unslash($_GET['reservation'])) : '';
        $messages = [
            'success' => 'Danke! Ihre Reservierungsanfrage wurde erfolgreich übermittelt. Sie erhalten in Kürze eine Bestätigung per E-Mail mit allen Buchungsdetails.',
            'error' => 'Bitte prüfen Sie Ihre Eingaben. Alle Pflichtfelder müssen ausgefüllt sein.',
            'conflict' => 'Diese Uhrzeit ist leider nicht mehr verfügbar. Bitte wählen Sie eine andere freie Uhrzeit.',
        ];

        ob_start();
        ?>
        <div class="nazar-form-wrap">
            <?php if ($status && isset($messages[$status])) : ?>
                <div class="nazar-alert nazar-alert-<?php echo esc_attr($status === 'conflict' ? 'error' : $status); ?>">
                    <?php echo esc_html($messages[$status]); ?>
                </div>
            <?php endif; ?>
            <form class="nazar-reservation-form" method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" data-availability-form>
                <input type="hidden" name="action" value="nazar_reserve_table">
                <?php wp_nonce_field('nazar_reserve_table', 'nazar_reserve_nonce'); ?>
                <div class="nazar-form-grid">
                    <label>
                        <span>Name *</span>
                        <input type="text" name="guest_name" required>
                    </label>
                    <label>
                        <span>Telefon *</span>
                        <input type="tel" name="guest_phone" required>
                    </label>
                    <label>
                        <span>E-Mail *</span>
                        <input type="email" name="guest_email" required>
                    </label>
                    <label>
                        <span>Personen *</span>
                        <select name="party_size" required data-party-size>
                            <option value="">Bitte wählen</option>
                            <option value="1">1</option>
                            <option value="2">2</option>
                            <option value="3">3</option>
                            <option value="4">4</option>
                            <option value="5">5</option>
                            <option value="6">6</option>
                            <option value="7">7</option>
                            <option value="8+">8+</option>
                        </select>
                    </label>
                    <label>
                        <span>Datum *</span>
                        <input type="date" name="reservation_date" min="<?php echo esc_attr(wp_date('Y-m-d')); ?>" required data-reservation-date>
                    </label>
                    <label>
                        <span>Uhrzeit *</span>
                        <select name="reservation_time" required data-reservation-time disabled>
                            <option value="">Bitte erst Datum und Personen wählen</option>
                        </select>
                    </label>
                </div>
                <p class="nazar-availability-note" data-availability-note>Bitte wählen Sie zuerst Datum und Personenzahl.</p>
                <label>
                    <span>Hinweise</span>
                    <textarea name="reservation_notes" rows="4" placeholder="z. B. Kinderstuhl, ruhiger Tisch, Allergien"></textarea>
                </label>
                <p class="nazar-form-note">Reservierungen werden direkt gegen bestehende Buchungen geprüft. Gesperrte Zeiten richten sich nach der Personenzahl: 1 Person = 10 Min., 2 Personen = 15 Min., 3–4 Personen = 30 Min., ab 5 Personen = 60 Min.</p>
                <button type="submit" class="wp-element-button">Tisch anfragen</button>
            </form>
        </div>
        <?php
        return ob_get_clean();
    }

    public function handle_reservation() {
        $redirect_url = wp_get_referer() ?: home_url('/reservierung/');

        if (!isset($_POST['nazar_reserve_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nazar_reserve_nonce'])), 'nazar_reserve_table')) {
            wp_safe_redirect(add_query_arg('reservation', 'error', $redirect_url));
            exit;
        }

        $fields = [
            'guest_name' => sanitize_text_field(wp_unslash($_POST['guest_name'] ?? '')),
            'guest_phone' => sanitize_text_field(wp_unslash($_POST['guest_phone'] ?? '')),
            'guest_email' => sanitize_email(wp_unslash($_POST['guest_email'] ?? '')),
            'party_size' => sanitize_text_field(wp_unslash($_POST['party_size'] ?? '')),
            'reservation_date' => sanitize_text_field(wp_unslash($_POST['reservation_date'] ?? '')),
            'reservation_time' => sanitize_text_field(wp_unslash($_POST['reservation_time'] ?? '')),
            'reservation_notes' => sanitize_textarea_field(wp_unslash($_POST['reservation_notes'] ?? '')),
        ];

        if (!$fields['guest_name'] || !$fields['guest_phone'] || !$fields['guest_email'] || !$fields['party_size'] || !$fields['reservation_date'] || !$fields['reservation_time']) {
            wp_safe_redirect(add_query_arg('reservation', 'error', $redirect_url));
            exit;
        }

        $fields['reservation_time'] = $this->normalize_time($fields['reservation_time']);

        if (!$fields['reservation_time'] || !$this->is_time_available($fields['reservation_date'], $fields['reservation_time'], $fields['party_size'])) {
            wp_safe_redirect(add_query_arg('reservation', 'conflict', $redirect_url));
            exit;
        }

        $title = sprintf(
            'Reservierung – %s – %s %s',
            $fields['guest_name'],
            $fields['reservation_date'],
            $fields['reservation_time']
        );

        $post_id = wp_insert_post([
            'post_type' => self::POST_TYPE,
            'post_status' => 'publish',
            'post_title' => $title,
            'meta_input' => [
                '_guest_name' => $fields['guest_name'],
                '_guest_phone' => $fields['guest_phone'],
                '_guest_email' => $fields['guest_email'],
                '_party_size' => $fields['party_size'],
                '_reservation_date' => $fields['reservation_date'],
                '_reservation_time' => $fields['reservation_time'],
                '_reservation_notes' => $fields['reservation_notes'],
                '_reservation_duration' => $this->get_duration_minutes($fields['party_size']),
                self::STATUS_META => 'neu',
            ],
        ]);

        if (is_wp_error($post_id) || !$post_id) {
            wp_safe_redirect(add_query_arg('reservation', 'error', $redirect_url));
            exit;
        }

        $notification_results = $this->send_new_reservation_notifications($post_id, $fields);
        update_post_meta($post_id, '_admin_notification_sent', $notification_results['admin'] ? 'yes' : 'no');
        update_post_meta($post_id, '_customer_notification_sent', $notification_results['customer'] ? 'yes' : 'no');
        update_post_meta($post_id, '_notification_sent_at', current_time('mysql'));

        wp_safe_redirect(add_query_arg('reservation', 'success', home_url('/reservierung/')));
        exit;
    }

    public function ajax_get_available_times() {
        check_ajax_referer(self::AVAILABILITY_NONCE, 'nonce');

        $date = sanitize_text_field(wp_unslash($_POST['reservation_date'] ?? ''));
        $party_size = sanitize_text_field(wp_unslash($_POST['party_size'] ?? ''));

        if (!$date || !$party_size) {
            wp_send_json_error([
                'message' => 'Datum und Personenzahl sind erforderlich.',
            ], 400);
        }

        $times = $this->get_available_time_slots($date, $party_size);
        $duration = $this->get_duration_minutes($party_size);

        wp_send_json_success([
            'times' => $times,
            'duration' => $duration,
            'message' => sprintf(
                'Für %s blockiert eine Reservierung %d Minuten. Es werden nur freie Uhrzeiten angezeigt.',
                $party_size,
                $duration
            ),
        ]);
    }

    public function admin_columns($columns) {
        return [
            'cb' => $columns['cb'],
            'title' => 'Anfrage',
            'reservation_datetime' => 'Datum & Uhrzeit',
            'party_size' => 'Personen',
            'contact' => 'Kontakt',
            'reservation_status' => 'Status',
            'date' => 'Eingegangen',
        ];
    }

    public function render_admin_columns($column, $post_id) {
        switch ($column) {
            case 'reservation_datetime':
                echo esc_html(get_post_meta($post_id, '_reservation_date', true));
                echo '<br>';
                echo esc_html(get_post_meta($post_id, '_reservation_time', true));
                break;
            case 'party_size':
                echo esc_html(get_post_meta($post_id, '_party_size', true));
                break;
            case 'contact':
                echo esc_html(get_post_meta($post_id, '_guest_name', true));
                echo '<br>';
                echo esc_html(get_post_meta($post_id, '_guest_phone', true));
                $email = get_post_meta($post_id, '_guest_email', true);
                if ($email) {
                    echo '<br>' . esc_html($email);
                }
                break;
            case 'reservation_status':
                echo esc_html(ucfirst(get_post_meta($post_id, self::STATUS_META, true) ?: 'neu'));
                break;
        }
    }

    public function add_meta_boxes() {
        add_meta_box(
            'nazar_reservation_details',
            'Reservierungsdetails',
            [$this, 'render_meta_box'],
            self::POST_TYPE,
            'normal',
            'high'
        );
    }

    public function render_meta_box($post) {
        wp_nonce_field('nazar_save_reservation', 'nazar_save_reservation_nonce');
        $status = get_post_meta($post->ID, self::STATUS_META, true) ?: 'neu';
        ?>
        <table class="form-table">
            <tr><th>Name</th><td><?php echo esc_html(get_post_meta($post->ID, '_guest_name', true)); ?></td></tr>
            <tr><th>Telefon</th><td><?php echo esc_html(get_post_meta($post->ID, '_guest_phone', true)); ?></td></tr>
            <tr><th>E-Mail</th><td><?php echo esc_html(get_post_meta($post->ID, '_guest_email', true)); ?></td></tr>
            <tr><th>Datum</th><td><?php echo esc_html(get_post_meta($post->ID, '_reservation_date', true)); ?></td></tr>
            <tr><th>Uhrzeit</th><td><?php echo esc_html(get_post_meta($post->ID, '_reservation_time', true)); ?></td></tr>
            <tr><th>Personen</th><td><?php echo esc_html(get_post_meta($post->ID, '_party_size', true)); ?></td></tr>
            <tr><th>Blockiert bis</th><td><?php echo esc_html($this->get_blocked_until_label($post->ID)); ?></td></tr>
            <tr><th>Admin-E-Mail</th><td><?php echo esc_html($this->humanize_notification_status(get_post_meta($post->ID, '_admin_notification_sent', true))); ?></td></tr>
            <tr><th>Kunden-E-Mail</th><td><?php echo esc_html($this->humanize_notification_status(get_post_meta($post->ID, '_customer_notification_sent', true))); ?></td></tr>
            <tr><th>Status-E-Mail</th><td><?php echo esc_html($this->humanize_notification_status(get_post_meta($post->ID, '_status_notification_sent', true))); ?></td></tr>
            <tr><th>Hinweise</th><td><?php echo nl2br(esc_html(get_post_meta($post->ID, '_reservation_notes', true))); ?></td></tr>
            <tr>
                <th><label for="nazar_reservation_status">Status</label></th>
                <td>
                    <select name="nazar_reservation_status" id="nazar_reservation_status">
                        <?php foreach (['neu', 'bestätigt', 'abgelehnt', 'erledigt'] as $option) : ?>
                            <option value="<?php echo esc_attr($option); ?>" <?php selected($status, $option); ?>><?php echo esc_html(ucfirst($option)); ?></option>
                        <?php endforeach; ?>
                    </select>
                </td>
            </tr>
        </table>
        <?php
    }

    public function save_reservation_meta($post_id) {
        if (!isset($_POST['nazar_save_reservation_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nazar_save_reservation_nonce'])), 'nazar_save_reservation')) {
            return;
        }

        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
            return;
        }

        if (!current_user_can('edit_post', $post_id)) {
            return;
        }

        $status = sanitize_text_field(wp_unslash($_POST['nazar_reservation_status'] ?? 'neu'));
        $previous_status = get_post_meta($post_id, self::STATUS_META, true) ?: 'neu';

        update_post_meta($post_id, self::STATUS_META, $status);

        if ($status !== $previous_status) {
            $status_sent = $this->send_status_update_notification($post_id, $status, $previous_status);
            update_post_meta($post_id, '_status_notification_sent', $status_sent ? 'yes' : 'no');
            update_post_meta($post_id, '_status_notification_sent_at', current_time('mysql'));
        }
    }

    public function get_available_time_slots($date, $party_size) {
        if (!$this->is_valid_reservation_date($date) || !$this->parse_party_size($party_size)) {
            return [];
        }

        $slots = [];
        $start = $this->date_time_to_timestamp($date, self::OPENING_TIME);
        $end = $this->date_time_to_timestamp($date, self::LAST_BOOKING_TIME);

        if (!$start || !$end || $start > $end) {
            return [];
        }

        for ($cursor = $start; $cursor <= $end; $cursor += self::TIME_STEP_MINUTES * MINUTE_IN_SECONDS) {
            $time = wp_date('H:i', $cursor);
            if ($this->is_time_available($date, $time, $party_size)) {
                $slots[] = [
                    'value' => $time,
                    'label' => $time,
                ];
            }
        }

        return $slots;
    }

    public function is_time_available($date, $time, $party_size, $exclude_post_id = 0) {
        if (!$this->is_valid_reservation_date($date)) {
            return false;
        }

        $time = $this->normalize_time($time);
        $party_count = $this->parse_party_size($party_size);

        if (!$time || !$party_count) {
            return false;
        }

        $requested_start = $this->date_time_to_timestamp($date, $time);
        $requested_end = $requested_start ? $requested_start + ($this->get_duration_minutes($party_size) * MINUTE_IN_SECONDS) : false;

        if (!$requested_start || !$requested_end) {
            return false;
        }

        foreach ($this->get_reservations_for_date($date, $exclude_post_id) as $reservation) {
            if (($reservation['status'] ?? '') === 'abgelehnt') {
                continue;
            }

            if (!$reservation['start'] || !$reservation['end']) {
                continue;
            }

            if ($requested_start < $reservation['end'] && $requested_end > $reservation['start']) {
                return false;
            }
        }

        return true;
    }

    private function send_new_reservation_notifications($post_id, $fields) {
        $admin_email = sanitize_email(get_option('admin_email'));
        $admin_sent = false;
        $customer_sent = false;

        $details = $this->get_reservation_email_details($post_id, $fields);

        if ($admin_email) {
            $subject = sprintf('Neue Reservierung: %s am %s um %s', $details['name'], $details['date_label'], $details['time_label']);
            $message = implode("
", [
                'Eine neue Reservierungsanfrage wurde über die Website gesendet.',
                '',
                'Name: ' . $details['name'],
                'Telefon: ' . $details['phone'],
                'E-Mail: ' . $details['email'],
                'Personen: ' . $details['party_size'],
                'Datum: ' . $details['date_label'],
                'Uhrzeit: ' . $details['time_label'],
                'Blockiert bis: ' . $details['blocked_until_label'],
                'Hinweise: ' . ($details['notes'] ?: 'Keine'),
                '',
                'Im Admin bearbeiten: ' . admin_url('post.php?post=' . $post_id . '&action=edit'),
            ]);

            $admin_sent = wp_mail($admin_email, $subject, $message, $this->get_email_headers());
        }

        if ($details['email']) {
            $subject = sprintf('Ihre Reservierungsanfrage bei %s', get_bloginfo('name'));
            $message = implode("
", [
                'Vielen Dank für Ihre Reservierungsanfrage bei ' . get_bloginfo('name') . '.',
                '',
                'Ihre Buchungsdaten:',
                'Name: ' . $details['name'],
                'Telefon: ' . $details['phone'],
                'E-Mail: ' . $details['email'],
                'Personen: ' . $details['party_size'],
                'Datum: ' . $details['date_label'],
                'Uhrzeit: ' . $details['time_label'],
                'Reservierungsdauer: ' . $details['duration_label'],
                'Hinweise: ' . ($details['notes'] ?: 'Keine'),
                '',
                'Falls wir Rückfragen haben, melden wir uns unter der angegebenen Telefonnummer oder E-Mail-Adresse.',
                'Telefon Restaurant: +49 781 96643005',
                'Adresse: Saarlandstraße 2, 77652 Offenburg',
            ]);

            $customer_sent = wp_mail($details['email'], $subject, $message, $this->get_email_headers());
        }

        return [
            'admin' => (bool) $admin_sent,
            'customer' => (bool) $customer_sent,
        ];
    }

    private function send_status_update_notification($post_id, $new_status, $old_status) {
        $email = sanitize_email(get_post_meta($post_id, '_guest_email', true));

        if (!$email) {
            return false;
        }

        $details = $this->get_reservation_email_details($post_id);
        $status_labels = [
            'neu' => 'neu',
            'bestätigt' => 'bestätigt',
            'abgelehnt' => 'abgelehnt',
            'erledigt' => 'erledigt',
        ];

        $new_label = $status_labels[$new_status] ?? $new_status;
        $old_label = $status_labels[$old_status] ?? $old_status;

        $subject = sprintf('Update zu Ihrer Reservierung bei %s', get_bloginfo('name'));
        $message = implode("
", [
            'Es gibt ein Update zu Ihrer Reservierung bei ' . get_bloginfo('name') . '.',
            '',
            'Bisheriger Status: ' . $old_label,
            'Neuer Status: ' . $new_label,
            '',
            'Name: ' . $details['name'],
            'Personen: ' . $details['party_size'],
            'Datum: ' . $details['date_label'],
            'Uhrzeit: ' . $details['time_label'],
            '',
            'Bei Fragen erreichen Sie uns unter +49 781 96643005.',
        ]);

        return (bool) wp_mail($email, $subject, $message, $this->get_email_headers());
    }

    private function get_reservation_email_details($post_id = 0, $fields = []) {
        $name = $fields['guest_name'] ?? get_post_meta($post_id, '_guest_name', true);
        $phone = $fields['guest_phone'] ?? get_post_meta($post_id, '_guest_phone', true);
        $email = $fields['guest_email'] ?? get_post_meta($post_id, '_guest_email', true);
        $party_size = $fields['party_size'] ?? get_post_meta($post_id, '_party_size', true);
        $date = $fields['reservation_date'] ?? get_post_meta($post_id, '_reservation_date', true);
        $time = $fields['reservation_time'] ?? get_post_meta($post_id, '_reservation_time', true);
        $notes = $fields['reservation_notes'] ?? get_post_meta($post_id, '_reservation_notes', true);

        $date_label = $date ? wp_date('d.m.Y', strtotime($date)) : '–';
        $time_label = $this->normalize_time($time) ?: '–';
        $duration = $this->get_duration_minutes($party_size);
        $blocked_until_label = '–';

        if ($date && $time_label) {
            $start = $this->date_time_to_timestamp($date, $time_label);
            if ($start) {
                $blocked_until_label = wp_date('d.m.Y H:i', $start + ($duration * MINUTE_IN_SECONDS));
            }
        }

        return [
            'name' => $name ?: '–',
            'phone' => $phone ?: '–',
            'email' => $email ?: '',
            'party_size' => $party_size ?: '–',
            'date_label' => $date_label,
            'time_label' => $time_label,
            'duration_label' => $duration ? ($duration . ' Minuten') : '–',
            'blocked_until_label' => $blocked_until_label,
            'notes' => $notes ?: '',
        ];
    }

    private function get_email_headers() {
        $blogname = wp_specialchars_decode(get_bloginfo('name'), ENT_QUOTES);
        $admin_email = sanitize_email(get_option('admin_email'));

        return [
            'Content-Type: text/plain; charset=UTF-8',
            sprintf('Reply-To: %s <%s>', $blogname, $admin_email),
        ];
    }

    private function humanize_notification_status($status) {
        return $status === 'yes' ? 'Gesendet' : ($status === 'no' ? 'Fehlgeschlagen' : '–');
    }

    private function get_reservations_for_date($date, $exclude_post_id = 0) {
        $query = new WP_Query([
            'post_type' => self::POST_TYPE,
            'post_status' => 'publish',
            'posts_per_page' => -1,
            'fields' => 'ids',
            'meta_key' => '_reservation_date',
            'meta_value' => $date,
            'orderby' => 'meta_value',
            'order' => 'ASC',
            'post__not_in' => $exclude_post_id ? [(int) $exclude_post_id] : [],
        ]);

        $reservations = [];

        foreach ($query->posts as $post_id) {
            $time = $this->normalize_time(get_post_meta($post_id, '_reservation_time', true));
            $party_size = get_post_meta($post_id, '_party_size', true);
            $start = $time ? $this->date_time_to_timestamp($date, $time) : false;
            $duration = $this->get_duration_minutes($party_size);

            $reservations[] = [
                'post_id' => $post_id,
                'status' => get_post_meta($post_id, self::STATUS_META, true) ?: 'neu',
                'time' => $time,
                'party_size' => $party_size,
                'duration' => $duration,
                'start' => $start,
                'end' => $start ? $start + ($duration * MINUTE_IN_SECONDS) : false,
            ];
        }

        wp_reset_postdata();

        return $reservations;
    }

    private function get_duration_minutes($party_size) {
        $count = $this->parse_party_size($party_size);

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

        if ($count === 1) {
            return 10;
        }

        if ($count === 2) {
            return 15;
        }

        if ($count <= 4) {
            return 30;
        }

        return 60;
    }

    private function parse_party_size($party_size) {
        if (is_numeric($party_size)) {
            return max(0, (int) $party_size);
        }

        if (is_string($party_size) && preg_match('/^(\d+)\+?$/', $party_size, $matches)) {
            return max(0, (int) $matches[1]);
        }

        return 0;
    }

    private function normalize_time($time) {
        if (!is_string($time) || $time === '') {
            return '';
        }

        $date_time = date_create_from_format('H:i', $time, wp_timezone()) ?: date_create_from_format('H:i:s', $time, wp_timezone());

        if (!$date_time) {
            return '';
        }

        return $date_time->format('H:i');
    }

    private function is_valid_reservation_date($date) {
        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', (string) $date)) {
            return false;
        }

        $candidate = date_create_immutable_from_format('Y-m-d', $date, wp_timezone());

        return $candidate && $candidate->format('Y-m-d') === $date;
    }

    private function date_time_to_timestamp($date, $time) {
        $date_time = date_create_immutable_from_format('Y-m-d H:i', $date . ' ' . $time, wp_timezone());

        return $date_time ? $date_time->getTimestamp() : false;
    }

    private function get_blocked_until_label($post_id) {
        $date = get_post_meta($post_id, '_reservation_date', true);
        $time = $this->normalize_time(get_post_meta($post_id, '_reservation_time', true));
        $party_size = get_post_meta($post_id, '_party_size', true);
        $start = ($date && $time) ? $this->date_time_to_timestamp($date, $time) : false;

        if (!$start) {
            return '–';
        }

        $end = $start + ($this->get_duration_minutes($party_size) * MINUTE_IN_SECONDS);

        return wp_date('Y-m-d H:i', $end);
    }
}

$GLOBALS['nazar_kebap_mvp'] = new Nazar_Kebap_MVP();
