<?php
/**
 * Flavor – Restaurant Menu
 *
 * Shortcode [flavor_menu] — Free version (Card Grid layout, Elegant Dark theme).
 * All other layouts and themes are available in Flavor Pro.
 *
 * @package    FlavorMenu
 * @copyright  Copyright (c) 2024 Flavor Studio
 * @license    GPL-2.0-or-later
 * @link       https://flavor-menu.com
 */

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

class Flavor_Shortcode {

    public static function init() {
        add_shortcode( 'flavor_menu', array( __CLASS__, 'render' ) );
    }

    // ── Layout / Style registry ─────────────────────────────────────────────────

    public static function get_layout_options() {
        return array(
            'card-grid' => __( 'Card Grid', 'flavor-restaurant-menu' ),
        );
    }

    public static function get_style_options() {
        return array(
            'dark' => __( 'Elegant Dark', 'flavor-restaurant-menu' ),
        );
    }

    // ── Shared helpers ──────────────────────────────────────────────────────────

    /**
     * Build a structured category tree for category-aware layouts.
     * Returns array of sections:
     *   [ 'term' => WP_Term, 'posts' => [id,...], 'children' => [ ['term'=>WP_Term, 'posts'=>[id,...]], ... ] ]
     */
    private static function build_category_tree( $parent_cats, $child_cats, $posts_by_term ) {
        $sections = array();
        foreach ( $parent_cats as $pid => $pterm ) {
            $child_term_ids = array();
            foreach ( $child_cats[ $pid ] as $cterm ) {
                $child_term_ids[] = $cterm->term_id;
            }

            // Posts directly in parent but not in any child
            $direct_posts = array();
            if ( isset( $posts_by_term[ $pid ] ) ) {
                foreach ( $posts_by_term[ $pid ] as $dp_id ) {
                    $dp_terms = get_the_terms( $dp_id, 'flavor_menu_cat' );
                    $in_child = false;
                    if ( $dp_terms && ! is_wp_error( $dp_terms ) ) {
                        foreach ( $dp_terms as $dpt ) {
                            if ( in_array( $dpt->term_id, $child_term_ids, true ) ) {
                                $in_child = true;
                                break;
                            }
                        }
                    }
                    if ( ! $in_child ) {
                        $direct_posts[] = $dp_id;
                    }
                }
            }

            // Child sections
            $children_data = array();
            foreach ( $child_cats[ $pid ] as $cterm ) {
                $cp_ids = isset( $posts_by_term[ $cterm->term_id ] ) ? $posts_by_term[ $cterm->term_id ] : array();
                if ( ! empty( $cp_ids ) ) {
                    $children_data[] = array( 'term' => $cterm, 'posts' => $cp_ids );
                }
            }

            if ( ! empty( $direct_posts ) || ! empty( $children_data ) ) {
                $sections[] = array(
                    'term'     => $pterm,
                    'posts'    => $direct_posts,
                    'children' => $children_data,
                );
            }
        }
        return $sections;
    }

    /**
     * Output the header block (title + ornament + description).
     */
    private static function render_header( $atts ) {
        if ( empty( $atts['title'] ) && empty( $atts['description'] ) ) {
            return;
        }
        ?>
        <div class="flavor-menu__header">
            <?php if ( ! empty( $atts['title'] ) ) : ?>
                <h2 class="flavor-menu__title"><?php echo esc_html( $atts['title'] ); ?></h2>
                <div class="flavor-menu__title-ornament"><span></span><span></span><span></span></div>
            <?php endif; ?>
            <?php if ( ! empty( $atts['description'] ) ) : ?>
                <p class="flavor-menu__desc"><?php echo esc_html( $atts['description'] ); ?></p>
            <?php endif; ?>
        </div>
        <?php
    }

    // ── Layout: Card Grid ───────────────────────────────────────────────────────

