<?php
/**
 * Bulk Run Agent Class
 *
 * @package SAAI\Classes\Chat
 */

namespace SAAI\Classes\Chat;

use SAAI\Traits\Singleton_Trait;
use SAAI\Helpers\Helper;
use SAAI\Classes\Plan_Manager;
use SAAI\REST\Chat\Chat_Widget_Settings;

/**
 * Bulk Run Agent Class
 *
 * @since 1.0.0
 */
class Chat_Widget {

    use Singleton_Trait;

    /**
     * Run the chat widget class.
     */
    public function run() {
        add_action( 'wp_footer', array( $this, 'display_chat_widget' ) );
        add_shortcode( 'storeagent_chat', array( $this, 'display_inline_chat_shortcode' ) );
        add_action( 'admin_footer', array( $this, 'output_chat_config_in_admin' ) );
    }

    /**
     * Should display chat widget.
     * Chat will be displayed based on display settings, exclusions, and post type configurations.
     *
     * @return bool
     */
    public function should_display_chat_widget() {
        // Get chat widget settings to check if enabled.
        $settings = Chat_Widget_Settings::get_chat_widget_settings();

        // Check if chat widget is enabled in settings.
        if ( empty( $settings['enabled'] ) ) {
            return false;
        }

        // Check if chat is allowed for current user.
        $is_chat_allowed = Plan_Manager::instance()->is_chat_allowed_for_current_user();
        if ( ! $is_chat_allowed ) {
            return false;
        }

        // Check if current page/post is excluded (highest priority).
        if ( $this->is_page_excluded( $settings ) ) {
            return false;
        }

        // Check if display settings are configured.
        $display_post_types = ! empty( $settings['display_post_types'] ) ? $settings['display_post_types'] : array();
        $display_my_account = ! empty( $settings['display_my_account'] );

        // If display settings are not configured, use backward compatibility with existing filter.
        if ( empty( $display_post_types ) && ! $display_my_account ) {
            $is_allowed_on_page = apply_filters( 'storeagent_chat_widget_display_on_page', is_front_page() || is_shop() || is_product_category() || is_product_tag() || is_product() );
            return $is_allowed_on_page;
        }

        // Check if on My Account page and My Account display is enabled.
        if ( $this->is_my_account_page() ) {
            // My Account pages should only show widget for logged-in users.
            if ( $display_my_account && is_user_logged_in() ) {
                return true;
            }
            return false;
        }

        // Check if current post type is enabled in display settings.
        if ( $this->is_post_type_enabled( $display_post_types ) ) {
            return true;
        }

        return false;
    }

    /**
     * Check if current page/post is excluded from widget display.
     *
     * @since 1.1.2
     * @param array $settings Chat widget settings.
     * @return bool True if page is excluded, false otherwise.
     */
    private function is_page_excluded( $settings ) {
        $excluded_pages = ! empty( $settings['excluded_pages'] ) ? $settings['excluded_pages'] : array();

        if ( empty( $excluded_pages ) ) {
            return false;
        }

        // Get current page/post ID.
        $current_id = get_queried_object_id();

        // For singular posts/pages, check the post ID.
        if ( is_singular() ) {
            $post_id = get_the_ID();
            if ( $post_id && in_array( $post_id, $excluded_pages, true ) ) {
                return true;
            }
        }

        // Check queried object ID (works for pages, posts, and archives).
        if ( $current_id && in_array( $current_id, $excluded_pages, true ) ) {
            return true;
        }

        return false;
    }

