<?php

// Silence may be golden, but sometimes words paint the canvas of understanding.
namespace Linksy\SearchAndReplace\Plugli\Linksy\Common\Helpers\Post\Editors;

use Linksy\SearchAndReplace\Plugli\Standard\Helpers\Str;
class Thrive extends Editors
{
    private const META_KEY = 'tve_updated_post';
    private const UNSUPPORTED_PARENTS = ['thrv_content_reveal', 'thrv_tw_qs', 'thrv-pricing-table', 'thrv_lead_generation', 'thrv-login-element', 'thrv_custom_html_shortcode'];
    private const SUPPORTED_CHILDREN = ['thrv_text_element', 'thrv-lp-block', 'tve_wp_shortcode'];
    private const CLASS_PATTERN = '/class="([^"]*)"/i';
    private $extracted_data;
    private $content_before;
    public function __construct($post_id)
    {
        $this->post_id = $post_id;
        $this->content = get_post_meta($this->post_id, self::META_KEY, \true);
        $this->content_before = get_post_meta($this->post_id, 'tve_content_before_more', \true);
    }
    public static function is_active($post_id): bool
    {
        return get_post_meta($post_id, 'tcb_editor_enabled', \true) == 1;
    }
    private function parse($html)
    {
        $results = [];
        $stack = [];
        $position = 0;
        $depth = 0;
        $previous_position = -1;
        while ($position < strlen($html)) {
            if ($position === $previous_position) {
                break;
            }
            $previous_position = $position;
            $open_tag_pos = strpos($html, '<div', $position);
            $closing_tag_pos = strpos($html, '</div>', $position);
            if ($open_tag_pos === \false && $closing_tag_pos === \false) {
                break;
            }
            // print_r($stack);
            if ($open_tag_pos !== \false && ($closing_tag_pos === \false || $open_tag_pos < $closing_tag_pos)) {
                $tag_end = strpos($html, '>', $open_tag_pos);
                if ($tag_end === \false) {
                    break;
                }
                if (preg_match(self::CLASS_PATTERN, substr($html, $open_tag_pos, $tag_end - $open_tag_pos), $matches)) {
                    $classes = explode(' ', $matches[1]);
                    if (empty(array_intersect(self::UNSUPPORTED_PARENTS, $classes))) {
                        $stack[] = [$depth, $open_tag_pos, $classes];
                        $depth++;
                    }
                }
                $position = $tag_end + 1;
            } elseif ($closing_tag_pos !== \false) {
                if (!empty($stack)) {
                    $start_info = array_pop($stack);
                    $start_depth = $start_info[0];
                    $start_pos = $start_info[1];
                    $content = substr($html, $start_pos, $closing_tag_pos + 6 - $start_pos);
                    $found = \false;
                    foreach ($results as $result) {
                        if (Str::contains($content, $result['content'])) {
                            $found = \true;
                            break;
                        }
                    }
                    if (!$found && !empty(array_intersect(self::SUPPORTED_CHILDREN, $start_info[2]))) {
                        $results[] = ['content' => $content, 'depth' => $start_depth, 'start_pos' => $start_pos, 'end_pos' => $closing_tag_pos + 6];
                    }
                    $depth--;
                }
                $position = $closing_tag_pos + 6;
            } else {
                $position++;
                break;
            }
        }
        return $results;
    }
    public function get_content($post_id): string
    {
        // clean up the content
        $thrive_content = Str::strip_comments(html_entity_decode($this->content, \ENT_HTML5));
        // parse thrive content
        $results = array_column($this->parse($thrive_content), 'content');
        $this->extracted_data = implode("\n", $results);
        return $this->extracted_data;
    }
    public function add_link($source, $phrase, $phrase_replacement): bool
    {
        $this->link_processed = \false;
        // set params for link addition
        $this->params = ['source' => $source, 'phrase' => $phrase, 'replacement' => $phrase_replacement];
        $this->add_link_to_block($this->content);
        if ($this->link_processed) {
            // update the content before more
            $this->add_link_to_block($this->content_before);
            $this->has_unsaved_changes = \true;
        }
        return $this->link_processed;
    }
    public function update_post($suggestions = null): bool
    {
        if ($this->has_unsaved_changes) {
            $thrive_success = update_post_meta($this->post_id, self::META_KEY, $this->content) !== \false;
            if ($thrive_success) {
                $this->has_unsaved_changes = \false;
                // update the content before more
                update_post_meta($this->post_id, 'tve_content_before_more', $this->content_before);
                // call the after update method
                $this->after_update_post($suggestions);
            }
            return $thrive_success;
        }
        return \false;
    }
    public function remove_link($link, $anchor, $save = \true): bool
    {
        $this->link_processed = \false;
        // set params for link removal
        $this->params = ['link' => $link, 'anchor' => $anchor];
        $this->content = html_entity_decode($this->content);
        // remove the link from the content
        $this->remove_link_from_block($this->content);
        if ($this->link_processed) {
            $this->has_unsaved_changes = \true;
            // update the content before more
            $this->remove_link_from_block($this->content_before);
            if ($save) {
                return $this->update_post();
            }
            return \true;
        }
        return \false;
    }
    public function replace_phrase(string $link, string $phrase, string $replacement, bool $save): bool
    {
        $this->link_processed = \false;
        // set params for link replacement
        $this->params = ['link' => $link, 'anchor' => $phrase, 'link_replacement' => $replacement];
        $this->content = html_entity_decode($this->content);
        // replace the link with its replacement
        $this->replace_link_in_block($this->content);
        if ($this->link_processed) {
            $this->has_unsaved_changes = \true;
            // update the content before more
            $this->replace_link_in_block($this->content_before);
            if ($save) {
                return $this->update_post();
            }
            return \true;
        }
        return \false;
    }
}