    /**
     * Render a single card's inner content.
     */
    private static function render_card_inner( $post_id, $atts, $ratio ) {
        $prices   = get_post_meta( $post_id, '_flavor_prices', true );
        $subtitle = get_post_meta( $post_id, '_flavor_subtitle', true );
        ?>
        <div class="flavor-menu__card-image flavor-ratio-<?php echo esc_attr( $ratio ); ?>">
            <?php if ( has_post_thumbnail( $post_id ) ) : ?>
                <?php echo get_the_post_thumbnail( $post_id, 'medium_large' ); ?>
            <?php else : ?>
                <div class="flavor-menu__card-placeholder">
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
                        <path d="M12 6v6l4 2M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0z"/>
                    </svg>
                </div>
            <?php endif; ?>
        </div>
        <div class="flavor-menu__card-body">
            <h3 class="flavor-menu__card-title"><?php echo esc_html( get_the_title( $post_id ) ); ?></h3>
            <?php if ( ! empty( $subtitle ) ) : ?>
                <p class="flavor-menu__card-subtitle"><?php echo esc_html( $subtitle ); ?></p>
            <?php endif; ?>
            <?php
            $post_obj = get_post( $post_id );
            $content  = $post_obj ? $post_obj->post_content : '';
            if ( ! empty( $content ) ) : ?>
                <div class="flavor-menu__card-desc"><?php echo wp_kses_post( wpautop( $content ) ); ?></div>
            <?php endif; ?>
            <?php if ( is_array( $prices ) && ! empty( $prices ) ) : ?>
                <div class="flavor-menu__card-prices">
                    <?php foreach ( $prices as $v ) : if ( empty( $v['price'] ) ) continue; ?>
                        <div class="flavor-menu__price-row">
                            <?php if ( ! empty( $v['label'] ) ) : ?>
                                <span class="flavor-menu__price-label"><?php echo esc_html( $v['label'] ); ?></span>
                            <?php endif; ?>
                            <span class="flavor-menu__price-dots"></span>
                            <span class="flavor-menu__price-value"><?php echo esc_html( $v['price'] ); ?> <?php echo esc_html( $atts['currency'] ); ?></span>
                        </div>
                    <?php endforeach; ?>
                </div>
            <?php endif; ?>
        </div>
        <?php
    }