    /**
     * Check if current post type is enabled in display settings.
     *
     * @param array $display_post_types Array of enabled post type slugs.
     * @return bool True if current post type is enabled, false otherwise.
     */
    private function is_post_type_enabled( $display_post_types ) {
        if ( empty( $display_post_types ) ) {
            return false;
        }

        // Check for singular post types.
        if ( is_singular() ) {
            $post_type = get_post_type();
            if ( $post_type && in_array( $post_type, $display_post_types, true ) ) {
                return true;
            }
        }

        // Check for post type archives.
        if ( is_post_type_archive() ) {
            $queried_object = get_queried_object();
            if ( $queried_object && isset( $queried_object->name ) ) {
                $post_type = $queried_object->name;
                if ( in_array( $post_type, $display_post_types, true ) ) {
                    return true;
                }
            }
        }

        // Check for specific WordPress conditions.
        // Front page can be a page or posts page.
        if ( is_front_page() ) {
            if ( in_array( 'page', $display_post_types, true ) && is_page() ) {
                return true;
            }
            if ( in_array( 'post', $display_post_types, true ) && is_home() ) {
                return true;
            }
        }

        // Check for blog home (posts page).
        if ( is_home() && ! is_front_page() && in_array( 'post', $display_post_types, true ) ) {
            return true;
        }

        // Check for singular posts (not blog home).
        if ( is_singular( 'post' ) && ! is_home() && in_array( 'post', $display_post_types, true ) ) {
            return true;
        }

        // Check for WooCommerce pages.
        if ( function_exists( 'is_shop' ) && is_shop() && in_array( 'product', $display_post_types, true ) ) {
            return true;
        }

        if ( function_exists( 'is_product_category' ) && is_product_category() && in_array( 'product', $display_post_types, true ) ) {
            return true;
        }

        if ( function_exists( 'is_product_tag' ) && is_product_tag() && in_array( 'product', $display_post_types, true ) ) {
            return true;
        }

        if ( function_exists( 'is_product' ) && is_product() && in_array( 'product', $display_post_types, true ) ) {
            return true;
        }

        return false;
    }

    /**
     * Check if current page is a WooCommerce My Account page.
     *
     * @return bool True if on My Account page, false otherwise.
     */
    private function is_my_account_page() {
        // Check if WooCommerce is active and is_account_page function exists.
        if ( function_exists( 'is_account_page' ) ) {
            return is_account_page();
        }

        return false;
    }

    /**
     * Get chat widget script url.
     *
     * @return string
     */
    public function get_chat_widget_script_url() {
        $script_url = apply_filters( 'storeagent_chat_widget_script_url', Helper::get_storeagent_base_url() . 'chat/chat.js' );

        if ( defined( 'STOREAGENT_CHAT_SCRIPT_URL' ) ) {
            $script_url = constant( 'STOREAGENT_CHAT_SCRIPT_URL' );
        }

        // Add version to script url so it's not cached by the browser.
        return add_query_arg( 'v', SAAI_VERSION, $script_url );
    }

    /**
     * Get inline chat widget script url.
     *
     * @return string
     */
    public function get_inline_chat_widget_script_url() {
        $script_url = apply_filters( 'storeagent_inline_chat_widget_script_url', Helper::get_storeagent_base_url() . 'chat/chat-inline.js' );

        if ( defined( 'STOREAGENT_INLINE_CHAT_SCRIPT_URL' ) ) {
            $script_url = constant( 'STOREAGENT_INLINE_CHAT_SCRIPT_URL' );
        }

        // Add version to script url so it's not cached by the browser.
        return add_query_arg( 'v', SAAI_VERSION, $script_url );
    }

    /**
     * Get current page context for chat widget.
     *
     * @return array
     */
    public function get_page_context() {
        $context = array(
            'title' => '',
            'type'  => '',
        );

        if ( is_product() ) {
            $context['type']  = 'product';
            $context['title'] = get_the_title();
        } elseif ( is_product_category() ) {
            $context['type']  = 'product_category';
            $context['title'] = single_cat_title( '', false );
        } elseif ( is_product_tag() ) {
            $context['type']  = 'product_tag';
            $context['title'] = single_tag_title( '', false );
        } elseif ( is_shop() ) {
            $context['type']  = 'shop';
            $context['title'] = woocommerce_page_title( false );
        } elseif ( is_front_page() ) {
            $context['type']  = 'front_page';
            $context['title'] = get_the_title();
        } elseif ( is_page() ) {
            $context['type']  = 'page';
            $context['title'] = get_the_title();
        } elseif ( is_home() ) {
            $context['type']  = 'blog_home';
            $context['title'] = get_the_title() ? get_the_title() : get_bloginfo( 'name' );
        } else {
            $context['type']  = 'other';
            $context['title'] = get_the_title() ? get_the_title() : get_bloginfo( 'name' );
        }

        return apply_filters( 'storeagent_chat_widget_page_context', $context );
    }

