<?php
/**
 * Menu footer (legal info, contact) and printable dish menu.
 *
 * @package Maca_Menu_List
 */

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

/**
 * Whether the dish menu footer is enabled.
 *
 * @return bool
 */
function maca_menulist_menu_footer_enabled() {
    if (!maca_menulist_is_dishes_mode()) {
        return false;
    }

    return get_option('maca_menulist_menu_footer_enabled', '1') === '1';
}

/**
 * Default footer copy (translatable).
 *
 * @param string $key Footer text key: allergy, price, age.
 * @return string
 */
function maca_menulist_get_menu_footer_default_text($key) {
    $defaults = array(
        'allergy' => __(
            'Do you have allergies or special dietary requirements? Please ask our staff — we are happy to help.',
            'maca-restu-pro'
        ),
        'price' => maca_menulist_get_menu_footer_default_price_text(),
        'age' => __('ID may be required when purchasing alcohol.', 'maca-restu-pro'),
    );

    return isset($defaults[$key]) ? $defaults[$key] : '';
}

/**
 * Default price/VAT notice, including configured dine-in and takeaway rates when set.
 *
 * @return string
 */
function maca_menulist_get_menu_footer_default_price_text() {
    $text = __('All prices include VAT.', 'maca-restu-pro');
    $rate_details = maca_menulist_get_vat_rate_summary_text();

    if ($rate_details !== '') {
        /* translators: 1: base price notice, 2: dine-in/takeaway VAT rate summary */
        $text = sprintf(__('%1$s %2$s', 'maca-restu-pro'), $text, $rate_details);
    }

    return $text;
}

/**
 * Stored VAT registration number (Momsregistreringsnummer).
 *
 * @return string
 */
function maca_menulist_get_vat_number() {
    return trim((string) get_option('maca_menulist_menu_footer_vat_number', ''));
}

/**
 * Sanitize a VAT rate percentage (0–100).
 *
 * @param mixed $value Raw value.
 * @return string Empty string when unset, otherwise decimal string.
 */
function maca_menulist_sanitize_vat_rate($value) {
    if ($value === null || $value === '') {
        return '';
    }

    $rate = (float) $value;
    if ($rate < 0) {
        $rate = 0;
    }
    if ($rate > 100) {
        $rate = 100;
    }

    $formatted = number_format($rate, 2, '.', '');
    $formatted = rtrim(rtrim($formatted, '0'), '.');

    return $formatted;
}

/**
 * VAT rate for dine-in (äta på plats), as percentage — resolved at optional timestamp.
 *
 * @param int|null $at Unix timestamp; null = now.
 * @return string Empty when not configured.
 */
function maca_menulist_get_vat_rate_dine_in($at = null) {
    if (function_exists('maca_menulist_resolve_vat_rate_for_category')) {
        return maca_menulist_resolve_vat_rate_for_category('dine_in', $at);
    }

    return maca_menulist_sanitize_vat_rate(get_option('maca_menulist_vat_rate_dine_in', ''));
}

/**
 * VAT rate for takeaway (hämtmat), as percentage — resolved at optional timestamp.
 *
 * @param int|null $at Unix timestamp; null = now.
 * @return string Empty when not configured.
 */
function maca_menulist_get_vat_rate_takeaway($at = null) {
    if (function_exists('maca_menulist_resolve_vat_rate_for_category')) {
        return maca_menulist_resolve_vat_rate_for_category('takeaway', $at);
    }

    return maca_menulist_sanitize_vat_rate(get_option('maca_menulist_vat_rate_takeaway', ''));
}

/**
 * VAT rate for alcohol, as percentage — resolved at optional timestamp.
 *
 * @param int|null $at Unix timestamp; null = now.
 * @return string Empty when not configured.
 */
function maca_menulist_get_vat_rate_alcohol($at = null) {
    if (function_exists('maca_menulist_resolve_vat_rate_for_category')) {
        return maca_menulist_resolve_vat_rate_for_category('alcohol', $at);
    }

    return maca_menulist_sanitize_vat_rate(get_option('maca_menulist_vat_rate_alcohol', ''));
}

/**
 * Human-readable VAT rate label, e.g. 12%.
 *
 * @param string $rate Sanitized rate.
 * @return string
 */
function maca_menulist_format_vat_rate_label($rate) {
    $rate = maca_menulist_sanitize_vat_rate($rate);
    if ($rate === '') {
        return '';
    }

    return $rate . '%';
}

/**
 * Short summary of configured dine-in, takeaway, and alcohol VAT rates.
 *
 * @return string
 */
