<?php

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

class Cornerstone extends Editors
{
    const META_KEY = '_cornerstone_data';
    private $extracted_data = '';
    public function __construct($post_id)
    {
        $this->post_id = $post_id;
        $content = get_post_meta($post_id, self::META_KEY, \true);
        if (gettype($content) !== 'string') {
            $content = '[]';
        }
        $this->content = json_decode($content);
    }
    public static function is_active($post_id): bool
    {
        // return true if there's cornerstone data
        return !empty(get_post_meta($post_id, self::META_KEY, \true));
    }
    private function handle_block_ops(&$block_content, $op_code)
    {
        switch ($op_code) {
            case self::OP_CODES['EXTRACT_CONTENT']:
                $found = preg_match('/^<(\w+).*?>.*?<\/\1>$/m', $block_content, $matches);
                // add extracted block content. Put the content in a div if not in a div.
                $this->extracted_data .= !$found ? "<div>{$block_content}</div>\n" : "{$block_content}\n";
                break;
            case self::OP_CODES['ADD_LINK']:
                // add the link to the content
                $this->add_link_to_block($block_content);
                break;
            case self::OP_CODES['REMOVE_LINK']:
                $this->remove_link_from_block($block_content);
                break;
            case self::OP_CODES['REPLACE_LINK']:
                $this->replace_link_in_block($block_content);
                break;
            default:
                break;
        }
        return $this->link_processed;
    }
    private function extract_content(&$data, $op_code = self::OP_CODES['EXTRACT_CONTENT'])
    {
        foreach ($data as &$block) {
            if (isset($block->_modules) && !empty($block->_modules)) {
                $this->extract_content($block->_modules, $op_code);
            }
            if (in_array($block->_type, ['text'])) {
                foreach (['text_content'] as $content_key) {
                    if (isset($block->{$content_key})) {
                        $this->handle_block_ops($block->{$content_key}, $op_code);
                    }
                }
            }
            if (in_array($block->_type, ['accordion', 'tabs'])) {
                if (isset($block->_modules)) {
                    foreach ($block->_modules as $item) {
                        if (isset($item->_modules)) {
                            $this->extract_content($item->_modules, $op_code);
                        }
                    }
                }
            }
        }
    }
    public function get_content($post_id): string
    {
        $this->extracted_data = '';
        // extract content from supported blocks
        if (is_countable($this->content)) {
            $this->extract_content($this->content);
        }
        return $this->extracted_data;
    }
    public function add_link($source, $phrase, $phrase_replacement): bool
    {
        $this->params = ['source' => $source, 'phrase' => $phrase, 'replacement' => $phrase_replacement];
        $this->link_processed = \false;
        // insert link into content
        $this->extract_content($this->content, self::OP_CODES['ADD_LINK']);
        if ($this->link_processed) {
            $this->has_unsaved_changes = \true;
            return \true;
        }
        return \false;
    }
    public function update_post($suggestions = null): bool
    {
        $success = \false;
        if ($this->has_unsaved_changes) {
            $cs_data = addslashes(wp_json_encode($this->content));
            $success = update_post_meta($this->post_id, self::META_KEY, $cs_data) !== \false;
            if ($success) {
                $this->has_unsaved_changes = \false;
                // sync changes with wp post content
                $this->after_update_post($suggestions);
            }
        }
        return $success;
    }
    public function remove_link(string $link, string $anchor, $save = \true): bool
    {
        $this->link_processed = \false;
        // set the params for link removal
        $this->params = ['link' => $link, 'anchor' => $anchor];
        // remove link from content
        $this->extract_content($this->content, self::OP_CODES['REMOVE_LINK']);
        if ($this->link_processed) {
            $this->has_unsaved_changes = \true;
            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 the params that will be used to replace the link
        $this->params = ['link' => $link, 'anchor' => $phrase, 'link_replacement' => $replacement];
        $this->extract_content($this->content, self::OP_CODES['REPLACE_LINK']);
        if ($this->link_processed) {
            $this->has_unsaved_changes = \true;
            if ($save) {
                return $this->update_post();
            }
            return \true;
        }
        return \false;
    }
}
