<?php

namespace TableBuilderPro\Routes;

defined('ABSPATH') || exit;

class PostDataRoute
{
    use \TableBuilderPro\Traits\Singleton;

    private array $hidden_fields = [
        'date_gmt',
        'post_date_gmt',
        'modified',
        'modified_gmt',
        'password',
        'comment_status',
        'ping_status',
        'sticky',
        'template',
        'format',
        'permalink_template',
        'generated_slug',
        'class_list',
        '_links',
        'to_ping',
        'pinged',
        'post_modified_gmt',
        'post_password',
        'post_content_filtered',
        'guid',
        'post_parent',
        'menu_order',
        'post_mime_type',
        'filter'
    ];

    // Custom field label mappings with consistent naming
    private array $field_labels = [
        'id' => 'ID',
        'post_title' => 'Post Title',
        'post_content' => 'Post Content',
        'post_excerpt' => 'Post Excerpt',
        'post_status' => 'Post Status',
        'post_date' => 'Post Date',
        'post_author' => 'Post Author ID',
        'post_author_name' => 'Post Author',
        'post_featured_image' => 'Post Featured Image',
        'post_permalink' => 'Post Permalink',
        'post_name' => 'Post Slug',
        'post_type' => 'Post Type',
        'post_comment_count' => 'Post Comments',

        // WooCommerce product fields with product_ prefix
        'product_id' => 'Product ID',
        'product_sku' => 'Product SKU',
        'product_regular_price' => 'Product Regular Price',
        'product_sale_price' => 'Product Sale Price',
        'product_stock_quantity' => 'Product Stock Quantity',
        'product_stock_level' => 'Product Stock Level',
        'product_manages_stock' => 'Product Manages Stock',
        'product_low_stock_threshold' => 'Product Low Stock Threshold',
        'product_type' => 'Product Type',
        'product_short_description' => 'Product Short Description',
        'product_categories' => 'Product Categories',
        'product_attributes' => 'Product Attributes',
        'product_average_rating' => 'Product Rating',
        'product_review_count' => 'Product Review Count',
        'product_add_to_cart' => 'Add To Cart Button',
        'product_quantity'    => 'Product Quantity',
        'product_backorders' => 'Product Backorders',
        'product_tax_status' => 'Product Tax Status',
        'product_is_purchasable' => 'Product Is Purchasable',
        'product_external_url' => 'Product External URL',
        'product_button_text' => 'Product Button Text',
        'is_variable' => 'Is Variable Product',
        'is_grouped' => 'Is Grouped Product',
        'grouped_products' => 'Grouped Products',

        // Legacy fields for backward compatibility
        'author_name' => 'Author',
        'featured_image' => 'Featured Image',
        'permalink' => 'Permalink',
        'sku' => 'SKU',
        'price' => 'Price',
        'categories' => 'Categories',
    ];

    private bool $is_woocommerce_active;

    public function __construct()
    {
        $this->is_woocommerce_active = class_exists('WooCommerce') && function_exists('WC');
        add_action('rest_api_init', [$this, 'register_routes']);
    }



    /**
     * Register REST API routes
     */
    public function register_routes(): void
    {
        register_rest_route('table-builder/v1', '/posts', [
            'methods'             => 'GET',
            'callback'            => [$this, 'get_posts_data'],
            'permission_callback' => '__return_true',
            'args'                => [
                'post_type'        => ['required' => true, 'type' => 'string'],
                'per_page'         => ['default' => 10, 'type' => 'integer'],
                'page'             => ['default' => 1, 'type' => 'integer'],
                'search'           => ['type' => 'string'],
                'taxonomy'         => ['type' => 'string'],
                'term'             => ['type' => 'string'],
                'authors'          => ['type' => 'string'],
                'orderby'          => ['default' => 'date', 'type' => 'string'],
                'order'            => ['default' => 'DESC', 'type' => 'string'],
                'offset'           => ['default' => 0, 'type' => 'integer'],
                'product_type'     => ['type' => 'string'], // Filter by product type: simple, variable, grouped, external
                'current_post_id' => ['type' => 'integer'],

            ],
        ]);

        register_rest_route('table-builder/v1', '/post-options', [
            'methods'             => 'GET',
            'callback'            => [$this, 'get_post_options'],
            'permission_callback' => '__return_true',
            'args'                => [
                'post_type' => ['required' => true, 'type' => 'string'],
            ],
        ]);

        // Add route for getting product attribute terms dynamically
        if ($this->is_woocommerce_active) {
            register_rest_route('table-builder/v1', '/product-attribute-terms', [
                'methods'             => 'GET',
                'callback'            => [$this, 'get_product_attribute_terms'],
                'permission_callback' => '__return_true',
                'args'                => [
                    'attribute' => ['required' => true, 'type' => 'string'],
                    'product_id' => ['type' => 'integer'],
                ],
            ]);

            register_rest_route('table-builder/v1', '/product-attributes', [
                'methods'             => 'GET',
                'callback'            => [$this, 'get_all_product_attributes'],
                'permission_callback' => '__return_true',
            ]);
        }

        // Note: Cart routes are handled by the dedicated CartHandler class
    }