function maca_menulist_get_vat_rate_summary_text() {
    if (function_exists('maca_menulist_build_vat_rate_summary_text')) {
        return maca_menulist_build_vat_rate_summary_text();
    }

    $parts = array();
    $dine_in = maca_menulist_get_vat_rate_dine_in();
    $takeaway = maca_menulist_get_vat_rate_takeaway();
    $alcohol = maca_menulist_get_vat_rate_alcohol();

    if ($dine_in !== '') {
        /* translators: %s: VAT rate, e.g. 12% */
        $parts[] = sprintf(__('Dine-in %s VAT.', 'maca-restu-pro'), maca_menulist_format_vat_rate_label($dine_in));
    }

    if ($takeaway !== '') {
        /* translators: %s: VAT rate, e.g. 6% */
        $parts[] = sprintf(__('Takeaway %s VAT.', 'maca-restu-pro'), maca_menulist_format_vat_rate_label($takeaway));
    }

    if ($alcohol !== '') {
        /* translators: %s: VAT rate, e.g. 25% */
        $parts[] = sprintf(__('Alcohol %s VAT.', 'maca-restu-pro'), maca_menulist_format_vat_rate_label($alcohol));
    }

    return implode(' ', $parts);
}

/**
 * Get configured footer text with fallback to defaults.
 *
 * @param string $key Footer text key: allergy, price, age.
 * @return string
 */
function maca_menulist_get_menu_footer_text($key) {
    if (function_exists('maca_menulist_get_bilingual_option_text')) {
        $text = maca_menulist_get_bilingual_option_text($key);
        if ($text !== '') {
            return $text;
        }
    }

    $option_map = array(
        'allergy' => 'maca_menulist_menu_footer_allergy_text',
        'price' => 'maca_menulist_menu_footer_price_text',
        'age' => 'maca_menulist_menu_footer_age_text',
    );

    if (!isset($option_map[$key])) {
        return '';
    }

    $stored = get_option($option_map[$key], '');

    if (is_string($stored) && trim($stored) !== '') {
        return $stored;
    }

    return maca_menulist_get_menu_footer_default_text($key);
}

/**
 * Footer settings for display and print.
 *
 * @return array<string, mixed>
 */
function maca_menulist_get_menu_footer_settings() {
    return array(
        'enabled' => maca_menulist_menu_footer_enabled(),
        'restaurant_name' => get_option('maca_menulist_menu_footer_restaurant_name', ''),
        'address' => get_option('maca_menulist_menu_footer_address', ''),
        'vat_number' => maca_menulist_get_vat_number(),
        'vat_rate_dine_in' => maca_menulist_get_vat_rate_dine_in(),
        'vat_rate_takeaway' => maca_menulist_get_vat_rate_takeaway(),
        'vat_rate_alcohol' => maca_menulist_get_vat_rate_alcohol(),
        'phone' => get_option('maca_menulist_menu_footer_phone', ''),
        'email' => get_option('maca_menulist_menu_footer_email', ''),
        'website' => get_option('maca_menulist_menu_footer_website', ''),
        'allergy_text' => maca_menulist_get_menu_footer_text('allergy'),
        'price_text' => maca_menulist_get_menu_footer_text('price'),
        'serves_alcohol' => get_option('maca_menulist_menu_footer_serves_alcohol', '0') === '1',
        'age_text' => maca_menulist_get_menu_footer_text('age'),
        'print_title' => maca_menulist_get_bilingual_option_text('print_title'),
    );
}

/**
 * Title used on the printable menu.
 *
 * @return string
 */
function maca_menulist_get_menu_print_title() {
    $settings = maca_menulist_get_menu_footer_settings();

    if ($settings['print_title'] !== '') {
        return $settings['print_title'];
    }

    if ($settings['restaurant_name'] !== '') {
        return $settings['restaurant_name'];
    }

    return maca_menulist_get_qr_guest_page_title();
}

/**
 * Whether the footer has any visible content.
 *
 * @param array<string, mixed> $settings Footer settings.
 * @return bool
 */
function maca_menulist_menu_footer_has_content($settings) {
    if ($settings['allergy_text'] !== '' || $settings['price_text'] !== '') {
        return true;
    }

    if ($settings['serves_alcohol'] && $settings['age_text'] !== '') {
        return true;
    }

    if (
        $settings['restaurant_name'] !== ''
        || $settings['address'] !== ''
        || !empty($settings['vat_number'])
        || $settings['phone'] !== ''
        || $settings['email'] !== ''
        || $settings['website'] !== ''
    ) {
        return true;
    }

    return false;
}

/**
 * Website URL shown in the menu footer.
 *
 * @param array<string, mixed> $settings Footer settings.
 * @return string
 */
function maca_menulist_get_menu_footer_website_url($settings) {
    $website = isset($settings['website']) ? trim((string) $settings['website']) : '';

    if ($website !== '') {
        return esc_url($website);
    }

    return esc_url(home_url('/'));
}

/**
 * Short label for a website URL (without scheme).
 *
 * @param string $url Website URL.
 * @return string
 */
function maca_menulist_get_menu_footer_website_label($url) {
    $label = preg_replace('#^https?://#i', '', $url);
    return rtrim((string) $label, '/');
}

/**
 * Inline SVG icon for menu footer contact rows.
 *
 * @param string $type Icon type: phone, email, website.
 * @return string
 */
