<?php
/**
 * Content Extractor - Extracts clean text from pages/posts.
 *
 * @package BoostBot
 * @since   1.1.0
 */

// Prevent direct access
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Class BoostBot_Content_Extractor
 *
 * Extracts clean text content from posts, pages, and products.
 * Supports Elementor content extraction.
 *
 * @since 1.1.0
 */
class BoostBot_Content_Extractor {

    /**
     * Text fields to look for in Elementor data.
     *
     * @var array
     */
    private $elementor_text_fields = array(
        'title',
        'heading',
        'text',
        'content',
        'description',
        'editor',
        'text_editor',
        'tab_title',
        'tab_content',
        'item_text',
        'price',
        'currency_symbol',
        'original_price',
        'product_description',
        'faq_question',
        'faq_answer',
        'testimonial_content',
        'testimonial_name',
        'testimonial_job',
        'alert_description',
        'counter_title',
        'string',
        'product_title',
        'product_short_description',
        'button_text',
        'link_text',
        'list_item',
    );

    /**
     * Extract clean text content from a post/page.
     *
     * @param int $post_id The post ID.
     * @return string The clean text content.
     */
    public function extract( $post_id ) {
        $post = get_post( $post_id );

        if ( ! $post ) {
            return '';
        }

        $content = '';

        // 1. Try Elementor content first
        if ( $this->is_elementor_page( $post_id ) ) {
            $content = $this->extract_elementor_content( $post_id );
        }

        // 2. Fallback to regular content
        if ( empty( $content ) ) {
            $content = $post->post_content;
        }

        // 3. Process the content
        $content = $this->clean_content( $content );

        // 4. Add metadata
        $content = $this->add_metadata( $post, $content );

        return $content;
    }

    /**
     * Check if page is built with Elementor.
     *
     * @param int $post_id The post ID.
     * @return bool True if Elementor page.
     */
    private function is_elementor_page( $post_id ) {
        // Check if Elementor is active
        if ( ! class_exists( '\Elementor\Plugin' ) ) {
            return false;
        }

        // Check if post was built with Elementor
        $document = \Elementor\Plugin::$instance->documents->get( $post_id );
        
        if ( ! $document ) {
            return false;
        }

        return $document->is_built_with_elementor();
    }

    /**
     * Extract content from Elementor.
     *
     * @param int $post_id The post ID.
     * @return string The Elementor content.
     */
    private function extract_elementor_content( $post_id ) {
        if ( ! class_exists( '\Elementor\Plugin' ) ) {
            return '';
        }

        // Parse Elementor data directly (more reliable for text)
        $elementor_data = get_post_meta( $post_id, '_elementor_data', true );

        if ( ! empty( $elementor_data ) ) {
            $data = json_decode( $elementor_data, true );
            if ( is_array( $data ) ) {
                $text_content = $this->extract_text_from_elementor_data( $data );
                if ( ! empty( $text_content ) ) {
                    return $text_content;
                }
            }
        }

        // Fallback: Get rendered content
        $frontend = \Elementor\Plugin::$instance->frontend;
        $content  = $frontend->get_builder_content_for_display( $post_id );

        return $content;
    }

