<?php
/**
 * GGM Commerce Preview Manager
 *
 * Handles preview product selection for single product templates in Elementor editor.
 * Allows users to select a product to preview while designing templates.
 *
 * @package GGM Commerce
 * @subpackage Elementor
 * @version 1.0.0
 */

// If this file is called directly, abort.
if (!defined('ABSPATH')) {
    exit;
}

// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching
// phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter

/**
 * Class GGM_Commerce_Preview_Manager
 */
class GGM_Commerce_Preview_Manager {

    /**
     * Meta key for storing preview product ID
     */
    const PREVIEW_META_KEY = '_ggm_preview_product_id';

    /**
     * Initialize the preview manager
     */
    public static function init() {
        // Only initialize if Elementor is loaded
        if (!did_action('elementor/loaded')) {
            // Wait for Elementor to load before initializing
            add_action('elementor/loaded', [__CLASS__, 'register_hooks']);
            return;
        }

        self::register_hooks();
    }

    /**
     * Register all hooks for the preview manager
     */
    public static function register_hooks() {
        // Document controls for preview product selection in Page Settings
        add_action('elementor/documents/register_controls', [__CLASS__, 'register_document_controls']);

        // Save handler for preview product selection
        add_action('elementor/document/after_save', [__CLASS__, 'save_preview_product'], 10, 2);

        // Admin bar indicator showing current preview product
        add_action('admin_bar_menu', [__CLASS__, 'add_preview_info_to_admin_bar'], 999);

        // AJAX handler for product search
        add_action('wp_ajax_ggm_get_preview_products', [__CLASS__, 'ajax_get_products']);

        // Editor scripts for preview indicator panel
        add_action('elementor/editor/before_enqueue_scripts', [__CLASS__, 'enqueue_editor_scripts']);
    }

    /**
     * Register document-level controls for preview product selection
     */
    public static function register_document_controls($document) {
        // Only add to page/post documents (where templates might be built)
        if (!$document) {
            return;
        }

        // Safety check - ensure Elementor Controls_Manager is available
        if (!class_exists('\Elementor\Controls_Manager')) {
            return;
        }

        try {
            $document->start_controls_section(
                'ggm_preview_section',
                [
                    'label' => __('GGM Commerce Preview', 'ggm-commerce'),
                    'tab' => \Elementor\Controls_Manager::TAB_SETTINGS,
                ]
            );

            $document->add_control(
                'ggm_preview_product_notice',
                [
                    'type' => \Elementor\Controls_Manager::RAW_HTML,
                    'raw' => '<div style="padding: 10px; background: #f0f6fc; border-left: 4px solid #2563eb; margin-bottom: 10px;">
                        <strong>' . __('Product Preview', 'ggm-commerce') . '</strong><br>
                        ' . __('Select a product to preview in the editor. GGM Commerce widgets will display data from this product.', 'ggm-commerce') . '
                    </div>',
                ]
            );

            // Get products for the select dropdown
            $products = self::get_products_for_select();

            $document->add_control(
                'ggm_preview_product_id',
                [
                    'label' => __('Preview Product', 'ggm-commerce'),
                    'type' => \Elementor\Controls_Manager::SELECT2,
                    'options' => $products,
                    'default' => '',
                    'label_block' => true,
                    'description' => __('Select a product to preview while editing this page/template.', 'ggm-commerce'),
                ]
            );

            $document->add_control(
                'ggm_preview_refresh_notice',
                [
                    'type' => \Elementor\Controls_Manager::RAW_HTML,
                    'raw' => '<p style="color: #666; font-size: 11px; margin-top: 5px;">' .
                        __('After selecting a product, save the page and refresh to see the preview.', 'ggm-commerce') .
                        '</p>',
                ]
            );

            $document->end_controls_section();
        } catch (\Exception $e) {
            // Silently fail if controls can't be registered
            return;
        }
    }

    /**
     * Get products for select dropdown
     */
    /** @var array|null Per-request cache for product select options */
    private static $products_for_select_cache = null;