    /**
     * Get standard WordPress post fields with consistent naming
     */
    private function get_post_type_fields($post_type): array
    {
        return [
            // Core post fields with consistent post_ prefix
            ['label' => 'Post ID',              'value' => 'id'],
            ['label' => 'Post Title',           'value' => 'post_title'],
            ['label' => 'Post Content',         'value' => 'post_content'],
            ['label' => 'Post Excerpt',         'value' => 'post_excerpt'],
            ['label' => 'Post Featured Image',  'value' => 'post_featured_image'],
            ['label' => 'Post Status',          'value' => 'post_status'],
            ['label' => 'Post Date',            'value' => 'post_date'],
            ['label' => 'Post Author',          'value' => 'post_author_name'],
            ['label' => 'Post Slug',            'value' => 'post_name'],
            ['label' => 'Post Permalink',       'value' => 'post_permalink'],
            ['label' => 'Post Comment Count',   'value' => 'post_comment_count'],

            // Taxonomy fields
            ['label' => 'Post Categories',      'value' => 'post_categories'],
            ['label' => 'Post Tags',            'value' => 'post_tags'],

            // Meta field option
            ['label' => 'Meta Field',           'value' => 'meta'],
        ];
    }



    /**
     * Unified method to get posts data for any post type
     */
    public function get_posts_data(\WP_REST_Request $request): array|\WP_Error
    {
    $post_type = sanitize_text_field($request->get_param('post_type'));
    $per_page = max(1, intval($request->get_param('per_page')) ?: 10);
    if ($per_page === -1 || $per_page >= 9999) {
    }
    
    $page = max(1, intval($request->get_param('page')) ?: 1);
    $search = sanitize_text_field((string)$request->get_param('search'));
    $taxonomy = sanitize_text_field((string)$request->get_param('taxonomy'));
    $term = sanitize_text_field((string)$request->get_param('term'));
    $authors = sanitize_text_field((string)$request->get_param('authors'));
    $orderby = sanitize_text_field((string)$request->get_param('orderby')) ?: 'date';
    $order = strtoupper(sanitize_text_field((string)$request->get_param('order'))) ?: 'DESC';
    $offset = max(0, intval($request->get_param('offset')) ?: 0);
    $product_type = sanitize_text_field((string)$request->get_param('product_type'));
    $current_post_id = absint($request->get_param('current_post_id'));


    if (!in_array($order, ['ASC', 'DESC'], true)) {
        $order = 'DESC';
    }

    // Build query arguments
    $query_args = $this->build_query_args($post_type, $per_page, $page, $search, $taxonomy, $term, $authors, $orderby, $order, $offset, $product_type, $current_post_id);

    // Execute query
    $query = new \WP_Query($query_args);
    $posts = $query->posts ?: [];

    if (empty($posts) && $query->found_posts === 0) {
        $total_for_post_type = (int)wp_count_posts($post_type)->publish;

        if ($total_for_post_type === 0) {
            return new \WP_Error(
                'no_posts',
                __('No posts found for the selected post type.', 'table-builder-block'),
                ['status' => 404]
            );
        } else {
            return new \WP_Error(
                'no_matches',
                __('No matched data found for the given filters.', 'table-builder-block'),
                ['status' => 404]
            );
        }
    }

    // Batch load post meta, thumbnails, and terms to avoid N+1 queries
    $this->batch_load_post_data($posts);

    // Prepare posts data
    $prepared_posts = [];
    foreach ($posts as $post) {
        $prepared_posts[] = $this->prepare_post_data($post);
    }

    // Calculate total pages (handle -1 case)
    $total_pages = $per_page > 0 ? ceil((int)$query->found_posts / $per_page) : 1;
    $dynamic_fields = $this->get_dynamic_fields($prepared_posts, $post_type);
    $all_taxonomies = $this->get_all_taxonomies_and_terms($post_type);
    $all_authors = $this->get_all_authors($post_type);

    wp_reset_postdata();

        return [
            'post_type' => $post_type,
            'posts' => $prepared_posts,
            'dynamicFields' => $dynamic_fields,
            'taxonomies' => $all_taxonomies,
            'authors' => $all_authors,
            'isWooCommerce' => $this->is_product_post_type($post_type),
            'currency' => $this->is_product_post_type($post_type) ? [
                'symbol'             => get_woocommerce_currency_symbol(),
                'position'           => get_option('woocommerce_currency_pos', 'left'),
                'decimals'           => wc_get_price_decimals(),
                'decimal_separator'  => wc_get_price_decimal_separator(),
                'thousand_separator' => wc_get_price_thousand_separator(),
            ] : null,
            'pagination' => [
                'current_page' => $page,
                'per_page' => $per_page === -1 ? 'all' : $per_page,
                'total_posts' => (int)$query->found_posts,
                'total_pages' => (int)$total_pages,
            ],
        ];
    }

private function build_query_args(string $post_type, int $per_page, int $page, string $search, string $taxonomy, string $term, string $authors, string $orderby, string $order, int $offset, string $product_type = '',  int $current_post_id = 0): array
    {
    $total_offset = $offset;
    if ($per_page > 0) {
        $pagination_offset = ($page - 1) * $per_page;
        $total_offset = $pagination_offset + $offset;
    }

    $args = [
        'post_type' => $post_type,
        'posts_per_page' => $per_page,
        'offset' => $total_offset,
        'orderby' => $orderby,
        'order' => $order,
        'post_status' => $post_type === 'attachment' ? 'inherit' : 'publish',
    ];

    if ($current_post_id > 0) {
         $args['post__not_in'] = [$current_post_id];
    }


    if (!empty($search)) {
        $args['s'] = $search;
    }

    // Initialize tax_query array
    $tax_query = [];

    // Filter by product type if specified (for WooCommerce products)
    if (!empty($product_type) && $this->is_product_post_type($post_type)) {
        $tax_query[] = [
            'taxonomy' => 'product_type',
            'field' => 'slug',
            'terms' => $product_type,
        ];
    }

    // Filter by custom taxonomy/term
    if (!empty($taxonomy) && !empty($term)) {
        $term_values = array_map('trim', explode(',', $term));
        $is_numeric_terms = count(array_filter($term_values, 'is_numeric')) === count($term_values);
        $field = $is_numeric_terms ? 'term_id' : 'slug';

        $tax_query[] = [
            'taxonomy' => $taxonomy,
            'field' => $field,
            'terms' => $is_numeric_terms ? array_map('intval', $term_values) : $term_values,
        ];
    }

    // Add tax_query to args if we have any filters
    if (!empty($tax_query)) {
        $args['tax_query'] = $tax_query;
        // If multiple taxonomy filters, use AND relation
        if (count($tax_query) > 1) {
            $args['tax_query']['relation'] = 'AND';
        }
    }

    if (!empty($authors)) {
        $author_slugs = array_map('trim', explode(',', $authors));
        $author_ids = [];

        foreach ($author_slugs as $slug) {
            if (is_numeric($slug)) {
                $author_ids[] = intval($slug);
            } else {
                $user = get_user_by('slug', $slug);
                if ($user) {
                    $author_ids[] = $user->ID;
                }
            }
        }

        if (!empty($author_ids)) {
            $args['author__in'] = $author_ids;
        }
    }

    return $args;
}

