<?php
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.WP.EnqueuedResourceParameters.MissingVersion -- Frontend reads custom plugin tables and registers local assets with the plugin version when available.
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class YATOON_Frontend {
    
    public function __construct() {
        add_shortcode('yatoon_booking', array($this, 'booking_shortcode'));
        add_shortcode('yatoon_catalog', array($this, 'catalog_shortcode'));
        add_shortcode('yatoon_gallery', array($this, 'gallery_shortcode'));
        add_action('wp_enqueue_scripts', array($this, 'enqueue_frontend_scripts'));
    }

    /**
     * Preload service options so returning from Add More / Add Guest does not
     * depend on a fresh admin-ajax request before the customer can continue.
     */
    private function get_preloaded_service_options() {
        global $wpdb;

        $services_table = $wpdb->prefix . 'yatoon_services';
        $options_table  = $wpdb->prefix . 'yatoon_service_options';
        $preloaded      = array();

        $options_table_exists = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $options_table ) );
        $services_table_exists = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $services_table ) );
        if ( $options_table_exists !== $options_table || $services_table_exists !== $services_table ) {
            return $preloaded;
        }

        $services = $wpdb->get_results( "SELECT id, price, square_id FROM {$services_table}" );
        $base_prices = array();
        $square_to_service = array();
        foreach ( (array) $services as $service ) {
            $service_id = intval( $service->id );
            $base_prices[ $service_id ] = floatval( $service->price );
            $preloaded[ $service_id ] = array(
                'options'    => array(),
                'base_price' => $base_prices[ $service_id ],
            );
            if ( ! empty( $service->square_id ) ) {
                $square_to_service[ (string) $service->square_id ] = $service_id;
            }
        }

        $options = $wpdb->get_results( "SELECT * FROM {$options_table} ORDER BY service_id ASC, sort_order ASC, name ASC" );
        foreach ( (array) $options as $option ) {
            $service_id  = intval( $option->service_id );
            $base_price  = isset( $base_prices[ $service_id ] ) ? $base_prices[ $service_id ] : 0;
            $linked_id   = null;
            $square_id   = isset( $option->square_id ) ? (string) $option->square_id : '';

            if ( $square_id !== '' && isset( $square_to_service[ $square_id ] ) ) {
                $linked_id = intval( $square_to_service[ $square_id ] );
            }

            if ( ! isset( $preloaded[ $service_id ] ) ) {
                $preloaded[ $service_id ] = array(
                    'options'    => array(),
                    'base_price' => $base_price,
                );
            }

            $preloaded[ $service_id ]['options'][] = array(
                'id'               => intval( $option->id ),
                'service_id'       => $service_id,
                'square_id'        => $square_id,
                'square_version'   => isset( $option->square_version ) ? $option->square_version : null,
                'name'             => (string) $option->name,
                'description'      => isset( $option->description ) ? (string) $option->description : '',
                'duration_minutes' => intval( $option->duration_minutes ),
                'price_modifier'   => floatval( $option->price_modifier ),
                'is_required'      => intval( $option->is_required ),
                'group_name'       => isset( $option->group_name ) ? $option->group_name : '',
                'badge_label'      => isset( $option->badge_label ) ? (string) $option->badge_label : '',
                'sort_order'       => intval( $option->sort_order ),
                'absolute_price'   => $base_price + floatval( $option->price_modifier ),
                'linked_service_id'=> $linked_id,
            );
        }

        return $preloaded;
    }

    /**
     * Preload eligible staff from local tables. Time-slot availability still
     * stays real-time, but the staff chooser should not wait on a network call.
     */
    private function get_preloaded_service_staff() {
        global $wpdb;

        $services_table       = $wpdb->prefix . 'yatoon_services';
        $staff_table          = $wpdb->prefix . 'yatoon_staff';
        $staff_services_table = $wpdb->prefix . 'yatoon_staff_services';
        $preloaded            = array();

        $services_table_exists = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $services_table ) );
        $staff_table_exists    = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $staff_table ) );
        if ( $services_table_exists !== $services_table || $staff_table_exists !== $staff_table ) {
            return $preloaded;
        }

        $staff_rows = $wpdb->get_results( "SELECT * FROM {$staff_table} WHERE is_active = 1 AND is_bookable = 1 ORDER BY sort_order ASC, name ASC" );
        $all_staff = array();
        $staff_by_id = array();
        foreach ( (array) $staff_rows as $staff ) {
            $row = array(
                'id'          => intval( $staff->id ),
                'name'        => (string) $staff->name,
                'bio'         => isset( $staff->bio ) ? (string) $staff->bio : '',
                'image_url'   => isset( $staff->image_url ) ? (string) $staff->image_url : '',
                'square_id'   => isset( $staff->square_id ) ? (string) $staff->square_id : '',
                'is_active'   => 1,
                'is_bookable' => 1,
            );
            $all_staff[] = $row;
            $staff_by_id[ intval( $staff->id ) ] = $row;
        }

        $assignments_by_service = array();
        $staff_services_exists = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $staff_services_table ) );
        if ( $staff_services_exists === $staff_services_table ) {
            $assignments = $wpdb->get_results( "SELECT staff_id, service_id FROM {$staff_services_table}" );
            foreach ( (array) $assignments as $assignment ) {
                $service_id = intval( $assignment->service_id );
                $staff_id   = intval( $assignment->staff_id );
                if ( ! isset( $assignments_by_service[ $service_id ] ) ) {
                    $assignments_by_service[ $service_id ] = array();
                }
                if ( isset( $staff_by_id[ $staff_id ] ) ) {
                    $assignments_by_service[ $service_id ][] = $staff_by_id[ $staff_id ];
                }
            }
        }

        $service_ids = $wpdb->get_col( "SELECT id FROM {$services_table}" );
        foreach ( (array) $service_ids as $service_id_raw ) {
            $service_id = intval( $service_id_raw );
            $staff_list = ! empty( $assignments_by_service[ $service_id ] )
                ? array_values( $assignments_by_service[ $service_id ] )
                : $all_staff;

            if ( count( $staff_list ) >= 2 ) {
                array_unshift( $staff_list, array(
                    'id'           => 0,
                    'name'         => 'Any staff',
                    'bio'          => '',
                    'image_url'    => '',
                    'square_id'    => '',
                    'is_any_staff' => true,
                    'is_active'    => 1,
                    'is_bookable'  => 1,
                ) );
            }

            $preloaded[ $service_id ] = array( 'staff' => $staff_list );
        }

        return $preloaded;
    }
    
    /**
     * Enqueue frontend scripts
     */
    public function enqueue_frontend_scripts() {
        if (!is_singular() && !is_page()) {
            return;
        }
        
        global $post;
        if (!$post || (!has_shortcode($post->post_content, 'yatoon_booking') && !has_shortcode($post->post_content, 'sbs_customer_portal') && !has_shortcode($post->post_content, 'yatoon_customer_portal'))) {
            return;
        }
        
        // Use minified assets in production; fall back to originals if .min file missing (dev mode)
        $min = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
        $min_css = file_exists( SBS_PLUGIN_DIR . 'assets/css/frontend.min.css' ) ? $min : '';
        $min_js  = file_exists( SBS_PLUGIN_DIR . 'assets/js/frontend.min.js'  ) ? $min : '';

        $frontend_css_file = SBS_PLUGIN_DIR . 'assets/css/frontend' . $min_css . '.css';
        $frontend_js_file  = SBS_PLUGIN_DIR . 'assets/js/frontend' . $min_js . '.js';
        $apple_polish_file = SBS_PLUGIN_DIR . 'assets/css/apple-polish' . YATOON_ASSET_SUFFIX . '.css';
        $ui_polish_file    = SBS_PLUGIN_DIR . 'assets/css/yatoon-ui-polish' . YATOON_ASSET_SUFFIX . '.css';
        $frontend_css_ver  = file_exists($frontend_css_file) ? SBS_VERSION . '.' . filemtime($frontend_css_file) : SBS_VERSION;
        $frontend_js_ver   = file_exists($frontend_js_file) ? SBS_VERSION . '.' . filemtime($frontend_js_file) : SBS_VERSION;
        $apple_polish_ver  = file_exists($apple_polish_file) ? SBS_VERSION . '.' . filemtime($apple_polish_file) : SBS_VERSION;
        $ui_polish_ver     = file_exists($ui_polish_file) ? SBS_VERSION . '.' . filemtime($ui_polish_file) : SBS_VERSION;

        wp_enqueue_style('sbs-frontend-css', SBS_PLUGIN_URL . 'assets/css/frontend' . $min_css . '.css', array(), $frontend_css_ver);
        wp_enqueue_style('yatoon-apple-polish', SBS_PLUGIN_URL . 'assets/css/apple-polish' . YATOON_ASSET_SUFFIX . '.css', array('sbs-frontend-css'), $apple_polish_ver);
        wp_enqueue_style('yatoon-ui-polish', SBS_PLUGIN_URL . 'assets/css/yatoon-ui-polish' . YATOON_ASSET_SUFFIX . '.css', array('yatoon-apple-polish'), $ui_polish_ver);
        wp_add_inline_style('yatoon-apple-polish', yatoon_apple_polish_inline_css());
        wp_enqueue_script('sbs-frontend-js', SBS_PLUGIN_URL . 'assets/js/frontend' . $min_js . '.js', array('jquery'), $frontend_js_ver, true);
        // Cloudflare Turnstile's remote script is not enqueued in the free
        // WordPress.org-safe package; remote offloaded scripts fail plugin checks.

        // External phone assets are intentionally not loaded in this build.
        // Inject brand CSS variables
        $primary        = get_option('yatoon_primary_color',      '#ec4899');
        $price_color    = get_option('yatoon_price_color',        '#ec4899');
        $banner_bg      = get_option('yatoon_banner_bg_color',    '#fdf2f8');
        $banner_text    = get_option('yatoon_banner_text_color',  '#9d174d');
        $banner_btn     = get_option('yatoon_banner_btn_color',   '#ec4899');
        $textus_bg      = get_option('yatoon_textus_bg_color',    '#ec4899');
        $textus_text    = get_option('yatoon_textus_text_color',  '#ffffff');
        $secondary      = get_option('yatoon_secondary_color',    '#f9a8d4');
        $text           = get_option('yatoon_text_color',         '#1a1a1a');
        $accent         = get_option('yatoon_accent_color',       '#000000');
        $plugin_bg      = sanitize_hex_color(get_option('yatoon_plugin_page_bg_color', '#f5f5f7')) ?: '#f5f5f7';
        $plugin_card_bg = sanitize_hex_color(get_option('yatoon_plugin_card_bg_color', '#ffffff')) ?: '#ffffff';
        $readmore_color = get_option('sbs_readmore_color', get_option('yatoon_readmore_color', '#16a34a'));
        $btn_r          = intval(get_option('yatoon_button_radius', 8));
        $card_r         = intval(get_option('yatoon_card_radius',   12));
        $font           = get_option('yatoon_font_family',        'system');
        $heading_font   = get_option('sbs_heading_font', get_option('yatoon_heading_font', 'bebas'));
        $heading_color  = get_option('sbs_heading_color', get_option('yatoon_heading_color', '#ec4899'));
        $heading_size   = intval(get_option('sbs_heading_size', get_option('yatoon_heading_size', 32)));
        $main_title_sz  = intval(get_option('sbs_main_title_size', get_option('yatoon_main_title_size', 34)));
        $cat_tab_sz     = (float) get_option('sbs_cat_tab_size', get_option('yatoon_cat_tab_size', 15));
        $cat_tab_sz     = max(8, min(28, $cat_tab_sz));
        $cat_tab_mobile_sz = max(8, min(12, $cat_tab_sz));
        $booking_template = sanitize_key((string) get_option('yatoon_booking_template', 'beauty'));
        $template_palettes = array(
            'beauty' => array('#db2777', '#be185d', '#fce7f3', '#1a1a1a', '#db2777', '#db2777'),
            'clean'  => array('#2563eb', '#1d4ed8', '#eff6ff', '#111827', '#2563eb', '#111827'),
            'luxury' => array('#92722a', '#78591e', '#fdf8ee', '#1a1109', '#92722a', '#92722a'),
        );
        if (isset($template_palettes[$booking_template])) {
            list($primary, $secondary, $banner_bg, $text, $price_color, $heading_color) = $template_palettes[$booking_template];
            $banner_text    = $booking_template === 'luxury' ? '#5c4414' : ($booking_template === 'clean' ? '#1e40af' : '#9d174d');
            $banner_btn     = $primary;
            $textus_bg      = $primary;
            $readmore_color = get_option('sbs_readmore_color', get_option('yatoon_readmore_color', $primary));
            $heading_color  = get_option('sbs_heading_color', get_option('yatoon_heading_color', $heading_color));
        }

        // -- Button fonts (per-button, falls back to shared sbs_btn_font) --------
        $btn_font_key        = get_option('yatoon_btn_font',          'system');
        $add_btn_font_key    = get_option('yatoon_add_btn_font',      $btn_font_key);
        $back_btn_font_key   = get_option('yatoon_back_btn_font',     $btn_font_key);
        $cont_btn_font_key   = get_option('sbs_continue_btn_font', $btn_font_key);
        $more_btn_font_key   = get_option('sbs_addmore_btn_font',  $btn_font_key);
        $more2_btn_font_key  = get_option('sbs_addmore2_btn_font', $btn_font_key);
        $more3_btn_font_key  = get_option('sbs_addmore3_btn_font', $btn_font_key);
        $conf_btn_font_key   = get_option('sbs_confirm_btn_font',  $btn_font_key);

        // -- Per-button settings ----------------------------------------------
        $add_btn_label    = get_option('yatoon_add_btn_label',          'Add');
        $add_btn_size     = intval(get_option('yatoon_add_btn_size',    14));
        $add_btn_color    = get_option('yatoon_add_btn_text_color',     '#ffffff');
        $add_btn_bg       = get_option('yatoon_add_btn_bg_color',       '#ec4899');

        $back_btn_label   = get_option('yatoon_back_btn_label',         'Back');
        $back_btn_size    = intval(get_option('yatoon_back_btn_size',   14));
        $back_btn_color   = get_option('yatoon_back_btn_text_color',    '#374151');
        $back_btn_bg      = get_option('yatoon_back_btn_bg_color',      '#f3f4f6');

        $cont_btn_label   = get_option('sbs_continue_btn_label',     'Continue');
        $cont_btn_size    = intval(get_option('sbs_continue_btn_size', 15));
        $cont_btn_color   = get_option('sbs_continue_btn_text_color', '#ffffff');
        $cont_btn_bg      = get_option('sbs_continue_btn_bg_color',   '#008a00');

        $more_btn_label   = get_option('sbs_addmore_btn_label',      'Add Another Appointment');
        $more_btn_size    = intval(get_option('sbs_addmore_btn_size', 14));
        $more_btn_color   = get_option('sbs_addmore_btn_text_color',  '#ffffff');
        $more_btn_bg      = get_option('sbs_addmore_btn_bg_color',    '#ec4899');

        $more2_btn_label  = get_option('sbs_addmore2_btn_label',      '+ Add More Services');
        $more2_btn_size   = intval(get_option('sbs_addmore2_btn_size', 16));
        $more2_btn_color  = get_option('sbs_addmore2_btn_text_color',  '#ffffff');
        $more2_btn_bg     = get_option('sbs_addmore2_btn_bg_color',    '#e00000');

        $more3_btn_label  = get_option('sbs_addmore3_btn_label',      '+ Add More Services');
        $more3_btn_size   = intval(get_option('sbs_addmore3_btn_size', 13));
        $more3_btn_color  = get_option('sbs_addmore3_btn_text_color',  '#ffffff');
        $more3_btn_bg     = get_option('sbs_addmore3_btn_bg_color',    '#e00000');

        $add_for_person_btn_label  = get_option('sbs_add_for_person_btn_label',      '+ Add Service for');
        $add_for_person_btn_size   = intval(get_option('sbs_add_for_person_btn_size', 12));
        $add_for_person_btn_color  = get_option('sbs_add_for_person_btn_text_color',  '#ffffff');
        $add_for_person_btn_bg     = get_option('sbs_add_for_person_btn_bg_color',    '#16a34a');
        $add_for_person_btn_radius = intval(get_option('sbs_add_for_person_btn_radius', 20));

        $add_guest_btn_label  = get_option('sbs_add_guest_btn_label',      '+ Add Guest Together');
        if (trim($add_guest_btn_label) === '+ Add Guest') {
            $add_guest_btn_label = '+ Add Guest Together';
        }
        $add_guest_btn_size   = intval(get_option('sbs_add_guest_btn_size', 12));
        $add_guest_btn_color  = get_option('sbs_add_guest_btn_text_color',  '#16a34a');
        $add_guest_btn_bg     = get_option('sbs_add_guest_btn_bg_color',    '#f0fdf4');
        $add_guest_btn_radius = intval(get_option('sbs_add_guest_btn_radius', 20));
        $max_guests_together  = max(0, min(10, intval(get_option('yatoon_max_guests_together', 2))));

        $conf_btn_label   = get_option('sbs_confirm_btn_label',      'Confirm All Bookings');
        $conf_btn_size    = intval(get_option('sbs_confirm_btn_size', 15));
        $conf_btn_color   = get_option('sbs_confirm_btn_text_color',  '#ffffff');
        $conf_btn_bg      = get_option('sbs_confirm_btn_bg_color',    '#16a34a');

        $conf_single_btn_label = get_option('sbs_confirm_single_btn_label', 'Confirm Booking');
        $conf_single_btn_size  = intval(get_option('sbs_confirm_single_btn_size', 15));
        $conf_single_btn_color = get_option('sbs_confirm_single_btn_text_color',  '#ffffff');
        $conf_single_btn_bg    = get_option('sbs_confirm_single_btn_bg_color',    '#16a34a');

        // Per-button border radius
        $add_btn_radius          = intval(get_option('yatoon_add_btn_radius',          20));
        $back_btn_radius         = intval(get_option('yatoon_back_btn_radius',         20));
        $cont_btn_radius         = intval(get_option('sbs_continue_btn_radius',     20));
        $more_btn_radius         = intval(get_option('sbs_addmore_btn_radius',      20));
        $more2_btn_radius        = intval(get_option('sbs_addmore2_btn_radius',     20));
        $more3_btn_radius        = intval(get_option('sbs_addmore3_btn_radius',     20));
        $conf_btn_radius         = intval(get_option('sbs_confirm_btn_radius',      20));
        $conf_single_btn_radius  = intval(get_option('sbs_confirm_single_btn_radius', 20));

        // -- Google Fonts map (body + heading + button) -----------------------
        $all_gfonts = array(
            'system'       => array(null,                null),
            'inter'        => array('Inter',             'Inter:wght@400;500;600;700'),
            'poppins'      => array('Poppins',           'Poppins:wght@400;500;600;700'),
            'roboto'       => array('Roboto',            'Roboto:wght@400;500;700'),
            'montserrat'   => array('Montserrat',        'Montserrat:wght@400;500;600;700'),
            'lato'         => array('Lato',              'Lato:wght@400;700'),
            'playfair'     => array('Playfair Display',  'Playfair+Display:wght@400;700'),
            'bebas'        => array('Bebas Neue',        'Bebas+Neue'),
            'anton'        => array('Anton',             'Anton'),
            'black_han'    => array('Black Han Sans',    'Black+Han+Sans'),
            'boogaloo'     => array('Boogaloo',          'Boogaloo'),
            'archivo_black'=> array('Archivo Black',     'Archivo+Black'),
            'oswald'       => array('Oswald',            'Oswald:wght@400;600;700'),
            'exo'          => array('Exo 2',             'Exo+2:wght@400;700;900'),
            'playfair_h'   => array('Playfair Display',  'Playfair+Display:wght@700;900'),
            'nunito'       => array('Nunito',            'Nunito:wght@400;600;700'),
            'raleway'      => array('Raleway',           'Raleway:wght@400;600;700'),
            'ubuntu'       => array('Ubuntu',            'Ubuntu:wght@400;500;700'),
        );

        // Body font
        $font_stack  = 'system-ui, -apple-system, sans-serif';
        $font_import = '';
        $load_google_fonts = get_option('yatoon_load_google_fonts', '1') === '1';
        if ($load_google_fonts && isset($all_gfonts[$font]) && $all_gfonts[$font][0]) {
            $font_stack  = "'" . $all_gfonts[$font][0] . "', sans-serif";
            $font_import = "@import url('https://fonts.googleapis.com/css2?family=" . $all_gfonts[$font][1] . "&display=swap');";
        }

        // Heading font
        $hfont_stack  = "'Bebas Neue', sans-serif";
        $hfont_import = $load_google_fonts ? "@import url('https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap');" : '';
        if (isset($all_gfonts[$heading_font])) {
            if ($load_google_fonts && $all_gfonts[$heading_font][0]) {
                $hfont_stack  = "'" . $all_gfonts[$heading_font][0] . "', sans-serif";
                $hfont_import = "@import url('https://fonts.googleapis.com/css2?family=" . $all_gfonts[$heading_font][1] . "&display=swap');";
            } else {
                $hfont_stack  = 'system-ui, -apple-system, sans-serif';
                $hfont_import = '';
            }
        }

        // -- Resolve font stack for each button separately -------------------
        function yatoon_resolve_font($key, &$all_gfonts, $load_google_fonts = true) {
            if ($load_google_fonts && isset($all_gfonts[$key]) && $all_gfonts[$key][0]) {
                return array(
                    "'" . $all_gfonts[$key][0] . "', sans-serif",
                    "@import url('https://fonts.googleapis.com/css2?family=" . $all_gfonts[$key][1] . "&display=swap');"
                );
            }
            return array('inherit', '');
        }
        list($add_btn_font_stack,  $add_btn_font_import)  = yatoon_resolve_font($add_btn_font_key,  $all_gfonts, $load_google_fonts);
        list($back_btn_font_stack, $back_btn_font_import) = yatoon_resolve_font($back_btn_font_key, $all_gfonts, $load_google_fonts);
        list($cont_btn_font_stack, $cont_btn_font_import) = yatoon_resolve_font($cont_btn_font_key, $all_gfonts, $load_google_fonts);
        list($more_btn_font_stack, $more_btn_font_import) = yatoon_resolve_font($more_btn_font_key, $all_gfonts, $load_google_fonts);
        list($more2_btn_font_stack, $more2_btn_font_import) = yatoon_resolve_font($more2_btn_font_key, $all_gfonts, $load_google_fonts);
        list($more3_btn_font_stack, $more3_btn_font_import) = yatoon_resolve_font($more3_btn_font_key, $all_gfonts, $load_google_fonts);
        list($conf_btn_font_stack, $conf_btn_font_import) = yatoon_resolve_font($conf_btn_font_key, $all_gfonts, $load_google_fonts);

        // Collect imports (deduplicate)
        $imports = array_unique(array_filter([
            $font_import, $hfont_import,
            $add_btn_font_import, $back_btn_font_import,
            $cont_btn_font_import, $more_btn_font_import, $more2_btn_font_import, $more3_btn_font_import, $conf_btn_font_import,
        ]));
        $all_imports = implode("\n        ", $imports);

        $custom_css = "
        {$all_imports}
        :root {
            --sbs-primary:          {$primary};
            --sbs-secondary:        {$secondary};
            --sbs-text:             {$text};
            --sbs-accent:           {$accent};
            --sbs-plugin-bg:        {$plugin_bg};
            --sbs-plugin-card-bg:   {$plugin_card_bg};
            --sbs-readmore:         {$readmore_color};
            --sbs-btn-radius:       {$btn_r}px;
            --sbs-card-radius:      {$card_r}px;
            --sbs-font:             {$font_stack};
            --sbs-hfont:            {$hfont_stack};
            --sbs-heading-color:    {$heading_color};
            --sbs-heading-size:     {$heading_size}px;
            --sbs-main-title-sz:    {$main_title_sz}px;
            --sbs-cat-tab-sz:       clamp(8px, calc(-7.35px + 4.5vw), {$cat_tab_sz}px);
            --sbs-price-color:      {$price_color};
            --sbs-banner-bg:        {$banner_bg};
            --sbs-banner-text:      {$banner_text};
            --sbs-banner-btn:       {$banner_btn};
            --sbs-textus-bg:        {$textus_bg};
            --sbs-textus-text:      {$textus_text};
        }
        .sbs-booking-container { font-family: var(--sbs-font); color: var(--sbs-text); }
        /* Price color */
        .sbs-service-price, .sbs-option-price { color: var(--sbs-price-color) !important; }
        /* Text Us button */
        #sbs-text-us-btn { background: var(--sbs-textus-bg) !important; color: var(--sbs-textus-text) !important; box-shadow: 0 4px 16px color-mix(in srgb, var(--sbs-textus-bg) 40%, transparent) !important; }
        .sbs-service-item.selected, .sbs-option-item.selected { border-color: var(--sbs-primary); }
        .sbs-prog-step.active { background: var(--sbs-primary); }
        .sbs-cart-bar { border-top: 3px solid var(--sbs-primary); }

        /* Category section titles */
        .sbs-category-title {
            font-family: var(--sbs-hfont) !important;
            color: var(--sbs-heading-color) !important;
            font-size: var(--sbs-heading-size) !important;
            font-weight: 900 !important;
            letter-spacing: .03em;
            text-shadow: 2px 2px 0px rgba(0,0,0,.12), 3px 3px 6px rgba(0,0,0,.10);
        }
        /* Book Your Appointment main title */
        .sbs-page-title, #sbs-main-title, #sbs-add-more-title {
            font-size: var(--sbs-main-title-sz) !important;
            font-weight: 800 !important;
        }
        /* Category tabs */
        .sbs-cat-tab {
            font-size: var(--sbs-cat-tab-sz);
            font-weight: 600 !important;
        }
        @media (max-width: 782px) {
            .sbs-category-tabs-wrap,
            body.sbs-booking-immersive .sbs-category-tabs-wrap {
                position: static !important;
                top: auto !important;
                z-index: auto !important;
                margin: 0 0 16px !important;
                padding: 0 0 8px !important;
                overflow: visible !important;
                background: transparent !important;
                backdrop-filter: none !important;
            }
            .sbs-category-tabs,
            body.sbs-booking-immersive .sbs-category-tabs {
                display: flex !important;
                gap: 7px !important;
                max-width: 100% !important;
                padding: 0 2px 4px !important;
                overflow-x: auto !important;
                overflow-y: hidden !important;
                scroll-padding-left: 2px !important;
                -webkit-overflow-scrolling: touch;
            }
            .sbs-cat-tab,
            .sbs-category-tab,
            body.sbs-booking-immersive .sbs-cat-tab {
                flex: 0 0 auto !important;
                min-height: 36px !important;
                max-width: 142px !important;
                padding: 8px 10px !important;
                font-size: {$cat_tab_mobile_sz}px !important;
                line-height: 1.05 !important;
                letter-spacing: 0 !important;
                white-space: nowrap !important;
                overflow: hidden !important;
                text-overflow: ellipsis !important;
            }
            .sbs-cat-tab.active,
            .sbs-category-tab.active,
            body.sbs-booking-immersive .sbs-cat-tab.active {
                max-width: 156px !important;
            }
            .sbs-cat-more-btn,
            #sbs-cat-more-btn,
            body.sbs-booking-immersive #sbs-cat-more-btn {
                max-width: 94px !important;
            }
        }
        /* ADD / service button */
        .sbs-book-btn {
            background: {$add_btn_bg} !important;
            color: {$add_btn_color} !important;
            font-size: {$add_btn_size}px !important;
            font-family: {$add_btn_font_stack} !important;
            border-radius: {$add_btn_radius}px !important;
        }
        /* Back button */
        .sbs-btn-back {
            background: {$back_btn_bg} !important;
            color: {$back_btn_color} !important;
            font-size: {$back_btn_size}px !important;
            font-family: {$back_btn_font_stack} !important;
            border-radius: {$back_btn_radius}px !important;
        }
        /* Continue button */
        .sbs-btn-next {
            background: {$cont_btn_bg} !important;
            color: {$cont_btn_color} !important;
            font-size: {$cont_btn_size}px !important;
            font-family: {$cont_btn_font_stack} !important;
            border-radius: {$cont_btn_radius}px !important;
        }
        /* Add More Services button (Step 5 Review page) */
        .sbs-btn-add-more {
            background: {$more_btn_bg} !important;
            color: {$more_btn_color} !important;
            font-size: {$more_btn_size}px !important;
            font-family: {$more_btn_font_stack} !important;
            border-radius: {$more_btn_radius}px !important;
            flex: 0 0 auto !important;
        }
        /* Add More Services - calendar bottom nav bar (next to Back)*/
        .sbs-navigation-buttons .sbs-btn-add-more-calendar {
            background: {$more2_btn_bg} !important;
            color: {$more2_btn_color} !important;
            font-size: {$more2_btn_size}px !important;
            font-family: {$more2_btn_font_stack} !important;
            border-radius: {$more2_btn_radius}px !important;
            flex: 1 !important;
        }
        /* Add More Services - calendar top green banner right button */
        #sbs-pending-services-banner .sbs-btn-add-more-banner {
            background: {$more3_btn_bg} !important;
            color: {$more3_btn_color} !important;
            font-size: {$more3_btn_size}px !important;
            font-family: {$more3_btn_font_stack} !important;
            border-radius: {$more3_btn_radius}px !important;
            flex: 0 0 auto !important;
            padding: 6px 14px !important;
        }
        /* Add Service for Person buttons */
        #sbs-pending-services-banner .sbs-add-service-for-person {
            background: {$add_for_person_btn_bg} !important;
            color: {$add_for_person_btn_color} !important;
            font-size: {$add_for_person_btn_size}px !important;
            border-radius: {$add_for_person_btn_radius}px !important;
            flex: 0 0 auto !important;
            padding: 6px 12px !important;
        }
        /* Add Guest button */
        #sbs-banner-add-guest {
            background: {$add_guest_btn_bg} !important;
            color: {$add_guest_btn_color} !important;
            font-size: {$add_guest_btn_size}px !important;
            border: 1.5px solid {$add_guest_btn_color} !important;
            border-radius: {$add_guest_btn_radius}px !important;
            flex: 0 0 auto !important;
            padding: 6px 12px !important;
        }
        /* Confirm / Submit button */
        .sbs-btn-submit {
            background: {$conf_btn_bg} !important;
            color: {$conf_btn_color} !important;
            font-size: {$conf_btn_size}px !important;
            font-family: {$conf_btn_font_stack} !important;
            border-radius: {$conf_btn_radius}px !important;
        }
        .sbs-btn-submit.sbs-btn-single {
            background: {$conf_single_btn_bg} !important;
            color: {$conf_single_btn_color} !important;
            font-size: {$conf_single_btn_size}px !important;
            border-radius: {$conf_single_btn_radius}px !important;
        }
        .sbs-btn-back:hover, .sbs-btn-next:hover, .sbs-btn-add-more:hover,
        .sbs-btn-add-more-calendar:hover, .sbs-btn-add-more-banner:hover,
        .sbs-btn-submit:hover, .sbs-book-btn:hover { filter: brightness(0.92); }
        ";

        wp_add_inline_style('sbs-frontend-css', $custom_css);

        // Button labels for JS rendering
        $btn_labels = array(
            'add'            => sanitize_text_field($add_btn_label)  ?: 'Add',
            'back'           => sanitize_text_field($back_btn_label) ?: 'Back',
            'cont'           => sanitize_text_field($cont_btn_label) ?: 'Continue',
            'more'           => sanitize_text_field($more_btn_label) ?: '+ Add More Services',
            'more2'          => sanitize_text_field($more2_btn_label) ?: '+ Add More Services',
            'more3'          => sanitize_text_field($more3_btn_label) ?: '+ Add More Services',
            'add_for_person' => sanitize_text_field($add_for_person_btn_label) ?: '+ Add Service for',
            'add_guest'      => sanitize_text_field($add_guest_btn_label) ?: '+ Add Guest Together',
            'confirm'        => sanitize_text_field($conf_btn_label) ?: 'Confirm All Bookings',
            'confirm_single' => sanitize_text_field($conf_single_btn_label) ?: 'Confirm Booking',
        );

        // Get logged-in user's display name/initial for the guest review screen
        $current_user      = wp_get_current_user();
        $client_name       = $current_user && $current_user->ID ? $current_user->display_name : '';
        $client_initial    = $client_name ? strtoupper( substr( $client_name, 0, 1 ) ) : 'Y';

        wp_localize_script('sbs-frontend-js', 'yatoonData', array(
            'ajax_url'          => admin_url('admin-ajax.php'),
            'nonce'             => wp_create_nonce('yatoon_frontend_nonce'),
            'turnstileEnabled'  => get_option('yatoon_turnstile_enabled', '0') === '1' && !empty(get_option('yatoon_turnstile_site_key')),
            'turnstileSiteKey'  => get_option('yatoon_turnstile_site_key', ''),
            'siteTimezone'      => wp_timezone()->getName(),
            'locationId'        => isset( $yatoon_location ) && $yatoon_location ? (string) $yatoon_location->id : '',
            'clientName'        => sanitize_text_field( $client_name ),
            'clientInitial'     => sanitize_text_field( $client_initial ),
            'btnLabels'         => $btn_labels,
            'portalUrl'         => esc_url_raw(get_option('yatoon_portal_url', '')),
            'portalLabel'       => sanitize_text_field(get_option('yatoon_portal_label', 'My Appointments')),
            'bookNewUrl'        => esc_url_raw(get_option('yatoon_book_new_url', '')),
            'headerOffset'      => intval(get_option('yatoon_header_offset', 0)),
            'multiApptEnabled'  => get_option('yatoon_multi_appointment', '1') === '1',
            'maxGuestsTogether' => $max_guests_together,
            'immersiveMode'     => get_option('yatoon_booking_immersive_mode', '1') === '1',
            'serviceOptions'     => $this->get_preloaded_service_options(),
            'serviceStaff'       => $this->get_preloaded_service_staff(),
            'bookingLabels'       => array(
                'servicePopular'    => sanitize_text_field(get_option('yatoon_service_popular_label', 'Popular')),
                'customizeKicker'   => sanitize_text_field(get_option('yatoon_option_customize_kicker', 'Customize your service')),
                'relatedEyebrow'    => sanitize_text_field(get_option('yatoon_option_related_eyebrow', 'Related choices')),
                'relatedTitle'      => sanitize_text_field(get_option('yatoon_option_related_title', 'Choose what fits your visit')),
                'relatedHint'       => sanitize_text_field(get_option('yatoon_option_related_hint', 'Tap to select')),
                'mainGroupLabel'    => sanitize_text_field(get_option('yatoon_option_main_group_label', 'Choose one option')),
                'mainGroupHelp'     => sanitize_text_field(get_option('yatoon_option_main_group_help', 'Pick the main style or variation for this service.')),
                'addonGroupLabel'   => sanitize_text_field(get_option('yatoon_option_addon_group_label', 'Recommended add-ons')),
                'addonGroupHelp'    => sanitize_text_field(get_option('yatoon_option_addon_group_help', 'Optional extras you can add to this appointment.')),
                'recommendedBadge'  => sanitize_text_field(get_option('yatoon_option_recommended_badge_label', 'Recommended')),
                'popularBadge'      => sanitize_text_field(get_option('yatoon_option_popular_badge_label', 'Popular')),
                'addonBadge'        => sanitize_text_field(get_option('yatoon_option_addon_badge_label', 'Add-on')),
            ),
            'policyEnabled'     => get_option('yatoon_policy_enabled', '0') === '1',
            'policyRequireAck'  => get_option('yatoon_policy_require_ack', '1') === '1',
            'consentEnabled'    => get_option('yatoon_consent_enabled', '0') === '1',
            'couponsEnabled'    => yatoon_is_pro() && get_option('yatoon_enable_coupons', '0') === '1',
            'depositEnabled'    => yatoon_is_pro() && get_option('yatoon_deposit_enabled', '0') === '1'
                                   && !empty(get_option('yatoon_deposit_stripe_key', ''))
                                   && !empty(YATOON_Crypto::get_option('yatoon_deposit_stripe_secret', '')),
            'squarePaymentsEnabled' => yatoon_is_pro()
                                   && class_exists('Yatoon_Square_Payments')
                                   && Yatoon_Square_Payments::is_enabled(),
            'squarePaymentMode'  => class_exists('Yatoon_Square_Payments') ? Yatoon_Square_Payments::payment_mode() : 'deposit',
            'squarePaymentMethods' => class_exists('Yatoon_Square_Payments') ? Yatoon_Square_Payments::enabled_methods() : array('card'),
            'squareApplicationId'=> sanitize_text_field(get_option('yatoon_square_application_id', '')),
            'squareLocationId'   => sanitize_text_field(get_option('yatoon_square_location_id', '')),
            'squareEnvironment'  => sanitize_key(get_option('yatoon_square_environment', 'production')),
            'squareCountryCode'  => strtoupper(sanitize_text_field(get_option('yatoon_square_country_code', 'US'))),
            'currency'           => strtoupper(sanitize_text_field(get_option('yatoon_currency', 'USD'))),
            'waitlistEnabled'   => get_option('yatoon_waitlist_enabled', '1') === '1',
            'ajaxUrl'           => admin_url('admin-ajax.php'),
            'verifyEmailOtp'    => get_option('yatoon_verify_email_otp', '0'),
            'verifySmsOtp'      => get_option('yatoon_verify_sms_otp', '0'),
            'phoneMode'         => get_option('yatoon_phone_mode', 'us_only'),
            'useIpGeo'          => get_option('yatoon_use_ip_geo_phone_detect', '0') === '1',
            'textUsEnabled'     => get_option('yatoon_text_us_enabled', '1') === '1',
            'whatsappEnabled'   => get_option('yatoon_whatsapp_enabled', '0') === '1',
            'whatsappNumber'    => preg_replace('/[^0-9]/', '', get_option('yatoon_whatsapp_number', get_option('yatoon_business_phone', ''))),
            'whatsappLabel'     => sanitize_text_field(get_option('yatoon_whatsapp_label', 'Message us on WhatsApp')),
            'successNote'       => sanitize_text_field(get_option('yatoon_success_action_note', 'Your booking is confirmed. You can add it to your calendar, manage changes, or book another visit.')),
            'rebookingNudgeText'=> sanitize_text_field(get_option('yatoon_rebooking_nudge_text', 'Most clients rebook every 2-3 weeks. Want us to remind you?')),
            'rebookingNudgeBtn' => sanitize_text_field(get_option('yatoon_rebooking_nudge_btn', 'Book next visit')),
            'availabilityHelp'  => sanitize_text_field(get_option('yatoon_availability_help_text', 'Try another date, choose another staff member, or text us and we can help.')),
            'ai'                => array(
                'serviceHelperEnabled' => get_option('yatoon_ai_service_helper_enabled', '1') === '1',
                'available'             => class_exists('YATOON_AI') && YATOON_AI::is_text_available(),
                'status'                => class_exists('YATOON_AI') ? YATOON_AI::status_message() : __('AI requires WordPress 7.0 or newer.', 'yatoon-booking-system'),
                'isPro'                 => yatoon_is_pro(),
            ),
            'strings'    => array(
                'select_service'   => __('Select a service', 'yatoon-booking-system'),
                'select_options'   => __('Select options', 'yatoon-booking-system'),
                'select_staff'     => __('Select staff member', 'yatoon-booking-system'),
                'select_date_time' => __('Select date & time', 'yatoon-booking-system'),
                'your_information' => __('Your information', 'yatoon-booking-system'),
                'confirm_booking'  => __('Confirm booking', 'yatoon-booking-system'),
                'booking_success'  => __('Booking confirmed!', 'yatoon-booking-system'),
                'booking_error'    => __('Booking failed. Please try again.', 'yatoon-booking-system'),
                'read_more'        => __('Read more', 'yatoon-booking-system'),
                'show_less'        => __('Show less', 'yatoon-booking-system'),
                'rating'           => __('Rating', 'yatoon-booking-system'),
                'checking_availability' => __('Checking availability...', 'yatoon-booking-system'),
            )
        ));

        // Load Stripe.js only when deposit is enabled (Pro)
        $deposit_active = yatoon_is_pro()
                          && get_option('yatoon_deposit_enabled', '0') === '1'
                          && !empty(get_option('yatoon_deposit_stripe_key', ''))
                          && !empty(YATOON_Crypto::get_option('yatoon_deposit_stripe_secret', ''));
        if ($deposit_active) {
            wp_enqueue_script('stripe-js', 'https://js.stripe.com/v3/', array(), null, true);
        }
        $square_payments_active = yatoon_is_pro()
                                  && class_exists('Yatoon_Square_Payments')
                                  && Yatoon_Square_Payments::is_enabled();
        if ($square_payments_active) {
            $square_sdk = get_option('yatoon_square_environment', 'production') === 'sandbox'
                ? 'https://sandbox.web.squarecdn.com/v1/square.js'
                : 'https://web.squarecdn.com/v1/square.js';
            wp_enqueue_script('yatoon-square-web-payments', $square_sdk, array(), null, true);
        }
    }
    
    /**
     * Booking shortcode
     */
    public function booking_shortcode($atts) {
        yatoon_record_onboarding_milestone( 'booking_page_opened' );
        $atts = shortcode_atts(array(
            'location_id' => '',
        ), $atts);
        
        ob_start();
        $this->render_booking_form($atts);
        return ob_get_clean();
    }

    public function catalog_shortcode($atts) {
        $atts = shortcode_atts(array(
            'category' => '',
            'limit'    => 50,
            'cols'     => get_option('yatoon_catalog_cols', 3),
        ), $atts);
        ob_start();
        include SBS_PLUGIN_DIR . 'public/views/catalog.php';
        return ob_get_clean();
    }

    public function gallery_shortcode($atts) {
        $atts = shortcode_atts(array(
            'service_id' => 0,
            'category'   => '',
            'limit'      => 50,
            'mode'       => get_option('yatoon_gallery_mode', 'grid'),
            'cols'       => get_option('yatoon_gallery_cols', 5),
            'gap'        => get_option('yatoon_gallery_gap', 6),
            'ratio'      => get_option('yatoon_gallery_ratio', '1/1'),
            'lightbox'   => get_option('yatoon_gallery_lightbox', '1'),
            'autoplay'   => get_option('yatoon_gallery_autoplay', '1'),
            'interval'   => get_option('yatoon_gallery_interval', 3500),
            'captions'   => get_option('yatoon_gallery_captions', '0'),
            'dots'       => '1',
            'arrows'     => '1',
            'height'     => get_option('yatoon_gallery_height', '460px'),
            'mobile_height' => '',
            'book_label' => get_option('yatoon_gallery_book_label', get_option('yatoon_catalog_book_label', 'Book Now')),
        ), $atts);
        ob_start();
        include SBS_PLUGIN_DIR . 'public/views/gallery.php';
        return ob_get_clean();
    }
    
    /**
     * Render booking form
     */
    private function render_booking_form($atts) {
        global $wpdb;

        // -- Resolve location --------------------------------------------------
        $yatoon_location = null;
        if ( get_option( 'yatoon_multi_location_enabled', '0' ) === '1' && class_exists( 'YATOON_Locations' ) ) {
            $loc_attr        = isset( $atts['location_id'] ) ? $atts['location_id'] : '';
            $yatoon_location = YATOON_Locations::resolve( $loc_attr );
        }

        // Get service list
        $table_services = $wpdb->prefix . 'yatoon_services';
        // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
        $services = $wpdb->get_results("
            SELECT * FROM $table_services
            WHERE is_active = 1
            ORDER BY sort_order ASC, name ASC
        ");
        
        // Use Square-style form
        include SBS_PLUGIN_DIR . 'public/views/booking-form-square.php';
    }
}