    /**
     * Display chat widget.
     */
    public function display_chat_widget() {
        if ( ! $this->should_display_chat_widget() ) {
            return;
        }

        // Get chat widget settings.
        $settings = Chat_Widget_Settings::get_chat_widget_settings();

        // Get feedback settings.
        $feedback_settings = \SAAI\Classes\Chat\Chat_Feedback::get_feedback_settings();

        // Create nonce for security.
        $nonce = wp_create_nonce( 'wp_rest' );

        // Get page context.
        $page_context = $this->get_page_context();

        // Output configuration and nonce for the frontend.
        echo '<script>window.storeagentChat = { 
			nonce: "' . esc_js( $nonce ) . '", 
			pageContext: {
				title: "' . esc_js( $page_context['title'] ) . '",
				type: "' . esc_js( $page_context['type'] ) . '"
			},
			feedbackTexts: {
				promptText: ' . wp_json_encode( $feedback_settings['feedback_prompt_text'] ) . ',
				skipButtonText: ' . wp_json_encode( $feedback_settings['skip_button_text'] ) . '
			}
		};</script>';

        echo '<style>
			storeagent-chat-widget {
				/* Brand colors */
				--chat-brand-primary: ' . esc_attr( $settings['brand_primary'] ) . ';
				--chat-brand-secondary: ' . esc_attr( $settings['brand_secondary'] ) . ';
				
				/* Layout & containers */
				--chat-container-bg: ' . esc_attr( $settings['container_bg'] ) . ';
				--chat-header-bg: ' . esc_attr( $settings['header_bg'] ) . ';
				--chat-input-bg: ' . esc_attr( $settings['input_bg'] ) . ';
				
				/* Interactive elements */
				--chat-trigger-bg: ' . esc_attr( $settings['trigger_bg'] ) . ';
				--chat-trigger-hover-bg: ' . esc_attr( $settings['trigger_hover_bg'] ) . ';
				--chat-send-button-bg: ' . esc_attr( $settings['send_button_bg'] ) . ';
				--chat-send-button-hover-bg: ' . esc_attr( $settings['send_button_hover_bg'] ) . ';
				--chat-online-indicator-bg: ' . esc_attr( $settings['online_indicator_bg'] ) . ';
				
				/* Messages */
				--chat-user-message-bg: ' . esc_attr( $settings['user_message_bg'] ) . ';
				--chat-ai-message-bg: ' . esc_attr( $settings['ai_message_bg'] ) . ';
				
				/* Typography */
				--chat-text-primary: ' . esc_attr( $settings['text_primary'] ) . ';
				--chat-text-secondary: ' . esc_attr( $settings['text_secondary'] ) . ';
				
				/* Input fields */
				--chat-input-border: ' . esc_attr( $settings['input_border'] ) . ';
				--chat-input-focus-border: ' . esc_attr( $settings['input_focus_border'] ) . ';
				
				/* Error states */
				--chat-error-bg: ' . esc_attr( $settings['error_bg'] ) . ';
				--chat-error-text: ' . esc_attr( $settings['error_text'] ) . ';
			}
		</style>';

        // Get device-specific positions with fallbacks.
        $position_tablet = ! empty( $settings['position_tablet'] ) ? $settings['position_tablet'] : $settings['position'];
        $position_mobile = ! empty( $settings['position_mobile'] ) ? $settings['position_mobile'] : $settings['position'];

        // Output custom web component with configuration.
        echo '<storeagent-chat-widget 
			chat-icon-color="' . esc_attr( $settings['chat_icon_color'] ) . '"
			position="' . esc_attr( $settings['position'] ) . '"
			position-tablet="' . esc_attr( $position_tablet ) . '"
			position-mobile="' . esc_attr( $position_mobile ) . '"
			greeting="' . esc_attr( $settings['greeting'] ) . '"
			placeholder="' . esc_attr( $settings['placeholder'] ) . '"
			assistant-name="' . esc_attr( $settings['assistant_name'] ) . '"
			avatar-acronym="' . esc_attr( $settings['avatar_acronym'] ) . '"
			status-text="' . esc_attr( $settings['status_text'] ) . '"'
            . ( ! empty( $settings['open_by_default'] ) ? ' open-by-default' : '' )
            . ( ! empty( $settings['open_by_default_tablet'] ) ? ' open-by-default-tablet' : '' )
            . ( ! empty( $settings['open_by_default_mobile'] ) ? ' open-by-default-mobile' : '' ) . '
		>
		</storeagent-chat-widget>';