    /**
     * Batch load post data to prevent N+1 queries
     * Loads thumbnails, terms, and meta for all posts at once
     */
    private function batch_load_post_data(array $posts): void
    {
        if (empty($posts)) {
            return;
        }

        $post_ids = array_column($posts, 'ID');
        
        // Batch load thumbnails
        if (!empty($post_ids)) {
            foreach ($post_ids as $post_id) {
                get_post_thumbnail_id($post_id);
            }
        }
        
        // Batch load terms for common taxonomies
        $taxonomies = ['category', 'post_tag'];
        if ($this->is_product_post_type($posts[0]->post_type)) {
            $taxonomies[] = 'product_cat';
            $taxonomies[] = 'product_tag';
        }
        wp_cache_add_non_persistent_groups(['terms', 'term_relationships']);
        foreach ($taxonomies as $taxonomy) {
            if (taxonomy_exists($taxonomy)) {
                $terms = wp_get_post_terms($post_ids, $taxonomy);
            }
        }
        
        // Batch load post meta (WordPress caches this automatically when queried)
        update_postmeta_cache($post_ids);
    }

    /**
     * Prepare post data with common fields and WooCommerce extensions
     */
    private function prepare_post_data(\WP_Post $post): array
    {
        // Handle attachment post type separately
        if ($post->post_type === 'attachment') {
            return [
                'id' => $post->ID,
                'post_title' => get_the_title($post->ID),
                'title' => get_the_title($post->ID),
                'post_date' => $post->post_date,
                'post_author_name' => get_the_author_meta('display_name', $post->post_author),
                'author_name' => get_the_author_meta('display_name', $post->post_author),
                'url' => wp_get_attachment_url($post->ID),
                'mime_type' => $post->post_mime_type,
                'post_featured_image' => wp_get_attachment_image($post->ID, 'thumbnail'),
                'featured_image' => wp_get_attachment_image($post->ID, 'thumbnail'),
            ];
        }

        // Base post data
        $post_data = $this->get_base_post_data($post);

        // Add WooCommerce data if this is a product
        if ($this->is_product_post_type($post->post_type) && $this->is_woocommerce_active) {
            $product_data = $this->prepare_product_data($post->ID);
            $post_data = array_merge($post_data, $product_data);
        }

        return $post_data;
    }

    /**
     * Get base post data common to all post types with consistent naming
     */
    private function get_base_post_data(\WP_Post $post): array
    {
        $post_data = get_object_vars($post);

        // Filter out hidden fields
        $post_data = array_filter(
            $post_data,
            fn($key) => !in_array($key, $this->hidden_fields, true),
            ARRAY_FILTER_USE_KEY
        );

        // Clean content and excerpt
        if (isset($post_data['post_content'])) {
            $post_data['post_content'] = $this->strip_content_to_plain_text($post_data['post_content']);
        }

        if (isset($post_data['post_excerpt'])) {
            $post_data['post_excerpt'] = $this->strip_content_to_plain_text($post_data['post_excerpt']);
        }

        // Add common fields with consistent naming
        $featured_image_id = get_post_thumbnail_id($post->ID);
        $post_data['post_featured_image'] = $this->format_image_for_display($featured_image_id);
        $post_data['post_permalink'] = get_permalink($post->ID);
        $post_data['post_author_name'] = get_the_author_meta('display_name', $post->post_author);
        $post_data['post_comment_count'] = get_comments_number($post->ID);

        // Add taxonomy data
        $post_data['post_categories'] = $this->format_terms_for_display($post->ID, 'category');
        $post_data['post_tags'] = $this->format_terms_for_display($post->ID, 'post_tag');

        // Add legacy fields for backward compatibility
        $post_data['featured_image'] = $post_data['post_featured_image'];
        $post_data['permalink'] = $post_data['post_permalink'];
        $post_data['author_name'] = $post_data['post_author_name'];

        // Add meta fields
        $post_data = array_merge($post_data, $this->get_post_meta_fields($post->ID));

        // Normalize ID field
        if (isset($post_data['ID'])) {
            $post_data['id'] = $post_data['ID'];
            unset($post_data['ID']);
        }

        return $post_data;
    }