function maca_menulist_get_menu_footer_icon_svg($type) {
    $icons = array(
        'phone' => '<svg class="maca-menu-footer-icon-svg" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 16.92z"/></svg>',
        'email' => '<svg class="maca-menu-footer-icon-svg" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg>',
        'website' => '<svg class="maca-menu-footer-icon-svg" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="10"/><path d="M2 12h20"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>',
    );

    return isset($icons[$type]) ? $icons[$type] : '';
}

/**
 * Contact rows (phone, email, website) for menu footers.
 *
 * @param array<string, mixed> $settings Footer settings.
 * @return array<int, array<string, string>>
 */
function maca_menulist_get_menu_footer_contact_items($settings) {
    $items = array();

    if (!empty($settings['phone'])) {
        $phone_href = preg_replace('/[^\d+]/', '', (string) $settings['phone']);
        $items[] = array(
            'type' => 'phone',
            'label' => (string) $settings['phone'],
            'href' => $phone_href !== '' ? 'tel:' . $phone_href : '',
        );
    }

    $email = isset($settings['email']) ? sanitize_email(trim((string) $settings['email'])) : '';
    if ($email !== '') {
        $items[] = array(
            'type' => 'email',
            'label' => $email,
            'href' => 'mailto:' . $email,
        );
    }

    $website_url = maca_menulist_get_menu_footer_website_url($settings);
    if ($website_url !== '') {
        $items[] = array(
            'type' => 'website',
            'label' => maca_menulist_get_menu_footer_website_label($website_url),
            'href' => $website_url,
        );
    }

    return $items;
}

/**
 * Whether the contact block has name, address, or contact rows.
 *
 * @param array<string, mixed> $settings Footer settings.
 * @return bool
 */
function maca_menulist_menu_footer_has_contact_block($settings) {
    if ($settings['restaurant_name'] !== '' || $settings['address'] !== '') {
        return true;
    }

    return !empty(maca_menulist_get_menu_footer_contact_items($settings));
}

/**
 * Available print menu themes.
 *
 * @return array<string, string>
 */
function maca_menulist_get_menu_print_themes() {
    return array(
        'classic' => __('Classic', 'maca-restu-pro'),
        'modern' => __('Modern', 'maca-restu-pro'),
        'minimal' => __('Minimal', 'maca-restu-pro'),
    );
}

/**
 * Active print menu theme key.
 *
 * @param string $override Optional theme override (admin preview).
 * @return string
 */
function maca_menulist_get_menu_print_theme($override = '') {
    $themes = maca_menulist_get_menu_print_themes();
    $override = sanitize_key($override);

    if ($override !== '' && isset($themes[$override])) {
        return $override;
    }

    $theme = sanitize_key(get_option('maca_menulist_menu_print_theme', 'classic'));

    if (!isset($themes[$theme])) {
        $theme = 'classic';
    }

    return $theme;
}

/**
 * Logo URL for the printable menu.
 *
 * @return string
 */
function maca_menulist_get_menu_print_logo_url() {
    $logo = get_option('maca_menulist_menu_print_logo', '');

    if ($logo !== '') {
        return esc_url($logo);
    }

    if (function_exists('maca_menulist_get_qr_menu_logo_url')) {
        return maca_menulist_get_qr_menu_logo_url();
    }

    $qr_logo = get_option('maca_menulist_qr_logo', '');

    return $qr_logo !== '' ? esc_url($qr_logo) : '';
}

/**
 * Centered company lines for the print footer.
 *
 * @param array<string, mixed> $settings Footer settings.
 * @return array<int, string>
 */
function maca_menulist_get_menu_print_company_lines($settings) {
    $lines = array();
    $line1 = array();

    if (!empty($settings['restaurant_name'])) {
        $line1[] = $settings['restaurant_name'];
    }

    if (!empty($settings['address'])) {
        $line1[] = str_replace(array("\r\n", "\r", "\n"), ', ', trim((string) $settings['address']));
    }

    if (!empty($line1)) {
        $lines[] = implode(' · ', $line1);
    }

    if (!empty($settings['vat_number'])) {
        /* translators: %s: VAT registration number */
        $lines[] = sprintf(__('VAT no. %s', 'maca-restu-pro'), (string) $settings['vat_number']);
    }

    return $lines;
}

/**
 * Render contact items with icons on one centered row (screen and print footers).
 *
 * @param array<string, mixed> $settings Footer settings.
 * @param string               $context  screen|print
 * @return void
 */