    private static function render_layout_card_grid( $data, $atts ) {
        $items          = $data['items'];
        $parent_cats    = $data['parent_cats'];
        $child_cats     = $data['child_cats'];
        $posts_by_term  = $data['posts_by_term'];
        $terms_by_id    = $data['terms_by_id'];
        $hierarchy_data = $data['hierarchy_data'];

        $ratio       = sanitize_html_class( $atts['image_ratio'] );
        $hide_all    = ( 'yes' === $atts['hide_all_btn'] );
        $default_cat = sanitize_text_field( $atts['default_category'] );
        $parent_slugs = wp_list_pluck( $parent_cats, 'slug' );
        $has_default  = ! empty( $default_cat ) && in_array( $default_cat, $parent_slugs, true );

        if ( 'yes' === $atts['show_filter'] && count( $parent_cats ) > 1 ) : ?>
            <div class="flavor-menu__filters">
                <?php if ( ! $hide_all ) : ?>
                    <button class="flavor-filter-btn <?php echo ! $has_default ? 'is-active' : ''; ?>" data-filter="*">
                        <?php esc_html_e( 'All', 'flavor-restaurant-menu' ); ?>
                    </button>
                <?php endif; ?>
                <?php foreach ( $parent_cats as $pid => $pterm ) :
                    $is_default   = ( $has_default && $pterm->slug === $default_cat );
                    $has_children = ! empty( $child_cats[ $pid ] );
                ?>
                    <button class="flavor-filter-btn <?php echo $is_default ? 'is-active' : ''; ?>"
                            data-filter="<?php echo esc_attr( $pterm->slug ); ?>"
                            data-has-children="<?php echo $has_children ? '1' : '0'; ?>">
                        <?php echo esc_html( $pterm->name ); ?>
                    </button>
                <?php endforeach; ?>
            </div>
            <div class="flavor-menu__subnav" style="display:none;"></div>
        <?php endif;

        if ( $items->have_posts() ) : ?>
            <div class="flavor-menu__content">
                <div class="flavor-menu__grid flavor-menu__grid--flat">
                    <?php
                    $items->rewind_posts();
                    while ( $items->have_posts() ) : $items->the_post();
                        $pid2 = get_the_ID();
                        $t2   = get_the_terms( $pid2, 'flavor_menu_cat' );
                        $cs2  = array();
                        if ( $t2 && ! is_wp_error( $t2 ) ) {
                            foreach ( $t2 as $t ) {
                                $cs2[] = $t->slug;
                                if ( $t->parent > 0 && isset( $terms_by_id[ $t->parent ] ) ) {
                                    $cs2[] = $terms_by_id[ $t->parent ]->slug;
                                }
                            }
                        }
                    ?>
                        <div class="flavor-menu__card" data-categories="<?php echo esc_attr( implode( ' ', array_unique( $cs2 ) ) ); ?>">
                            <?php self::render_card_inner( $pid2, $atts, $ratio ); ?>
                        </div>
                    <?php endwhile; ?>
                </div>

                <?php foreach ( $parent_cats as $pid => $pterm ) :
                    if ( empty( $child_cats[ $pid ] ) ) continue;

                    $child_term_ids = array();
                    foreach ( $child_cats[ $pid ] as $cterm ) { $child_term_ids[] = $cterm->term_id; }

                    $direct_posts = array();
                    if ( isset( $posts_by_term[ $pid ] ) ) {
                        foreach ( $posts_by_term[ $pid ] as $dp_id ) {
                            $dp_terms = get_the_terms( $dp_id, 'flavor_menu_cat' );
                            $in_child = false;
                            if ( $dp_terms && ! is_wp_error( $dp_terms ) ) {
                                foreach ( $dp_terms as $dpt ) {
                                    if ( in_array( $dpt->term_id, $child_term_ids, true ) ) { $in_child = true; break; }
                                }
                            }
                            if ( ! $in_child ) { $direct_posts[] = $dp_id; }
                        }
                    }
                ?>
                    <div class="flavor-menu__sections" data-parent="<?php echo esc_attr( $pterm->slug ); ?>" style="display:none;">
                        <?php if ( ! empty( $direct_posts ) ) : ?>
                            <div class="flavor-menu__section">
                                <div class="flavor-menu__section-header">
                                    <h3 class="flavor-menu__section-title"><?php echo esc_html( $pterm->name ); ?></h3>
                                    <div class="flavor-menu__section-line"></div>
                                </div>
                                <div class="flavor-menu__grid">
                                    <?php foreach ( $direct_posts as $dp_id ) : ?>
                                        <div class="flavor-menu__card"><?php self::render_card_inner( $dp_id, $atts, $ratio ); ?></div>
                                    <?php endforeach; ?>
                                </div>
                            </div>
                        <?php endif; ?>

                        <?php foreach ( $child_cats[ $pid ] as $cterm ) :
                            $cp_ids = isset( $posts_by_term[ $cterm->term_id ] ) ? $posts_by_term[ $cterm->term_id ] : array();
                            if ( empty( $cp_ids ) ) continue;
                        ?>
                            <div class="flavor-menu__section" data-section="<?php echo esc_attr( $cterm->slug ); ?>">
                                <div class="flavor-menu__section-header">
                                    <h3 class="flavor-menu__section-title"><?php echo esc_html( $cterm->name ); ?></h3>
                                    <div class="flavor-menu__section-line"></div>
                                </div>
                                <div class="flavor-menu__grid">
                                    <?php foreach ( $cp_ids as $cp_id ) : ?>
                                        <div class="flavor-menu__card"><?php self::render_card_inner( $cp_id, $atts, $ratio ); ?></div>
                                    <?php endforeach; ?>
                                </div>
                            </div>
                        <?php endforeach; ?>
                    </div>
                <?php endforeach; ?>
            </div>
        <?php else : ?>
            <p class="flavor-menu__empty"><?php esc_html_e( 'No menu items found.', 'flavor-restaurant-menu' ); ?></p>
        <?php endif;
    }

    // ── Main render ─────────────────────────────────────────────────────────────