    /**
     * Get low stock threshold for a product
     */
    private function get_low_stock_threshold(int $product_id): int
    {
        // Try to get product-specific low stock amount
        $product_threshold = get_post_meta($product_id, '_low_stock_amount', true);
        
        if (!empty($product_threshold) && is_numeric($product_threshold)) {
            return (int) $product_threshold;
        }
        
        // Fall back to WooCommerce global setting
        $global_threshold = get_option('woocommerce_notify_low_stock_amount', '');
        
        if (!empty($global_threshold) && is_numeric($global_threshold)) {
            return (int) $global_threshold;
        }
        
        // Default fallback
        return 5;
    }

    /**
     * Calculate stock level: In Stock, Low Stock, or Out of Stock
     */
    private function calculate_stock_level($product, string $stock_status, $stock_quantity): string
    {
        // If product is out of stock according to WooCommerce
        if ($stock_status === 'outofstock') {
            return 'Out of stock';
        }
        
        // If stock management is disabled
        if (!$product->get_manage_stock()) {
            return $stock_status === 'instock' ? 'In stock' : 'Out of stock';
        }
        
        // If stock quantity is 0 or less
        if ($stock_quantity !== null && $stock_quantity <= 0) {
            return 'Out of stock';
        }
        
        // Check for low stock
        if ($stock_quantity !== null) {
            $low_stock_threshold = $this->get_low_stock_threshold($product->get_id());
            
            if ($stock_quantity <= $low_stock_threshold) {
                return 'Low stock';
            }
        }
        
        // Everything else is in stock
        return 'In stock';
    }

    /**
     * Format stock status to human-readable text
     */
    private function format_stock_status(string $stock_status): string
    {
        switch ($stock_status) {
            case 'instock':
                return 'In stock';
            case 'outofstock':
                return 'Out of stock';
            case 'onbackorder':
                return 'On backorder';
            default:
                return ucwords(str_replace('_', ' ', $stock_status));
        }
    }