        echo '<script type="module" src="' . esc_url( $this->get_chat_widget_script_url() ) . '" defer></script>'; // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
    }

    /**
     * Output chat configuration in admin for testing purposes.
     * This allows the chat widget to work in the admin settings page.
     */
    public function output_chat_config_in_admin() {
        // Only output on StoreAgent settings page.
        $screen = get_current_screen();
        if ( ! $screen || 'storeagent_page_storeagent-settings' !== $screen->id ) {
            return;
        }

        // Create nonce for security.
        $nonce           = wp_create_nonce( 'wp_rest' );
        $shop_page       = wc_get_page_id( 'shop' );
        $shop_page_title = $shop_page ? get_the_title( $shop_page ) : __( 'Shop', 'storeagent-ai-for-woocommerce' );

        // Use shop page context for admin testing.
        $page_context = array(
            'title' => $shop_page_title,
            'type'  => 'shop',
        );

        // Output configuration and nonce for the admin.
        echo '<script>window.storeagentChat = { 
            nonce: "' . esc_js( $nonce ) . '", 
            pageContext: {
                title: "' . esc_js( $page_context['title'] ) . '",
                type: "' . esc_js( $page_context['type'] ) . '"
            }
        };</script>';
    }

    /**
     * Display inline chat widget via shortcode.
     *
     * @param array $atts Shortcode attributes.
     * @return string
     */
    public function display_inline_chat_shortcode( $atts = array() ) {
        // Parse shortcode attributes with defaults.
        $atts = shortcode_atts(
            array(
                'width'  => '100%',
                'height' => '500px',
                'class'  => '',
            ),
            $atts,
            'storeagent_chat'
        );

        // Check if chat is allowed for current user.
        if ( ! Plan_Manager::instance()->is_chat_allowed_for_current_user() ) {
            return '';
        }

        // Enqueue scripts for inline chat.
        $this->enqueue_inline_chat_scripts();

        // Get chat widget settings.
        $settings = Chat_Widget_Settings::get_chat_widget_settings();

        // Create nonce for security.
        $nonce = wp_create_nonce( 'wp_rest' );

        // Get page context.
        $page_context = $this->get_page_context();

        // Generate unique ID for this chat instance.
        $chat_id = 'storeagent-inline-chat-' . wp_rand( 1000, 9999 );

        // Load template file.
        return $this->load_inline_chat_template( compact( 'atts', 'settings', 'nonce', 'page_context', 'chat_id' ) );
    }

    /**
     * Load inline chat template with variables.
     *
     * @param array $variables Template variables.
     * @return string
     */
    private function load_inline_chat_template( $variables ) {
        // Extract variables for use in template.
        extract( $variables ); // phpcs:ignore WordPress.PHP.DontExtract.extract_extract

        // Start output buffering.
        ob_start();

        // Try to load custom template first (for theme overrides).
        $custom_template = locate_template( 'storeagent-ai/inline-chat-widget.php' );

        if ( $custom_template ) {
            // Load custom template from theme.
            include $custom_template;
        } else {
            // Load default plugin template.
            $plugin_template = SAAI_TEMPLATES_DIR . 'frontend/inline-chat-widget.php';

            if ( file_exists( $plugin_template ) ) {
                include $plugin_template;
            } else {
                // Fallback if template file doesn't exist.
                return '<div class="storeagent-error">Chat widget template not found.</div>';
            }
        }

        return ob_get_clean();
    }

    /**
     * Enqueue scripts and styles for inline chat.
     */
    public function enqueue_inline_chat_scripts() {
        static $scripts_enqueued = false;

        if ( $scripts_enqueued ) {
            return;
        }

        // Add script to head or footer.
        add_action( 'wp_footer', array( $this, 'output_inline_chat_script' ), 5 );

        $scripts_enqueued = true;
    }

    /**
     * Output inline chat script.
     */
    public function output_inline_chat_script() {
        echo '<script type="module" src="' . esc_url( $this->get_inline_chat_widget_script_url() ) . '"></script>'; // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
    }
}