function maca_menulist_render_menu_footer_contact_items($settings, $context = 'screen') {
    $items = maca_menulist_get_menu_footer_contact_items($settings);

    if (empty($items)) {
        return;
    }

    $is_print = ($context === 'print');
    $row_class = $is_print
        ? 'maca-menu-print-company-line maca-menu-print-contact-row'
        : 'maca-menu-footer-company-line maca-menu-footer-contact-row';
    $sep_class = $is_print ? 'maca-menu-print-contact-sep' : 'maca-menu-footer-contact-sep';

    echo '<p class="' . esc_attr($row_class) . '">';

    foreach ($items as $index => $item) {
        if ($index > 0) {
            echo '<span class="' . esc_attr($sep_class) . '" aria-hidden="true"> · </span>';
        }

        echo '<span class="maca-menu-footer-contact-item maca-menu-footer-contact-item--' . esc_attr($item['type']) . '">';
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Static SVG markup.
        echo '<span class="maca-menu-footer-icon">' . maca_menulist_get_menu_footer_icon_svg($item['type']) . '</span>';

        if (!$is_print && $item['href'] !== '') {
            echo '<a href="' . esc_url($item['href']) . '"';
            if ($item['type'] === 'website') {
                echo ' target="_blank" rel="noopener noreferrer"';
            }
            echo '>' . esc_html($item['label']) . '</a>';
        } else {
            echo '<span>' . esc_html($item['label']) . '</span>';
        }

        echo '</span>';
    }

    echo '</p>';
}

/**
 * Centered company block: name/address line(s) plus contact row with icons.
 *
 * @param array<string, mixed> $settings Footer settings.
 * @param string               $context  screen|print
 * @return void
 */
function maca_menulist_render_menu_footer_company_block($settings, $context = 'screen') {
    $company_lines = maca_menulist_get_menu_print_company_lines($settings);
    $contact_items = maca_menulist_get_menu_footer_contact_items($settings);

    if (empty($company_lines) && empty($contact_items)) {
        return;
    }

    $is_print = ($context === 'print');
    $wrapper_class = $is_print ? 'maca-menu-print-company' : 'maca-menu-footer-company';
    $line_class = $is_print ? 'maca-menu-print-company-line' : 'maca-menu-footer-company-line';

    echo '<div class="' . esc_attr($wrapper_class) . '">';

    foreach ($company_lines as $line) {
        echo '<p class="' . esc_attr($line_class) . '">' . esc_html($line) . '</p>';
    }

    maca_menulist_render_menu_footer_contact_items($settings, $context);

    echo '</div>';
}

/**
 * Paper size for printable menu (A4 or A5).
 *
 * @return string
 */
function maca_menulist_get_menu_print_paper_size() {
    $size = sanitize_key(get_option('maca_menulist_menu_print_paper_size', ''));

    if ($size === '') {
        $size = sanitize_key(get_option('maca_menulist_qr_paper_size', 'a4'));
    }

    return $size === 'a5' ? 'A5' : 'A4';
}

/**
 * Print layout density for printable menu.
 *
 * @param string $override Optional layout override (admin preview).
 * @return string compact|standard
 */
function maca_menulist_get_menu_print_layout_density($override = '') {
    $override = sanitize_key($override);
    if (in_array($override, array('compact', 'standard'), true)) {
        return $override;
    }

    $layout = sanitize_key(get_option('maca_menulist_menu_print_layout', 'compact'));
    return in_array($layout, array('compact', 'standard'), true) ? $layout : 'compact';
}

/**
 * Inner page padding used when printing (browser @page margin is zero).
 *
 * @param string $paper_size Paper size label.
 * @return string
 */
function maca_menulist_get_menu_print_page_padding($paper_size = '') {
    if ($paper_size === '') {
        $paper_size = maca_menulist_get_menu_print_paper_size();
    }

    return ($paper_size === 'A5') ? '8mm' : '12mm';
}

/**
 * Legal + company block at the bottom of printable menus (normal document flow, not a browser footer).
 */
function maca_menulist_render_dish_menu_print_footer() {
    maca_menulist_load_textdomain();

    $settings = maca_menulist_get_menu_footer_settings();
    $legal_items = array();

    if ($settings['allergy_text'] !== '') {
        $legal_items[] = $settings['allergy_text'];
    }

    if ($settings['price_text'] !== '') {
        $legal_items[] = $settings['price_text'];
    }

    if ($settings['serves_alcohol'] && $settings['age_text'] !== '') {
        $legal_items[] = $settings['age_text'];
    }

    $company_lines = maca_menulist_get_menu_print_company_lines($settings);
    $contact_items = maca_menulist_get_menu_footer_contact_items($settings);

    if (empty($legal_items) && empty($company_lines) && empty($contact_items)) {
        return;
    }

    echo '<div class="maca-menu-print-footer" role="contentinfo" aria-label="' . esc_attr__('Menu information', 'maca-restu-pro') . '">';

    if (!empty($legal_items)) {
        echo '<div class="maca-menu-print-legal">';
        foreach ($legal_items as $item) {
            echo '<p class="maca-menu-print-legal-item">' . esc_html($item) . '</p>';
        }
        echo '</div>';
    }

    if (!empty($company_lines) || !empty($contact_items)) {
        maca_menulist_render_menu_footer_company_block($settings, 'print');
    }

    echo '</div>';
}

/**
 * Render menu footer on the guest dish menu (website and QR).
 */