    /**
     * Prepare WooCommerce product specific data with consistent naming
     */
    private function prepare_product_data(int $product_id): array
    {
    if (!function_exists('wc_get_product')) {
        return [];
    }

    $product = wc_get_product($product_id);
    if (!$product) {
        return [];
    }

    // Get stock status and quantity properly
    $stock_status = $product->get_stock_status();
    $stock_status_formatted = $this->format_stock_status($stock_status);
    $is_in_stock = $stock_status === 'instock';
    
    // Get stock quantity - handle products with stock management disabled
    $manages_stock = $product->get_manage_stock();
    $stock_quantity = $manages_stock ? $product->get_stock_quantity() : null;
    
    // Calculate stock level (In Stock, Low Stock, Out of Stock)
    $stock_level = $this->calculate_stock_level($product, $stock_status, $stock_quantity);
    
    // Get low stock threshold
    $low_stock_amount = $this->get_low_stock_threshold($product_id);

    $product_data = [
        // Core product fields with product_ prefix
        'product_id' => $product->get_id(),
        'product_sku' => $product->get_sku(),
        'product_regular_price' => $product->get_regular_price() ,
        'product_sale_price' => $product->get_sale_price(),
        'product_stock_status' => $stock_status_formatted, // Human-readable: In Stock, Out of Stock, On Backorder
        'product_stock_quantity' => $stock_quantity, // Numeric quantity or null
        'product_stock_level' => $stock_level, // Computed: In Stock, Low Stock, Out of Stock
        'product_manages_stock' => $manages_stock, // Whether stock management is enabled
        'product_low_stock_threshold' => $low_stock_amount, // The threshold for low stock
        'product_type' => $product->get_type(),
        'product_short_description' => $this->strip_content_to_plain_text($product->get_short_description()),
        'product_backorders' => $product->get_backorders(),
        'product_tax_status' => $product->get_tax_status(),
        'product_average_rating' => $product->get_average_rating(),
        'product_review_count' => $product->get_review_count(),
        'product_categories' => $this->format_terms_for_display($product_id, 'product_cat'),
        'product_add_to_cart' => $product->is_purchasable() && $is_in_stock,
        'product_is_purchasable' => $product->is_purchasable(),

        // Legacy fields for backward compatibility
        'sku' => $product->get_sku(),
        'categories' => $this->format_terms_for_display($product_id, 'product_cat'),
        'add_to_cart' => $product->is_purchasable() && $is_in_stock,
        'out_of_stock' => !$is_in_stock, // CRITICAL: This should be boolean
        'stock_status' => $stock_status_formatted,
        'stock_quantity' => $stock_quantity, // Legacy field
        'stock_level' => $stock_level, // Legacy field for stock_level
    ];

    // Set button text based on product type and stock
    if ($product->is_type('external')) {
        if ($product instanceof \WC_Product_External) {
            $external_url = $product->get_product_url();
            $button_text = $product->get_button_text() ?: 'Buy Product';
            
            $product_data['product_external_url'] = $external_url ?: '';
            $product_data['external_url'] = $external_url ?: ''; 
            $product_data['product_url'] = $external_url ?: '';
            $product_data['product_button_text'] = $button_text;
            $product_data['product_external_button_text'] = $button_text;
            $product_data['button_text'] = $button_text;
        }
    } elseif ($product->is_type('variable')) {
        if ($product instanceof \WC_Product_Variable) {
            $variation_ids = $product->get_children();
            $variations_data = [];
            
            foreach ($variation_ids as $variation_id) {
                $variation = wc_get_product($variation_id);
                
                if (!$variation || !$variation->is_type('variation')) {
                    continue;
                }
                
                /** @var \WC_Product_Variation $variation */
                $var_stock_status = $variation->get_stock_status();
                $var_stock_status_formatted = $this->format_stock_status($var_stock_status);
                $var_is_in_stock = $var_stock_status === 'instock';
                $var_manages_stock = $variation->get_manage_stock();
                $var_stock_quantity = $var_manages_stock ? $variation->get_stock_quantity() : null;
                $var_stock_level = $this->calculate_stock_level($variation, $var_stock_status, $var_stock_quantity);
                
                $variations_data[] = [
                    'variation_id' => $variation_id,
                    'attributes' => $variation->get_attributes(),
                    'is_in_stock' => $var_is_in_stock,
                    'is_purchasable' => $variation->is_purchasable() && $var_is_in_stock,
                    'display_price' => $variation->get_price(),
                    'price_html' => $variation->get_price_html(),
                    'sku' => $variation->get_sku(),
                    'stock_status' => $var_stock_status_formatted,
                    'stock_quantity' => $var_stock_quantity,
                    'stock_level' => $var_stock_level,
                    'manages_stock' => $var_manages_stock,
                ];
            }
            
            $product_data['variations'] = $variations_data;
            $product_data['variation_attributes'] = $product->get_variation_attributes();
            $product_data['is_variable'] = true;
            $product_data['button_text'] = $is_in_stock ? 'Select Options' : 'Read More';
        }
    } elseif ($product->is_type('grouped')) {
        $product_data['product_type'] = 'grouped';
        $product_data['is_grouped'] = true;
        $product_data['product_is_grouped'] = true;
        $product_data['button_text'] = 'View Products';
        
        if ($product instanceof \WC_Product_Grouped) {
            $product_data['grouped_products'] = $product->get_children();
            $product_data['children'] = $product->get_children();
        }
    } else {
        // Simple product
        $product_data['button_text'] = $is_in_stock ? 'Add to Cart' : 'Read More';
    }

    // Add product attributes for all products
    $product_data['product_attributes'] = $this->get_product_attributes($product);

    // Add product_selection flag if product has attributes
    if (!empty($product_data['product_attributes']) && is_array($product_data['product_attributes'])) {
        $product_data['product_selection'] = true;
    } else {
        $product_data['product_selection'] = false;
    }

    return $product_data;
}

    /**
     * Get product attributes for WooCommerce products
     * Returns a structured array of attributes with their terms, optimized for UI display
     */
    private function get_product_attributes($product): array
{
    if (!is_object($product)) {
        return [];
    }

    $attributes = [];
    $product_attributes = $product->get_attributes();
    $variation_attributes = $product->is_type('variable') ? $product->get_variation_attributes() : [];

    foreach ($product_attributes as $attribute_name => $attribute) {
        // Normalize attribute name - remove prefixes
        $clean_name = str_replace(['attribute_', 'pa_'], '', $attribute_name);
        
        $attribute_data = [
            'name' => $clean_name, // Use clean name
            'attribute_name' => $attribute_name, // Keep original for reference
            'label' => wc_attribute_label($attribute_name),
            'is_variation' => $attribute->get_variation(),
            'is_visible' => $attribute->get_visible(),
            'is_taxonomy' => $attribute->is_taxonomy(),
            'position' => $attribute->get_position(),
            'terms' => [],
            'display_type' => $attribute->is_taxonomy() ? 'taxonomy' : 'custom'
        ];

        // Get attribute terms
        if ($attribute->is_taxonomy()) {
            $terms = wp_get_post_terms($product->get_id(), $attribute_name);
            if (!is_wp_error($terms)) {
                foreach ($terms as $term) {
                    $attribute_data['terms'][] = [
                        'id' => $term->term_id,
                        'name' => $term->name,
                        'slug' => $term->slug,
                    ];
                }
            }
        } else {
            $values = $attribute->get_options();
            foreach ($values as $value) {
                $attribute_data['terms'][] = [
                    'id' => sanitize_title($value),
                    'name' => $value,
                    'slug' => sanitize_title($value),
                ];
            }
        }

        // Add variation options if this is a variation attribute
        if ($attribute->get_variation()) {
            // Try multiple key variations to find the matching variation_attributes
            $possible_keys = [
                $clean_name,
                $attribute_name,
                'pa_' . $clean_name,
                str_replace('pa_', '', $attribute_name)
            ];
            
            $variation_options = null;
            foreach ($possible_keys as $key) {
                if (isset($variation_attributes[$key])) {
                    $variation_options = $variation_attributes[$key];
                    break;
                }
            }
            
            if ($variation_options) {
                $attribute_data['variation_options'] = $variation_options;
                $attribute_data['is_required_for_variation'] = true;
            } elseif (!empty($attribute_data['terms'])) {
                // Fallback: use terms as variation options
                $attribute_data['variation_options'] = array_column($attribute_data['terms'], 'name');
                $attribute_data['is_required_for_variation'] = true;
            }
        }

        $attributes[] = $attribute_data;
    }

    // Sort by position
    usort($attributes, function ($a, $b) {
        return $a['position'] <=> $b['position'];
    });

    return $attributes;
}

