<?php
/**
 * Elementor Content Parser
 *
 * Extracts clean text content from Elementor's data structure.
 *
 * @package BoostBot
 * @since   1.0.0
 */

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

/**
 * Class BoostBot_Elementor_Parser
 *
 * Parser for extracting content from Elementor pages.
 */
class BoostBot_Elementor_Parser {

    /**
     * Extract content from Elementor page.
     *
     * @param int $post_id Post ID.
     * @return string|null Extracted content or null.
     */
    public function extract_content( int $post_id ): ?string {
        // Check if post uses Elementor.
        if ( ! $this->is_elementor_page( $post_id ) ) {
            return null;
        }

        // Get Elementor data.
        $elementor_data = get_post_meta( $post_id, '_elementor_data', true );

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

        $data = json_decode( $elementor_data, true );

        if ( ! is_array( $data ) ) {
            return null;
        }

        $content = array(
            'text'    => array(),
            'headers' => array(),
            'lists'   => array(),
            'links'   => array(),
            'images'  => array(),
            'prices'  => array(),
        );

        $this->parse_elements( $data, $content );

        return $this->format_content( $content );
    }

    /**
     * Check if page is built with Elementor.
     *
     * @param int $post_id Post ID.
     * @return bool True if Elementor page.
     */
    public function is_elementor_page( int $post_id ): bool {
        return get_post_meta( $post_id, '_elementor_edit_mode', true ) === 'builder';
    }

    /**
     * Recursively parse Elementor elements.
     *
     * @param array $elements Elements array.
     * @param array $content  Content array (by reference).
     */
    private function parse_elements( array $elements, array &$content ): void {
        foreach ( $elements as $element ) {
            $this->parse_element( $element, $content );

            // Parse nested elements.
            if ( ! empty( $element['elements'] ) ) {
                $this->parse_elements( $element['elements'], $content );
            }
        }
    }

    /**
     * Parse a single Elementor element.
     *
     * @param array $element Element data.
     * @param array $content Content array (by reference).
     */
    private function parse_element( array $element, array &$content ): void {
        $widget_type = $element['widgetType'] ?? $element['elType'] ?? '';
        $settings    = $element['settings'] ?? array();

        switch ( $widget_type ) {
            case 'heading':
                $text = $this->clean_text( $settings['title'] ?? '' );
                if ( $text ) {
                    $tag               = $settings['header_size'] ?? 'h2';
                    $content['headers'][] = array(
                        'level' => $this->get_heading_level( $tag ),
                        'text'  => $text,
                    );
                }
                break;

            case 'text-editor':
                $text = $this->clean_html( $settings['editor'] ?? '' );
                if ( $text ) {
                    $content['text'][] = $text;
                }
                break;

            case 'icon-list':
                $items = $settings['icon_list'] ?? array();
                $list  = array();
                foreach ( $items as $item ) {
                    $text = $this->clean_text( $item['text'] ?? '' );
                    if ( $text ) {
                        $list[] = $text;
                    }
                }
                if ( ! empty( $list ) ) {
                    $content['lists'][] = $list;
                }
                break;

            case 'button':
                $text = $this->clean_text( $settings['text'] ?? '' );
                $link = $settings['link']['url'] ?? '';
                if ( $text && $link ) {
                    $content['links'][] = array(
                        'text' => $text,
                        'url'  => $link,
                    );
                }
                break;

            case 'image':
                $url     = $settings['image']['url'] ?? '';
                $alt     = $settings['image']['alt'] ?? '';
                $caption = $settings['caption'] ?? '';
                if ( $url ) {
                    $content['images'][] = array(
                        'url'     => $url,
                        'alt'     => $alt,
                        'caption' => $caption,
                    );
                }
                break;

            case 'price-table':
                $this->parse_price_table( $settings, $content );
                break;

            case 'price-list':
                $this->parse_price_list( $settings, $content );
                break;

            case 'toggle':
            case 'accordion':
                $this->parse_accordion( $settings, $content );
                break;

            case 'tabs':
                $this->parse_tabs( $settings, $content );
                break;

            case 'testimonial':
                $this->parse_testimonial( $settings, $content );
                break;

            case 'call-to-action':
                $this->parse_cta( $settings, $content );
                break;
        }
    }

    /**
     * Parse price table widget.
     *
     * @param array $settings Widget settings.
     * @param array $content  Content array (by reference).
     */
    private function parse_price_table( array $settings, array &$content ): void {
        $price    = $settings['price'] ?? '';
        $title    = $settings['heading'] ?? '';
        $period   = $settings['period'] ?? '';
        $features = $settings['features_list'] ?? array();

        if ( $title ) {
            $content['headers'][] = array(
                'level' => 3,
                'text'  => $title,
            );
        }

        if ( $price ) {
            $price_text = $price;
            if ( $period ) {
                $price_text .= ' / ' . $period;
            }
            $content['prices'][] = $price_text;
            $content['text'][]   = sprintf( 'מחיר: %s', $price_text );
        }

        $feature_list = array();
        foreach ( $features as $feature ) {
            $text = $this->clean_text( $feature['item_text'] ?? '' );
            if ( $text ) {
                $feature_list[] = $text;
            }
        }
        if ( ! empty( $feature_list ) ) {
            $content['lists'][] = $feature_list;
        }
    }

    /**
     * Parse price list widget.
     *
     * @param array $settings Widget settings.
     * @param array $content  Content array (by reference).
     */
    private function parse_price_list( array $settings, array &$content ): void {
        $items = $settings['price_list'] ?? array();

        foreach ( $items as $item ) {
            $title       = $this->clean_text( $item['title'] ?? '' );
            $price       = $item['price'] ?? '';
            $description = $this->clean_text( $item['item_description'] ?? '' );

            if ( $title && $price ) {
                $content['text'][] = sprintf( '%s - %s', $title, $price );
                if ( $description ) {
                    $content['text'][] = $description;
                }
            }
        }
    }