function maca_menulist_render_dish_menu_footer($context = 'screen') {
    if ($context === 'print') {
        maca_menulist_render_dish_menu_print_footer();
        return;
    }

    if (!maca_menulist_menu_footer_enabled()) {
        return;
    }

    maca_menulist_load_textdomain();

    $settings = maca_menulist_get_menu_footer_settings();

    if (!maca_menulist_menu_footer_has_content($settings)) {
        return;
    }

    echo '<footer class="maca-menu-footer" aria-label="' . esc_attr__('Menu information', 'maca-restu-pro') . '">';
    echo '<div class="maca-menu-footer-inner">';

    if ($settings['allergy_text'] !== '') {
        echo '<section class="maca-menu-footer-block">';
        echo '<h4 class="maca-menu-footer-heading">' . esc_html__('Allergy information', 'maca-restu-pro') . '</h4>';
        echo '<p class="maca-menu-footer-text">' . esc_html($settings['allergy_text']) . '</p>';
        echo '</section>';
    }

    if ($settings['price_text'] !== '') {
        echo '<section class="maca-menu-footer-block">';
        echo '<h4 class="maca-menu-footer-heading">' . esc_html__('Prices', 'maca-restu-pro') . '</h4>';
        echo '<p class="maca-menu-footer-text">' . esc_html($settings['price_text']) . '</p>';
        echo '</section>';
    }

    if ($settings['serves_alcohol'] && $settings['age_text'] !== '') {
        echo '<section class="maca-menu-footer-block">';
        echo '<h4 class="maca-menu-footer-heading">' . esc_html__('Age limit', 'maca-restu-pro') . '</h4>';
        echo '<p class="maca-menu-footer-text">' . esc_html($settings['age_text']) . '</p>';
        echo '</section>';
    }

    if (maca_menulist_menu_footer_has_contact_block($settings)) {
        echo '<section class="maca-menu-footer-block maca-menu-footer-contact">';
        maca_menulist_render_menu_footer_company_block($settings, 'screen');
        echo '</section>';
    }

    echo '</div>';
    echo '</footer>';
}

/**
 * Render printable dish rows (text-focused layout).
 */
function maca_menulist_render_printable_dish_menu_body($campaign_id = 0) {
    maca_menulist_load_textdomain();
    $grouped = array();

    if ($campaign_id > 0) {
        $campaign = maca_menulist_db_get_campaign($campaign_id);
        if ($campaign) {
            $campaign_dishes = maca_menulist_db_get_dishes_for_campaign((int) $campaign->id, true);
            if (!empty($campaign_dishes)) {
                $grouped = maca_menulist_build_grouped_dishes_from_campaigns(
                    array(
                        array(
                            'campaign' => $campaign,
                            'dishes' => maca_menulist_prepare_campaign_dishes($campaign_dishes),
                        ),
                    )
                );
            }
        }
    } else {
        $grouped = maca_menulist_get_grouped_dishes();
    }

    if (empty($grouped)) {
        $empty_label = $campaign_id > 0
            ? __('No dishes available in this campaign.', 'maca-restu-pro')
            : __('No dishes available.', 'maca-restu-pro');
        echo '<p class="maca-menu-print-empty">' . esc_html($empty_label) . '</p>';
        return;
    }

    echo '<div class="maca-menu-print-body">';

    foreach ($grouped as $group) {
        $category = $group['category'];
        $dishes = $group['dishes'];

        echo '<section class="maca-menu-print-category">';
        echo '<h2 class="maca-menu-print-category-title">' . esc_html(maca_menulist_get_dish_category_display_name($category)) . '</h2>';
        echo '<ul class="maca-menu-print-dish-list">';

        foreach ($dishes as $dish) {
            $price = maca_menulist_format_price($dish->price);
            $allergens = !empty($dish->allergens) && is_array($dish->allergens) ? $dish->allergens : array();

            echo '<li class="maca-menu-print-dish">';
            echo '<div class="maca-menu-print-dish-header">';
            echo '<span class="maca-menu-print-dish-title">' . esc_html(maca_menulist_get_dish_display_title($dish)) . '</span>';

            if ($price !== '') {
                echo '<span class="maca-menu-print-dish-price">' . esc_html($price) . '</span>';
            }

            echo '</div>';

            $print_description = maca_menulist_get_dish_display_description($dish);
            if ($print_description !== '') {
                echo '<p class="maca-menu-print-dish-description">' . esc_html($print_description) . '</p>';
            }

            if (!empty($allergens)) {
                $allergen_names = array();

                foreach ($allergens as $allergen) {
                    if (is_object($allergen)) {
                        $label = maca_menulist_get_allergen_display_name($allergen);
                        if ($label !== '') {
                            $allergen_names[] = $label;
                        }
                    }
                }

                if (!empty($allergen_names)) {
                    echo '<p class="maca-menu-print-dish-allergens"><em>';
                    echo esc_html__('Allergens:', 'maca-restu-pro') . ' ';
                    echo esc_html(implode(', ', $allergen_names));
                    echo '</em></p>';
                }
            }

            echo '</li>';
        }

        echo '</ul>';
        echo '</section>';
    }

    echo '</div>';
}

/**
 * Output inline CSS for printable menu page.
 *
 * @param string $theme Theme key.
 * @param string $layout_density_override Optional print density override.
 * @return string
 */