    /**
     * Check if post type is a WooCommerce product
     */
    private function is_product_post_type(string $post_type): bool
    {
        return $post_type === 'product';
    }

    /**
     * Get post options (fields) for a specific post type
     */
    public function get_post_options(\WP_REST_Request $request): array
    {
        $post_type = sanitize_text_field($request->get_param('post_type'));

        if ($this->is_product_post_type($post_type)) {
            return $this->get_woocommerce_fields();
        }

        return $this->get_post_type_fields($post_type);
    }

    /**
     * Get attribute terms for a specific WooCommerce product attribute
     * This enables dynamic selection in the UI
     */
    public function get_product_attribute_terms(\WP_REST_Request $request): array|\WP_Error
    {
        if (!$this->is_woocommerce_active) {
            return new \WP_Error('woocommerce_not_active', 'WooCommerce is not active', ['status' => 400]);
        }

        $attribute = sanitize_text_field($request->get_param('attribute'));
        $product_id = intval($request->get_param('product_id'));

        if (empty($attribute)) {
            return new \WP_Error('missing_attribute', 'Attribute parameter is required', ['status' => 400]);
        }

        // If product_id is provided, get terms for that specific product
        if ($product_id > 0) {
            $product = wc_get_product($product_id);
            if (!$product) {
                return new \WP_Error('invalid_product', 'Invalid product ID', ['status' => 404]);
            }

            $product_attributes = $product->get_attributes();
            if (!isset($product_attributes[$attribute])) {
                return new \WP_Error('attribute_not_found', 'Attribute not found for this product', ['status' => 404]);
            }

            $attribute_obj = $product_attributes[$attribute];
            $terms = [];

            if ($attribute_obj->is_taxonomy()) {
                $product_terms = wp_get_post_terms($product_id, $attribute);
                if (!is_wp_error($product_terms)) {
                    foreach ($product_terms as $term) {
                        $terms[] = [
                            'id' => $term->term_id,
                            'name' => $term->name,
                            'slug' => $term->slug
                        ];
                    }
                }
            } else {
                // Custom attribute
                $values = $attribute_obj->get_options();
                foreach ($values as $value) {
                    $terms[] = [
                        'id' => sanitize_title($value),
                        'name' => $value,
                        'slug' => sanitize_title($value)
                    ];
                }
            }

            return [
                'attribute' => $attribute,
                'label' => wc_attribute_label($attribute),
                'terms' => $terms
            ];
        }

        // Get all terms for the attribute taxonomy (global)
        if (taxonomy_exists($attribute)) {
            $terms = get_terms([
                'taxonomy' => $attribute,
                'hide_empty' => false,
            ]);

            if (is_wp_error($terms)) {
                return new \WP_Error('terms_error', $terms->get_error_message(), ['status' => 500]);
            }

            $formatted_terms = [];
            foreach ($terms as $term) {
                $formatted_terms[] = [
                    'id' => $term->term_id,
                    'name' => $term->name,
                    'slug' => $term->slug
                ];
            }

            return [
                'attribute' => $attribute,
                'label' => wc_attribute_label($attribute),
                'terms' => $formatted_terms
            ];
        }

        return new \WP_Error('invalid_attribute', 'Invalid attribute or taxonomy', ['status' => 404]);
    }

