<?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\Linksy\Common\Helpers\Utils;
class Muffin extends Editors
{
    const META_KEY = 'mfn-page-items';
    const SUPPORTED_BLOCKS = ['column', 'plain_text', 'accordion', 'faq', 'feature_box', 'feature_list', 'flat_box', 'helper', 'icon_box', 'info_box', 'list_2', 'list', 'tabs', 'toggle', 'visual', 'blockquote'];
    private $extracted_data = '';
    public function __construct($post_id)
    {
        $this->post_id = $post_id;
        $this->content = get_post_meta($post_id, self::META_KEY, \true);
    }
    public static function is_active($post_id): bool
    {
        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']:
                $this->extracted_data .= wpautop($block_content) . "\n";
                break;
            case self::OP_CODES['ADD_LINK']:
                $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 $block_content;
    }
    private function extract_content($block, $op_code = self::OP_CODES['EXTRACT_CONTENT'])
    {
        if (isset($block['type']) && in_array($block['type'], self::SUPPORTED_BLOCKS)) {
            if (isset($block['attr']) && !empty($block['attr'])) {
                foreach (['content', 'content1'] as $prop) {
                    if (!empty($block['attr'][$prop])) {
                        $block['attr'][$prop] = $this->handle_block_ops($block['attr'][$prop], $op_code);
                    }
                }
                if (isset($block['attr']['tabs']) && is_array($block['attr']['tabs'])) {
                    foreach ($block['attr']['tabs'] as $idx => $tab) {
                        if (isset($tab['content'])) {
                            $block['attr']['tabs'][$idx]['content'] = $this->handle_block_ops($tab['content'], $op_code);
                        }
                    }
                }
            }
        }
        // get the children of the current block if it exists
        $block_children = isset($block['wraps']) ? $block['wraps'] : $block['items'] ?? [];
        foreach ($block_children as $idx => $child) {
            $block_children[$idx] = $this->extract_content($child, $op_code);
        }
        if ($this->link_processed) {
            if (isset($block['wraps'])) {
                $block['wraps'] = $block_children;
            } else {
                $block['items'] = $block_children;
            }
        }
        return $block;
    }
    public function get_content($post_id): string
    {
        $this->extracted_data = '';
        if (is_countable($this->content)) {
            foreach ($this->content as $block) {
                // extract content from block if supported
                $this->extract_content($block);
            }
        }
        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];
        if (is_countable($this->content)) {
            foreach ($this->content as $key => $block) {
                // update the original content with the new content
                $this->content[$key] = $this->extract_content($block, 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) {
            $success = update_post_meta($this->post_id, self::META_KEY, $this->content) !== \false;
            if ($success) {
                // 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 params for link removal
        $this->params = ['link' => $link, 'anchor' => $anchor];
        if (is_countable($this->content)) {
            foreach ($this->content as $key => $block) {
                // update the original content with the new content
                $this->content[$key] = $this->extract_content($block, 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;
        $this->params = ['link' => $link, 'anchor' => $phrase, 'link_replacement' => $replacement];
        if (is_countable($this->content)) {
            foreach ($this->content as $key => $block) {
                // update the original block content with the new content
                $this->content[$key] = $this->extract_content($block, self::OP_CODES['REPLACE_LINK']);
                if ($this->link_processed) {
                    $this->has_unsaved_changes = \true;
                    if ($save) {
                        return $this->update_post();
                    }
                    return \true;
                }
            }
        }
        return \false;
    }
}