function maca_menulist_get_menu_print_styles($theme = 'classic', $layout_density_override = '') {
    $theme = maca_menulist_get_menu_print_theme($theme);
    $paper_size = maca_menulist_get_menu_print_paper_size();
    $print_side_padding = maca_menulist_get_menu_print_page_padding($paper_size);
    $print_vertical_padding = '100px';
    $layout_density = maca_menulist_get_menu_print_layout_density($layout_density_override);
    $compact_print_css = '';

    if ($paper_size === 'A4' && $layout_density === 'compact') {
        $compact_print_css = '
            .maca-menu-print-page {
                padding: 10mm 9mm !important;
            }
            .maca-menu-print-logo-wrap {
                margin-bottom: 10px;
            }
            .maca-menu-print-logo {
                max-height: 78px;
            }
            .maca-menu-print-title {
                font-size: 24px;
                margin-bottom: 14px;
                line-height: 1.2;
            }
            .maca-menu-print-category {
                margin-bottom: 14px;
            }
            .maca-menu-print-category-title {
                font-size: 15px;
                margin-bottom: 7px;
                padding-bottom: 3px;
                line-height: 1.2;
            }
            .maca-menu-print-dish {
                margin-bottom: 8px;
            }
            .maca-menu-print-dish-title {
                font-size: 14px;
                line-height: 1.25;
            }
            .maca-menu-print-dish-price {
                font-size: 13px;
            }
            .maca-menu-print-dish-description,
            .maca-menu-print-dish-allergens {
                margin-top: 2px;
                font-size: 11.5px;
                line-height: 1.32;
            }
            .maca-menu-print-footer {
                margin-top: 18px;
                padding-top: 12px;
            }
            .maca-menu-print-legal-item,
            .maca-menu-print-company-line {
                font-size: 11px;
                line-height: 1.35;
            }
        ';
    }

    $css = '
        * { box-sizing: border-box; margin: 0; padding: 0; }
        body {
            color: #1a1a1a;
            background: #f5f5f5;
            line-height: 1.45;
        }
        .maca-menu-print-toolbar {
            position: sticky;
            top: 0;
            z-index: 10;
            display: flex;
            justify-content: center;
            align-items: center;
            flex-wrap: wrap;
            gap: 12px;
            padding: 14px;
            background: #fff;
            border-bottom: 1px solid #ddd;
        }
        .maca-menu-print-toolbar button,
        .maca-menu-print-toolbar a {
            display: inline-block;
            padding: 10px 18px;
            border-radius: 4px;
            font-size: 14px;
            text-decoration: none;
            cursor: pointer;
        }
        .maca-menu-print-toolbar button {
            background: #0073aa;
            color: #fff;
            border: none;
        }
        .maca-menu-print-toolbar a {
            background: #fff;
            color: #0073aa;
            border: 1px solid #0073aa;
        }
        .maca-menu-print-toolbar-note {
            width: 100%;
            text-align: center;
            font-size: 13px;
            color: #666;
        }
        .maca-menu-print-toolbar-hint {
            width: 100%;
            max-width: 640px;
            margin: 0 auto;
            text-align: left;
            font-size: 12px;
            line-height: 1.5;
            color: #444;
            background: #f7f8fa;
            border: 1px solid #e2e6ea;
            border-radius: 6px;
            padding: 10px 14px;
        }
        .maca-menu-print-toolbar-hint strong {
            display: block;
            margin-bottom: 4px;
            color: #222;
        }
        .maca-menu-print-page {
            max-width: 800px;
            margin: 24px auto 40px;
            padding: 40px 48px;
            background: #fff;
        }
        .maca-menu-print-logo-wrap {
            text-align: center;
            margin: 0 0 20px;
        }
        .maca-menu-print-logo {
            max-width: 220px;
            max-height: 120px;
            width: auto;
            height: auto;
            object-fit: contain;
        }
        .maca-menu-print-title {
            text-align: center;
            font-size: 30px;
            font-weight: 700;
            margin: 0 0 28px;
            letter-spacing: 0.02em;
        }
        .maca-menu-print-category {
            margin: 0 0 26px;
            /* Let long categories flow naturally across pages. */
            page-break-inside: auto;
            break-inside: auto;
        }
        .maca-menu-print-category-title {
            font-size: 18px;
            font-weight: 700;
            margin: 0 0 12px;
            padding-bottom: 6px;
            page-break-after: avoid;
            break-after: avoid-page;
        }
        .maca-menu-print-dish-list { list-style: none; margin: 0; padding: 0; }
        .maca-menu-print-dish {
            margin: 0 0 14px;
            page-break-inside: avoid;
            break-inside: avoid-page;
        }
        .maca-menu-print-dish-header {
            display: flex;
            align-items: baseline;
            justify-content: space-between;
            gap: 16px;
        }
        .maca-menu-print-dish-title {
            font-size: 16px;
            font-weight: 700;
        }
        .maca-menu-print-dish-price {
            flex: 0 0 auto;
            font-size: 15px;
            font-weight: 700;
            white-space: nowrap;
        }
        .maca-menu-print-dish-description,
        .maca-menu-print-dish-allergens {
            margin: 4px 0 0;
            font-size: 13px;
            color: #444;
            orphans: 2;
            widows: 2;
        }
        .maca-menu-print-empty {
            text-align: center;
            padding: 40px 0;
            color: #666;
        }
        .maca-menu-print-footer {
            margin-top: 36px;
            padding-top: 22px;
            border-top: 1px solid #ccc;
            text-align: center;
            page-break-inside: avoid;
            break-inside: avoid-page;
        }
        .maca-menu-print-legal {
            margin: 0 0 16px;
        }
        .maca-menu-print-legal-item {
            margin: 0 0 8px;
            font-size: 12px;
            font-style: italic;
            color: #444;
            line-height: 1.5;
        }
        .maca-menu-print-legal-item:last-child {
            margin-bottom: 0;
        }
        .maca-menu-print-company-line {
            margin: 0 0 6px;
            font-size: 13px;
            font-weight: 600;
            color: #222;
            line-height: 1.45;
        }
        .maca-menu-print-company-line:last-child {
            margin-bottom: 0;
        }
        .maca-menu-print-contact-row {
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
            align-items: center;
            gap: 4px 0;
        }
        .maca-menu-footer-contact-item {
            display: inline-flex;
            align-items: center;
            gap: 4px;
        }
        .maca-menu-footer-icon {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            flex: 0 0 auto;
            color: #555;
        }
        .maca-menu-footer-icon-svg {
            display: block;
            width: 14px;
            height: 14px;
        }
        .maca-menu-print-contact-sep {
            margin: 0 6px;
            color: #666;
        }
        @media (max-width: 700px) {
            .maca-menu-print-page { padding: 24px 18px; margin: 16px; }
        }
    ';

    if ($theme === 'classic') {
        $css .= '
        body.maca-menu-print-theme-classic {
            font-family: Georgia, "Times New Roman", serif;
        }
        body.maca-menu-print-theme-classic .maca-menu-print-page {
            border: 3px double #222;
            box-shadow: 0 2px 16px rgba(0, 0, 0, 0.08);
        }
        body.maca-menu-print-theme-classic .maca-menu-print-category-title {
            text-transform: uppercase;
            letter-spacing: 0.06em;
            border-bottom: 1px solid #222;
        }
        ';
    } elseif ($theme === 'modern') {
        $css .= '
        body.maca-menu-print-theme-modern {
            font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
        }
        body.maca-menu-print-theme-modern .maca-menu-print-page {
            border: 1px solid #d7dee8;
            border-top: 4px solid #0073aa;
            box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
        }
        body.maca-menu-print-theme-modern .maca-menu-print-title {
            color: #0073aa;
        }
        body.maca-menu-print-theme-modern .maca-menu-print-category-title {
            color: #0073aa;
            text-transform: uppercase;
            letter-spacing: 0.08em;
            border-bottom: 2px solid #0073aa;
        }
        body.maca-menu-print-theme-modern .maca-menu-print-dish-price {
            color: #0073aa;
        }
        ';
    } else {
        $css .= '
        body.maca-menu-print-theme-minimal {
            font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        }
        body.maca-menu-print-theme-minimal .maca-menu-print-page {
            border: none;
            box-shadow: none;
            padding-top: 28px;
            padding-bottom: 28px;
        }
        body.maca-menu-print-theme-minimal .maca-menu-print-title {
            font-size: 24px;
            font-weight: 600;
            letter-spacing: 0.12em;
            text-transform: uppercase;
        }
        body.maca-menu-print-theme-minimal .maca-menu-print-category-title {
            font-size: 14px;
            font-weight: 600;
            letter-spacing: 0.14em;
            text-transform: uppercase;
            color: #666;
            border-bottom: 1px solid #ddd;
        }
        body.maca-menu-print-theme-minimal .maca-menu-print-dish-title {
            font-weight: 600;
        }
        body.maca-menu-print-theme-minimal .maca-menu-print-footer {
            border-top-color: #e5e5e5;
        }
        ';
    }

    $css .= '
        @media print {
            @page {
                margin: 0;
                size: ' . esc_attr($paper_size) . ';
            }
            html, body {
                background: #fff;
                margin: 0;
                padding: 0;
            }
            .maca-menu-print-toolbar {
                display: none !important;
            }
            .maca-menu-print-page {
                max-width: none;
                width: 100%;
                margin: 0;
                padding: ' . esc_attr($print_vertical_padding) . ' ' . esc_attr($print_side_padding) . ';
                -webkit-box-decoration-break: clone;
                box-decoration-break: clone;
                box-shadow: none !important;
                border: none !important;
            }
            .maca-menu-print-category-title {
                page-break-after: avoid !important;
                break-after: avoid-page !important;
            }
            .maca-menu-print-dish {
                page-break-inside: avoid !important;
                break-inside: avoid-page !important;
            }
            .maca-menu-print-footer {
                page-break-inside: avoid !important;
                break-inside: avoid-page !important;
            }
            ' . $compact_print_css . '
        }
    ';

    return $css;
}