    /**
     * Get all available WooCommerce product attributes
     * Used to populate the initial attribute dropdown in the UI
     */
    public function get_all_product_attributes(\WP_REST_Request $request): array
    {
        if (!$this->is_woocommerce_active) {
            return [];
        }

        $attributes = [];

        // Get global product attributes
        $attribute_taxonomies = wc_get_attribute_taxonomies();
        foreach ($attribute_taxonomies as $attribute) {
            $taxonomy_name = wc_attribute_taxonomy_name($attribute->attribute_name);
            $attributes[] = [
                'name' => $taxonomy_name,
                'label' => $attribute->attribute_label,
                'slug' => $attribute->attribute_name,
                'type' => $attribute->attribute_type,
                'is_global' => true
            ];
        }

        // Get custom attributes from products (non-taxonomy attributes)
        global $wpdb;
        $custom_attributes = $wpdb->get_results("
            SELECT DISTINCT meta_value 
            FROM {$wpdb->postmeta} pm
            INNER JOIN {$wpdb->posts} p ON pm.post_id = p.ID
            WHERE p.post_type = 'product'
            AND pm.meta_key = '_product_attributes'
            AND pm.meta_value != ''
        ");

        foreach ($custom_attributes as $meta) {
            $unserialized = maybe_unserialize($meta->meta_value);
            if (is_array($unserialized)) {
                foreach ($unserialized as $attr_name => $attr_data) {
                    if (!isset($attr_data['is_taxonomy']) || !$attr_data['is_taxonomy']) {
                        $clean_name = str_replace('pa_', '', $attr_name);
                        $attributes[] = [
                            'name' => $attr_name,
                            'label' => ucfirst(str_replace(['_', '-'], ' ', $clean_name)),
                            'slug' => $clean_name,
                            'type' => 'custom',
                            'is_global' => false
                        ];
                    }
                }
            }
        }

        // Remove duplicates
        $unique_attributes = [];
        $seen = [];
        foreach ($attributes as $attribute) {
            if (!in_array($attribute['name'], $seen)) {
                $unique_attributes[] = $attribute;
                $seen[] = $attribute['name'];
            }
        }

        return [
            'attributes' => $unique_attributes,
            'total' => count($unique_attributes)
        ];
    }

    /**
     * Get WooCommerce product specific fields with consistent naming
     */
    private function get_woocommerce_fields(): array
    {
        $fields = [
            // Keep core aliases for default column compatibility when switching to product.
            ['label' => 'ID',               'value' => 'id'],
            ['label' => 'Author',           'value' => 'author_name'],
            ['label' => 'Product ID',            'value' => 'product_id'],
            ['label' => 'Product Title',         'value' => 'post_title'],
            ['label' => 'Product SKU',           'value' => 'product_sku'],
            ['label' => 'Product Regular Price', 'value' => 'product_regular_price'],
            ['label' => 'Product Sale Price',    'value' => 'product_sale_price'],
            ['label' => 'Product Image',         'value' => 'post_featured_image'],
            ['label' => 'Product Description',   'value' => 'post_content'],
            ['label' => 'Product Short Description', 'value' => 'product_short_description'],

            // Stock and availability
            ['label' => 'Product Stock Quantity', 'value' => 'product_stock_quantity'],
            ['label' => 'Product Stock Level',   'value' => 'product_stock_level'],
            ['label' => 'Product Manages Stock', 'value' => 'product_manages_stock'],
            ['label' => 'Product Low Stock Threshold', 'value' => 'product_low_stock_threshold'],
            ['label' => 'Product Backorders',    'value' => 'product_backorders'],
            ['label' => 'Add To Cart Button',    'value' => 'product_add_to_cart'],
            ['label' => 'Product Quantity',      'value' => 'product_quantity'],
            ['label' => 'Product Type',          'value' => 'product_type'],
            ['label' => 'Product Categories',    'value' => 'product_categories'],
            ['label' => 'Product Tax Status',    'value' => 'product_tax_status'],
            ['label' => 'Product Attributes',    'value' => 'product_attributes'],
            ['label' => 'Product Rating',        'value' => 'product_average_rating'],
            ['label' => 'Product Review Count',  'value' => 'product_review_count'],
            ['label' => 'Post Status',           'value' => 'post_status'],
            ['label' => 'Post Date',             'value' => 'post_date'],
            ['label' => 'Post Author',           'value' => 'post_author_name'],
            ['label' => 'Post Slug',             'value' => 'post_name'],
            ['label' => 'Post Permalink',        'value' => 'post_permalink'],
            ['label' => 'Meta Field',            'value' => 'meta'],
        ];

        return $fields;
    }

    private function get_all_taxonomies_and_terms(string $post_type): array
    {
        $result     = [];
        $taxonomies = get_object_taxonomies($post_type, 'objects');

        foreach ($taxonomies as $taxonomy => $tax_obj) {
            $terms = get_terms([
                'taxonomy'   => $taxonomy,
                'hide_empty' => false,
            ]);

            if (is_wp_error($terms)) {
                $terms = [];
            }

            $result[$taxonomy] = [
                'slug'  => $taxonomy,
                'label' => $tax_obj->label,
                'terms' => array_map(function ($term) {
                    return [
                        'id'   => $term->term_id,
                        'name' => $term->name,
                        'slug' => $term->slug,
                    ];
                }, $terms),
            ];
        }

        return $result;
    }

    private function get_all_authors(string $post_type): array
    {
        global $wpdb;

        $post_status = $post_type === 'attachment' ? 'inherit' : 'publish';

        $author_ids = $wpdb->get_col(
            $wpdb->prepare(
                "SELECT DISTINCT post_author FROM {$wpdb->posts} WHERE post_type = %s AND post_status = %s",
                $post_type,
                $post_status
            )
        );

        if (empty($author_ids)) {
            $out = [
                'label' => 'Authors',
                'items' => []
            ];
            return $out;
        }

        $users = get_users([
            'include' => $author_ids,
            'orderby' => 'display_name',
        ]);

        $authors = [];
        foreach ($users as $user) {
            $authors[] = [
                'id'          => $user->ID,
                'name'        => $user->display_name,
                'slug'        => $user->user_nicename,
                'url'         => get_author_posts_url($user->ID),
                'avatar'      => get_avatar_url($user->ID),
                'description' => get_the_author_meta('description', $user->ID),
            ];
        }

        $out = [
            'label' => 'Authors',
            'items' => $authors
        ];

        return $out;
    }

    private function get_post_taxonomies_and_terms(int $post_id, string $post_type): array
    {
        $result     = [];
        $taxonomies = get_object_taxonomies($post_type, 'objects');

        foreach ($taxonomies as $taxonomy => $tax_obj) {
            $terms = wp_get_post_terms($post_id, $taxonomy);
            if (is_wp_error($terms)) $terms = [];

            $result[$taxonomy] = [
                'label' => $tax_obj->label,
                'terms' => array_map(function ($term) {
                    return [
                        'id'   => $term->term_id,
                        'name' => $term->name,
                        'slug' => $term->slug,
                    ];
                }, $terms)
            ];
        }

        return $result;
    }

    /**
     * Get post meta fields and format them properly
     */
    private function get_post_meta_fields(int $post_id): array
    {
        $meta_data = [];
        $all_meta = get_post_meta($post_id);

        if (!is_array($all_meta)) {
            return $meta_data;
        }

        // Filter out WordPress internal meta fields
        $excluded_meta = [
            '_edit_lock',
            '_edit_last',
            '_wp_old_slug',
            '_wp_old_date',
            '_thumbnail_id',
            '_wp_attached_file',
            '_wp_attachment_metadata',
            '_wp_page_template',
            '_wp_attachment_image_alt',
            '_encloseme',
            '_pingme',
            '_wp_trash_meta_status',
            '_wp_trash_meta_time',
            '_menu_item_type',
            '_menu_item_menu_item_parent',
            '_menu_item_object_id',
            '_menu_item_object',
            '_menu_item_target',
            '_menu_item_classes',
            '_menu_item_xfn',
            '_menu_item_url',
            '_wp_attachment_backup_sizes',
            '_wp_attachment_context'
        ];

        foreach ($all_meta as $meta_key => $meta_values) {
            // Skip private meta fields (starting with _) and excluded ones
            if (strpos($meta_key, '_') === 0 || in_array($meta_key, $excluded_meta, true)) {
                continue;
            }

            // Get the first value (meta values are arrays)
            $meta_value = isset($meta_values[0]) ? $meta_values[0] : '';

            // Try to unserialize if it's serialized data
            if (is_string($meta_value) && is_serialized($meta_value)) {
                $unserialized = maybe_unserialize($meta_value);
                if (is_array($unserialized) || is_object($unserialized)) {
                    $meta_value = wp_json_encode($unserialized);
                } else {
                    $meta_value = $unserialized;
                }
            }

            // Add meta_ prefix to distinguish from regular fields
            $meta_data['meta_' . $meta_key] = $meta_value;
        }

        return $meta_data;
    }



    private function strip_content_to_plain_text(string $content): string
    {
        if (empty($content)) return '';

        $content = strip_shortcodes($content);
        $content = wp_strip_all_tags($content);
        $content = html_entity_decode($content, ENT_QUOTES, 'UTF-8');
        $content = preg_replace('/\s+/', ' ', $content);
        return trim($content);
    }



    /**
     * Build dynamic fields with proper labels
     */
    private function get_dynamic_fields(array $posts, string $post_type): array
    {
        // For WooCommerce products, return predefined fields
        if ($this->is_product_post_type($post_type)) {
            return $this->get_woocommerce_fields();
        }

        if (empty($posts)) {
            return $this->get_post_type_fields($post_type);
        }

        // Collect keys from first 10 posts
        $sample_posts = array_slice($posts, 0, 10);
        $keys = [];
        foreach ($sample_posts as $p) {
            if (is_array($p)) {
                foreach (array_keys($p) as $k) {
                    if (in_array($k, $this->hidden_fields, true)) continue;
                    $keys[$k] = true;
                }
            }
        }

        $fields = [];
        foreach (array_keys($keys) as $k) {
            // Skip individual meta fields - we don't want them in the dropdown
            if (strpos($k, 'meta_') === 0) {
                continue;
            }

            // Use custom label if available, otherwise format the key
            if (isset($this->field_labels[$k])) {
                $label = $this->field_labels[$k];
            } else {
                // Remove 'post_' prefix and format
                $clean_key = preg_replace('/^post_/', '', $k);
                $label = ucwords(str_replace('_', ' ', $clean_key));
            }

            $fields[] = ['label' => $label, 'value' => $k];
        }

        // Add the generic "Meta Field" option that users can select to enter custom meta keys
        $fields[] = ['label' => 'Meta Field', 'value' => 'meta'];

        return $fields;
    }

    /**
     * Format image for display in table
     */
    private function format_image_for_display($image_id): string
    {
        if (!$image_id) return '';

        $image_url = wp_get_attachment_image_url($image_id, 'thumbnail');
        $alt = get_post_meta($image_id, '_wp_attachment_image_alt', true);

        return $image_url ? "<img src='" . esc_url($image_url) . "' alt='" . esc_attr($alt) . "' class='post-table-image'>" : '';
    }

    private function format_terms_for_display(int $post_id, string $taxonomy): string
    {
        $terms = wp_get_post_terms($post_id, $taxonomy);
        if (is_wp_error($terms) || empty($terms)) return '';

        $term_names = array_map(function ($term) {
            return $term->name;
        }, $terms);

        return implode(', ', $term_names);
    }
}