    /**
     * Parse accordion/toggle widget.
     *
     * @param array $settings Widget settings.
     * @param array $content  Content array (by reference).
     */
    private function parse_accordion( array $settings, array &$content ): void {
        $tabs = $settings['tabs'] ?? array();

        foreach ( $tabs as $tab ) {
            $title   = $this->clean_text( $tab['tab_title'] ?? '' );
            $tabcontent = $this->clean_html( $tab['tab_content'] ?? '' );

            if ( $title ) {
                $content['headers'][] = array(
                    'level' => 4,
                    'text'  => $title,
                );
            }
            if ( $tabcontent ) {
                $content['text'][] = $tabcontent;
            }
        }
    }

    /**
     * Parse tabs widget.
     *
     * @param array $settings Widget settings.
     * @param array $content  Content array (by reference).
     */
    private function parse_tabs( array $settings, array &$content ): void {
        $tabs = $settings['tabs'] ?? array();

        foreach ( $tabs as $tab ) {
            $title      = $this->clean_text( $tab['tab_title'] ?? '' );
            $tabcontent = $this->clean_html( $tab['tab_content'] ?? '' );

            if ( $title ) {
                $content['headers'][] = array(
                    'level' => 4,
                    'text'  => $title,
                );
            }
            if ( $tabcontent ) {
                $content['text'][] = $tabcontent;
            }
        }
    }

    /**
     * Parse testimonial widget.
     *
     * @param array $settings Widget settings.
     * @param array $content  Content array (by reference).
     */
    private function parse_testimonial( array $settings, array &$content ): void {
        $text = $this->clean_text( $settings['testimonial_content'] ?? '' );
        $name = $this->clean_text( $settings['testimonial_name'] ?? '' );
        $job  = $this->clean_text( $settings['testimonial_job'] ?? '' );

        if ( $text ) {
            $testimonial = '"' . $text . '"';
            if ( $name ) {
                $testimonial .= ' - ' . $name;
                if ( $job ) {
                    $testimonial .= ', ' . $job;
                }
            }
            $content['text'][] = $testimonial;
        }
    }

    /**
     * Parse CTA widget.
     *
     * @param array $settings Widget settings.
     * @param array $content  Content array (by reference).
     */
    private function parse_cta( array $settings, array &$content ): void {
        $title       = $this->clean_text( $settings['title'] ?? '' );
        $description = $this->clean_text( $settings['description'] ?? '' );
        $button_text = $this->clean_text( $settings['button'] ?? '' );
        $button_link = $settings['link']['url'] ?? '';

        if ( $title ) {
            $content['headers'][] = array(
                'level' => 3,
                'text'  => $title,
            );
        }
        if ( $description ) {
            $content['text'][] = $description;
        }
        if ( $button_text && $button_link ) {
            $content['links'][] = array(
                'text' => $button_text,
                'url'  => $button_link,
            );
        }
    }

    /**
     * Format extracted content to clean text.
     *
     * @param array $content Extracted content.
     * @return string Formatted content.
     */
    private function format_content( array $content ): string {
        $output = array();

        // Add headers.
        foreach ( $content['headers'] as $header ) {
            $prefix   = str_repeat( '#', $header['level'] ) . ' ';
            $output[] = $prefix . $header['text'];
        }

        // Add text paragraphs.
        foreach ( $content['text'] as $text ) {
            $output[] = $text;
        }

        // Add lists.
        foreach ( $content['lists'] as $list ) {
            foreach ( $list as $item ) {
                $output[] = '• ' . $item;
            }
        }

        // Add links (if important).
        if ( ! empty( $content['links'] ) ) {
            $output[] = '';
            $output[] = 'קישורים:';
            foreach ( $content['links'] as $link ) {
                $output[] = '• ' . $link['text'] . ': ' . $link['url'];
            }
        }

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

    /**
     * Clean HTML to plain text.
     *
     * @param string $html HTML content.
     * @return string Clean text.
     */
    private function clean_html( string $html ): string {
        // Remove scripts and styles.
        $html = preg_replace( '/<script\b[^>]*>.*?<\/script>/is', '', $html );
        $html = preg_replace( '/<style\b[^>]*>.*?<\/style>/is', '', $html );

        // Convert <br> and </p> to newlines.
        $html = preg_replace( '/<br\s*\/?>/i', "\n", $html );
        $html = preg_replace( '/<\/p>/i', "\n", $html );

        // Strip remaining HTML.
        $text = wp_strip_all_tags( $html );

        // Decode entities.
        $text = html_entity_decode( $text, ENT_QUOTES, 'UTF-8' );

        // Clean whitespace.
        $text = preg_replace( '/\s+/', ' ', $text );
        $text = trim( $text );

        return $text;
    }

    /**
     * Clean text.
     *
     * @param string $text Text to clean.
     * @return string Clean text.
     */
    private function clean_text( string $text ): string {
        $text = wp_strip_all_tags( $text );
        $text = html_entity_decode( $text, ENT_QUOTES, 'UTF-8' );
        return trim( $text );
    }

    /**
     * Get heading level from tag.
     *
     * @param string $tag HTML tag.
     * @return int Heading level.
     */
    private function get_heading_level( string $tag ): int {
        $levels = array(
            'h1' => 1,
            'h2' => 2,
            'h3' => 3,
            'h4' => 4,
            'h5' => 5,
            'h6' => 6,
        );
        return $levels[ strtolower( $tag ) ] ?? 2;
    }
}