/**
 * Render full printable menu document and exit.
 */
function maca_menulist_render_menu_print_document() {
    if (!maca_menulist_is_dishes_mode()) {
        wp_die(esc_html__('Online menu requires an active Pro subscription.', 'maca-restu-pro'));
    }

    maca_menulist_load_textdomain();

    // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Theme preview for admins on print page.
    $theme_override = isset($_GET['theme']) ? sanitize_key(wp_unslash($_GET['theme'])) : '';
    $theme = maca_menulist_get_menu_print_theme($theme_override);
    // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Layout preview for admins on print page.
    $layout_override = isset($_GET['layout']) ? sanitize_key(wp_unslash($_GET['layout'])) : '';
    $layout_density = maca_menulist_get_menu_print_layout_density($layout_override);
    // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Campaign filter for print preview.
    $campaign_id = isset($_GET['campaign_id']) ? absint(wp_unslash($_GET['campaign_id'])) : 0;
    $campaign = $campaign_id > 0 ? maca_menulist_db_get_campaign($campaign_id) : null;
    if ($campaign_id > 0 && !$campaign) {
        wp_die(esc_html__('Campaign not found.', 'maca-restu-pro'));
    }

    $themes = maca_menulist_get_menu_print_themes();
    $theme_label = isset($themes[$theme]) ? $themes[$theme] : $themes['classic'];
    $title = $campaign
        ? maca_menulist_get_campaign_display_name($campaign)
        : maca_menulist_get_menu_print_title();
    $logo_url = maca_menulist_get_menu_print_logo_url();
    $paper_size = maca_menulist_get_menu_print_paper_size();
    $back_url = $campaign
        ? admin_url('admin.php?page=maca-restu-campaigns')
        : admin_url('admin.php?page=maca-restu-dishes');
    $back_label = $campaign
        ? __('Back to campaigns', 'maca-restu-pro')
        : __('Back to dishes', 'maca-restu-pro');

    // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped -- Inline print stylesheet.
    echo '<!DOCTYPE html>
<html lang="' . esc_attr(str_replace('_', '-', get_locale())) . '">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>' . esc_html($title) . '</title>
    <style>' . maca_menulist_get_menu_print_styles($theme, $layout_density) . '</style>
</head>
<body class="maca-menu-print-theme-' . esc_attr($theme) . '">
    <div class="maca-menu-print-toolbar">
        <button type="button" onclick="window.print()">' . esc_html__('Print / Save as PDF', 'maca-restu-pro') . '</button>
        <a href="' . esc_url($back_url) . '" onclick="if (window.history.length > 1) { window.history.back(); return false; }">' . esc_html($back_label) . '</a>
        <p class="maca-menu-print-toolbar-note">' . esc_html(sprintf(
            /* translators: 1: print theme name, 2: layout density, 3: paper size (A4 or A5) */
            __('Print theme: %1$s · Layout: %2$s · Paper: %3$s', 'maca-restu-pro'),
            $theme_label,
            $layout_density === 'compact' ? __('Compact', 'maca-restu-pro') : __('Standard', 'maca-restu-pro'),
            $paper_size
        )) . '</p>
        <div class="maca-menu-print-toolbar-hint">
            <strong>' . esc_html__('Save as PDF without browser header or footer', 'maca-restu-pro') . '</strong>
            <p>' . esc_html__('In the print dialog, turn off “Headers and footers” (Chrome/Edge: More settings). The menu information at the bottom of the page is part of the menu layout, not the browser footer.', 'maca-restu-pro') . '</p>
        </div>
    </div>
    <article class="maca-menu-print-page">';

    if ($logo_url !== '') {
        echo '<div class="maca-menu-print-logo-wrap">';
        echo '<img class="maca-menu-print-logo" src="' . esc_url($logo_url) . '" alt="' . esc_attr($title) . '">';
        echo '</div>';
    }

    echo '<h1 class="maca-menu-print-title">' . esc_html($title) . '</h1>';
    // phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped

    maca_menulist_render_printable_dish_menu_body($campaign_id);
    maca_menulist_render_dish_menu_print_footer();

    echo '
    </article>
</body>
</html>';

    exit;
}

/**
 * Admin handler for printable menu page.
 */
function maca_menulist_handle_menu_print_page() {
    if (!isset($_GET['maca_menu_print']) || sanitize_text_field(wp_unslash($_GET['maca_menu_print'])) !== '1') {
        return;
    }

    if (!maca_menulist_user_can_manage_plugin()) {
        wp_die(esc_html__('You do not have permission to view this page.', 'maca-restu-pro'));
    }

    $nonce = isset($_GET['_wpnonce']) ? sanitize_text_field(wp_unslash($_GET['_wpnonce'])) : '';
    if (!wp_verify_nonce($nonce, 'maca_menu_print')) {
        wp_die(esc_html__('Invalid request.', 'maca-restu-pro'));
    }

    maca_menulist_render_menu_print_document();
}

add_action('admin_init', 'maca_menulist_handle_menu_print_page');