    /**
     * Recursively extract text from Elementor JSON data.
     *
     * @param array $elements The elements array.
     * @return string The extracted text.
     */
    private function extract_text_from_elementor_data( $elements ) {
        $text = array();

        foreach ( $elements as $element ) {
            // Extract text from widget settings
            if ( isset( $element['settings'] ) && is_array( $element['settings'] ) ) {
                $settings = $element['settings'];

                // Check common text fields
                foreach ( $this->elementor_text_fields as $field ) {
                    if ( ! empty( $settings[ $field ] ) && is_string( $settings[ $field ] ) ) {
                        $clean = wp_strip_all_tags( $settings[ $field ] );
                        $clean = trim( $clean );
                        if ( ! empty( $clean ) && strlen( $clean ) > 2 ) {
                            $text[] = $clean;
                        }
                    }
                }

                // Handle repeater fields (like lists, tabs, etc.)
                foreach ( $settings as $key => $value ) {
                    if ( is_array( $value ) && ! empty( $value ) ) {
                        foreach ( $value as $item ) {
                            if ( is_array( $item ) ) {
                                foreach ( $this->elementor_text_fields as $field ) {
                                    if ( ! empty( $item[ $field ] ) && is_string( $item[ $field ] ) ) {
                                        $clean = wp_strip_all_tags( $item[ $field ] );
                                        $clean = trim( $clean );
                                        if ( ! empty( $clean ) && strlen( $clean ) > 2 ) {
                                            $text[] = $clean;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // Recurse into child elements
            if ( ! empty( $element['elements'] ) && is_array( $element['elements'] ) ) {
                $child_text = $this->extract_text_from_elementor_data( $element['elements'] );
                if ( ! empty( $child_text ) ) {
                    $text[] = $child_text;
                }
            }
        }

        return implode( "\n\n", array_filter( $text ) );
    }

    /**
     * Clean HTML content to plain text.
     *
     * @param string $content The HTML content.
     * @return string Clean text.
     */
    private function clean_content( $content ) {
        if ( empty( $content ) ) {
            return '';
        }

        // Remove scripts and styles
        $content = preg_replace( '/<script\b[^>]*>(.*?)<\/script>/is', '', $content );
        $content = preg_replace( '/<style\b[^>]*>(.*?)<\/style>/is', '', $content );

        // Remove shortcodes
        $content = strip_shortcodes( $content );

        // Convert common HTML elements to line breaks
        $content = str_replace( array( '<br>', '<br/>', '<br />' ), "\n", $content );
        $content = str_replace( array( '</p>', '</div>', '</li>' ), "\n", $content );
        $content = str_replace( array( '<h1>', '<h2>', '<h3>', '<h4>', '<h5>', '<h6>' ), "\n\n", $content );
        $content = str_replace( array( '</h1>', '</h2>', '</h3>', '</h4>', '</h5>', '</h6>' ), "\n", $content );

        // Strip remaining HTML
        $content = wp_strip_all_tags( $content );

        // Decode HTML entities
        $content = html_entity_decode( $content, ENT_QUOTES, 'UTF-8' );

        // Clean up whitespace
        $content = preg_replace( '/[ \t]+/', ' ', $content );
        $content = preg_replace( '/\n\s*\n/', "\n\n", $content );
        $content = trim( $content );

        return $content;
    }

    /**
     * Add metadata to content.
     *
     * @param WP_Post $post    The post object.
     * @param string  $content The content.
     * @return string Content with metadata.
     */
    private function add_metadata( $post, $content ) {
        $meta = array();

        // Title
        $meta[] = 'כותרת: ' . $post->post_title;

        // URL
        $meta[] = 'קישור: ' . urldecode( get_permalink( $post->ID ) );

        // Post type
        $post_type_obj = get_post_type_object( $post->post_type );
        if ( $post_type_obj ) {
            $meta[] = 'סוג: ' . $post_type_obj->labels->singular_name;
        }

        // WooCommerce product data
        if ( 'product' === $post->post_type && function_exists( 'wc_get_product' ) ) {
            $product = wc_get_product( $post->ID );
            if ( $product ) {
                // Price
                $price = $product->get_price();
                if ( $price ) {
                    $meta[] = 'מחיר: ₪' . number_format( (float) $price, 2 );
                }

                // Sale price
                if ( $product->is_on_sale() ) {
                    $meta[] = 'מחיר מקורי: ₪' . number_format( (float) $product->get_regular_price(), 2 );
                    $meta[] = 'מחיר מבצע: ₪' . number_format( (float) $product->get_sale_price(), 2 );
                }

                // Stock
                $meta[] = 'מלאי: ' . ( $product->is_in_stock() ? 'במלאי' : 'אזל מהמלאי' );

                // SKU
                $sku = $product->get_sku();
                if ( $sku ) {
                    $meta[] = 'מק"ט: ' . $sku;
                }

                // Categories
                $cats = wc_get_product_category_list( $product->get_id(), ', ' );
                if ( $cats ) {
                    $meta[] = 'קטגוריות: ' . wp_strip_all_tags( $cats );
                }

                // Attributes/Specs
                $attributes = $product->get_attributes();
                foreach ( $attributes as $attr ) {
                    if ( is_object( $attr ) && method_exists( $attr, 'get_name' ) ) {
                        $name   = wc_attribute_label( $attr->get_name() );
                        $values = $attr->get_options();
                        if ( is_array( $values ) && ! empty( $values ) ) {
                            // Get term names if taxonomy attribute
                            if ( $attr->is_taxonomy() ) {
                                $term_names = array();
                                foreach ( $values as $term_id ) {
                                    $term = get_term( $term_id );
                                    if ( $term && ! is_wp_error( $term ) ) {
                                        $term_names[] = $term->name;
                                    }
                                }
                                $values = $term_names;
                            }
                            $meta[] = $name . ': ' . implode( ', ', $values );
                        }
                    }
                }

                // Short description
                $short_desc = $product->get_short_description();
                if ( $short_desc ) {
                    $meta[] = 'תיאור קצר: ' . wp_strip_all_tags( $short_desc );
                }
            }
        }

        // Categories for posts
        if ( 'post' === $post->post_type ) {
            $categories = get_the_category( $post->ID );
            if ( $categories ) {
                $cat_names = wp_list_pluck( $categories, 'name' );
                $meta[]    = 'קטגוריות: ' . implode( ', ', $cat_names );
            }
        }

        // Combine metadata with content
        $metadata_text = implode( "\n", $meta );

        if ( empty( $content ) ) {
            return "=== מידע על העמוד ===\n{$metadata_text}";
        }

        return "=== מידע על העמוד ===\n{$metadata_text}\n\n=== תוכן העמוד ===\n{$content}";
    }

    /**
     * Get full content for a page (for chat context).
     *
     * @param int $post_id The post ID.
     * @return array Content data.
     */
    public function get_page_context( $post_id ) {
        $post = get_post( $post_id );

        if ( ! $post ) {
            return array();
        }

        $full_content = $this->extract( $post_id );

        return array(
            'post_id'      => $post_id,
            'title'        => $post->post_title,
            'url'          => urldecode( get_permalink( $post_id ) ),
            'post_type'    => $post->post_type,
            'full_content' => $full_content,
            'excerpt'      => wp_trim_words( $full_content, 150, '...' ),
        );
    }
}