    public static function render( $atts ) {
        $atts = shortcode_atts( array(
            'title'            => 'Our Menu',
            'description'      => '',
            'category'         => '',
            'limit'            => 12,
            'columns'          => 3,
            'layout'           => 'card-grid',
            'style'            => 'dark',
            'image_ratio'      => '4-3',
            'show_filter'      => 'yes',
            'show_badges'      => 'yes',
            'hide_all_btn'     => '',
            'default_category' => '',
            'currency'         => '€',
            'el_class'         => '',
            'location'         => '',
        ), $atts, 'flavor_menu' );

        // Onboarding: remember that the menu has rendered on the front end at least once.
        if ( ! is_admin() && ! get_option( 'flavor_menu_rendered' ) ) {
            update_option( 'flavor_menu_rendered', 1 );
        }

        // Free version: always Card Grid + Elegant Dark, with the default
        // columns and image ratio (these are Pro-only controls).
        $atts['layout']      = 'card-grid';
        $atts['style']       = 'dark';
        $atts['columns']     = 3;
        $atts['image_ratio'] = '4-3';

        wp_enqueue_style( 'flavor-menu-style' );
        wp_enqueue_script( 'flavor-menu-script' );

        // ── Query ────────────────────────────────────────────────────────────────
        $query_args = array(
            'post_type'      => 'flavor_menu_item',
            'posts_per_page' => min( max( 1, intval( $atts['limit'] ) ), 200 ),
            'orderby'        => 'meta_value_num',
            'meta_key'       => '_flavor_sort_order', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Required for sort order; indexed in practice.
            'order'          => 'ASC',
            'post_status'    => 'publish',
        );

        $tax_query = array();
        if ( ! empty( $atts['category'] ) ) {
            $tax_query[] = array(
                'taxonomy' => 'flavor_menu_cat',
                'field'    => 'slug',
                'terms'    => array_map( 'trim', explode( ',', $atts['category'] ) ),
            );
        }
        if ( ! empty( $tax_query ) ) {
            $query_args['tax_query'] = $tax_query; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query -- Taxonomy filter is user-driven and intentional.
        }
        $items = new WP_Query( $query_args );

        // ── Build term maps ──────────────────────────────────────────────────────
        $item_term_ids = array();
        $posts_by_term = array();
        if ( $items->have_posts() ) {
            foreach ( $items->posts as $p ) {
                $terms = get_the_terms( $p->ID, 'flavor_menu_cat' );
                if ( $terms && ! is_wp_error( $terms ) ) {
                    foreach ( $terms as $t ) {
                        $item_term_ids[ $t->term_id ] = $t;
                        $posts_by_term[ $t->term_id ][] = $p->ID;
                    }
                }
            }
        }

        // ── Build hierarchy ──────────────────────────────────────────────────────
        $sorted_terms = Flavor_Category_Sort::get_sorted_categories();
        $terms_by_id  = array();
        foreach ( $sorted_terms as $st ) { $terms_by_id[ $st->term_id ] = $st; }

        $parent_cats = array();
        $child_cats  = array();
        foreach ( $sorted_terms as $st ) {
            if ( $st->parent != 0 ) continue;
            $children_of = array();
            foreach ( $sorted_terms as $mc ) {
                if ( $mc->parent == $st->term_id && isset( $item_term_ids[ $mc->term_id ] ) ) {
                    $children_of[] = $mc;
                }
            }
            if ( isset( $item_term_ids[ $st->term_id ] ) || ! empty( $children_of ) ) {
                $parent_cats[ $st->term_id ] = $st;
                $child_cats[ $st->term_id ]  = $children_of;
            }
        }

        // Hierarchy data for JS filter
        $hierarchy_data = array();
        foreach ( $parent_cats as $pid => $pterm ) {
            $cslugs = array();
            foreach ( $child_cats[ $pid ] as $cterm ) {
                $cslugs[] = array( 'slug' => $cterm->slug, 'name' => $cterm->name );
            }
            $hierarchy_data[ $pterm->slug ] = $cslugs;
        }

        $data = compact( 'items', 'parent_cats', 'child_cats', 'posts_by_term', 'terms_by_id', 'hierarchy_data' );

        // ── Output ───────────────────────────────────────────────────────────────
        ob_start();

        $extra = sanitize_html_class( $atts['el_class'] );
        $cols  = intval( $atts['columns'] );
        ?>
        <div class="flavor-menu flavor-theme-dark flavor-cols-<?php echo esc_attr( $cols ); ?> flavor-layout-card-grid <?php echo esc_attr( $extra ); ?>"
             data-columns="<?php echo esc_attr( $cols ); ?>"
             data-default-filter="<?php echo esc_attr( sanitize_text_field( $atts['default_category'] ) ); ?>"
             data-hierarchy="<?php echo esc_attr( wp_json_encode( $hierarchy_data ) ); ?>">

            <?php self::render_header( $atts ); ?>
            <?php self::render_layout_card_grid( $data, $atts ); ?>

        </div>
        <?php
        wp_reset_postdata();
        return ob_get_clean();
    }
}