    public static function get_products_for_select($limit = 100) {
        if (self::$products_for_select_cache !== null) {
            return self::$products_for_select_cache;
        }

        global $wpdb;

        $table_name = $wpdb->prefix . 'ggmc_products';

        // Check if table exists
        if ($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $table_name)) !== $table_name) {
            self::$products_for_select_cache = ['' => __('No products found', 'ggm-commerce')];
            return self::$products_for_select_cache;
        }

        // Products use status = 'active' or NULL for active products
        $products = $wpdb->get_results(
            $wpdb->prepare(
                // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is safely constructed
                "SELECT id, name, sku FROM $table_name WHERE (status = 'active' OR status IS NULL) ORDER BY name ASC LIMIT %d",
                $limit
            )
        );

        $options = ['' => __('-- Select a Product --', 'ggm-commerce')];

        if (!empty($products)) {
            foreach ($products as $product) {
                $label = $product->name;
                if (!empty($product->sku)) {
                    $label .= ' (SKU: ' . $product->sku . ')';
                }
                $options[$product->id] = $label;
            }
        }

        self::$products_for_select_cache = $options;
        return $options;
    }

    /**
     * Save preview product when document is saved
     */
    public static function save_preview_product($document, $data) {
        if (!isset($data['settings']['ggm_preview_product_id'])) {
            return;
        }

        $post_id = $document->get_main_id();
        $preview_product_id = absint($data['settings']['ggm_preview_product_id']);

        if ($preview_product_id > 0) {
            update_post_meta($post_id, self::PREVIEW_META_KEY, $preview_product_id);
        } else {
            delete_post_meta($post_id, self::PREVIEW_META_KEY);
        }
    }

    /**
     * Get the preview product ID for a given post
     */
    public static function get_preview_product_id($post_id = null) {
        if (empty($post_id)) {
            $post_id = get_the_ID();
        }

        // First check if we're in Elementor editor
        if (self::is_elementor_editor()) {
            // Try to get the post being edited
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Preview context checks, not form processing
            if (isset($_GET['post'])) {
                $post_id = absint($_GET['post']);
            }
        }

        if (empty($post_id)) {
            return null;
        }

        $preview_product_id = get_post_meta($post_id, self::PREVIEW_META_KEY, true);

        return !empty($preview_product_id) ? absint($preview_product_id) : null;
    }

    /**
     * Get preview product data
     */
    public static function get_preview_product_data($post_id = null) {
        $preview_product_id = self::get_preview_product_id($post_id);

        if (empty($preview_product_id)) {
            return null;
        }

        global $wpdb;
        $table_name = $wpdb->prefix . 'ggmc_products';

        return $wpdb->get_row(
            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is safely constructed
            $wpdb->prepare("SELECT * FROM $table_name WHERE id = %d", $preview_product_id)
        );
    }

    /**
     * Check if we're in Elementor editor mode
     * Uses safe checks to avoid errors when Elementor isn't fully initialized
     */
    public static function is_elementor_editor() {
        // First check URL parameters - these are always available and safe
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Preview context checks, not form processing
        if (isset($_GET['elementor-preview'])) {
            return true;
        }

        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Preview context checks, not form processing
        if (isset($_GET['action']) && $_GET['action'] === 'elementor') {
            return true;
        }

        // Check if Elementor class exists
        if (!class_exists('\Elementor\Plugin')) {
            return false;
        }

        // Safely check Elementor instance and its components
        try {
            $instance = \Elementor\Plugin::$instance;

            if (!$instance) {
                return false;
            }

            // Check editor mode - with null safety
            if (isset($instance->editor) && $instance->editor && method_exists($instance->editor, 'is_edit_mode')) {
                if ($instance->editor->is_edit_mode()) {
                    return true;
                }
            }

            // Check preview mode - with null safety
            if (isset($instance->preview) && $instance->preview && method_exists($instance->preview, 'is_preview_mode')) {
                if ($instance->preview->is_preview_mode()) {
                    return true;
                }
            }
        } catch (\Exception $e) {
            // If any error occurs, fall back to false
            return false;
        }

        return false;
    }

    /**
     * Check if we're in Elementor preview (iframe)
     * Uses safe checks to avoid errors when Elementor isn't fully initialized
     */
    public static function is_elementor_preview() {
        // First check URL parameter - always safe
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Preview context checks, not form processing
        if (isset($_GET['elementor-preview'])) {
            return true;
        }

        if (!class_exists('\Elementor\Plugin')) {
            return false;
        }

        try {
            $instance = \Elementor\Plugin::$instance;

            if (!$instance) {
                return false;
            }

            if (isset($instance->preview) && $instance->preview && method_exists($instance->preview, 'is_preview_mode')) {
                return $instance->preview->is_preview_mode();
            }
        } catch (\Exception $e) {
            return false;
        }

        return false;
    }

    /**
     * Add preview product info to admin bar
     */
    public static function add_preview_info_to_admin_bar($admin_bar) {
        if (!is_admin() && !self::is_elementor_editor()) {
            return;
        }

        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Preview context checks, not form processing
        $post_id = isset($_GET['post']) ? absint($_GET['post']) : get_the_ID();
        $preview_product = self::get_preview_product_data($post_id);

        if (!$preview_product) {
            return;
        }

        $admin_bar->add_node([
            'id' => 'ggm-preview-product',
            'title' => sprintf(
                '<span style="color: #72aee6;">GGM Preview:</span> %s',
                esc_html($preview_product->name)
            ),
            'parent' => 'top-secondary',
            'meta' => [
                'class' => 'ggm-preview-indicator',
            ],
        ]);
    }

    /**
     * AJAX handler for getting products
     */
    public static function ajax_get_products() {
        check_ajax_referer('ggm_commerce_nonce', 'nonce');

        $search = isset($_POST['search']) ? sanitize_text_field(wp_unslash($_POST['search'])) : '';

        global $wpdb;
        $table_name = $wpdb->prefix . 'ggmc_products';

        // Products use status = 'active' or NULL for active products
        $sql = "SELECT id, name, sku FROM $table_name WHERE (status = 'active' OR status IS NULL)";

        if (!empty($search)) {
            $sql .= $wpdb->prepare(
                " AND (name LIKE %s OR sku LIKE %s)",
                '%' . $wpdb->esc_like($search) . '%',
                '%' . $wpdb->esc_like($search) . '%'
            );
        }

        $sql .= " ORDER BY name ASC LIMIT 50";

        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- $sql is built safely with wpdb->prepare above
        $products = $wpdb->get_results($sql);

        $results = [];
        foreach ($products as $product) {
            $results[] = [
                'id' => $product->id,
                'text' => $product->name . (!empty($product->sku) ? ' (SKU: ' . $product->sku . ')' : ''),
            ];
        }

        wp_send_json_success($results);
    }

    /**
     * Enqueue editor scripts
     */
    public static function enqueue_editor_scripts() {
        wp_enqueue_script(
            'ggm-preview-manager',
            plugin_dir_url(dirname(__FILE__)) . 'assets/js/preview-manager.js',
            ['jquery', 'elementor-editor'],
            '1.0.0',
            true
        );

        wp_localize_script('ggm-preview-manager', 'ggmPreviewManager', [
            'ajaxUrl' => admin_url('admin-ajax.php'),
            'nonce' => wp_create_nonce('ggm_commerce_nonce'),
            'strings' => [
                'previewLabel' => __('Preview Product:', 'ggm-commerce'),
                'noProduct' => __('No preview product selected', 'ggm-commerce'),
                'selectProduct' => __('Select a product in Page Settings > GGM Commerce Preview', 'ggm-commerce'),
            ],
        ]);

        // Add inline styles for the preview indicator
        wp_add_inline_style('elementor-editor', '
            .ggm-preview-indicator-panel {
                background: #f0f6fc;
                border: 1px solid #2563eb;
                border-radius: 4px;
                padding: 10px 15px;
                margin: 10px;
                font-size: 12px;
            }
            .ggm-preview-indicator-panel strong {
                color: #2563eb;
            }
        ');
    }
}
