<?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 Themify extends Editors
{
    const META_KEY = '_themify_builder_settings_json';
    private $extracted_data;
    public static $content_types = ['content_text', 'text_accordion', 'content_box', 'text_tab'];
    public function __construct($post_id)
    {
        $this->post_id = $post_id;
        $content = get_post_meta($this->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 !empty(get_post_meta($post_id, self::META_KEY, \true)) && class_exists('Linksy\SearchAndReplace\ThemifyBuilder_Data_Manager');
    }
    private function handle_block_ops(&$block_content, $op_code, &$result = [])
    {
        switch ($op_code) {
            case self::OP_CODES['EXTRACT_CONTENT']:
                if (!in_array($block_content, $result)) {
                    $result[] = $block_content;
                }
                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 $this->link_processed;
    }
    private function extract_content(&$item, $op_code = self::OP_CODES['EXTRACT_CONTENT'])
    {
        $result = [];
        if (isset($item->mod_settings) && is_object($item->mod_settings)) {
            foreach ($item->mod_settings as $key => $value) {
                if (in_array($key, self::$content_types, \true) && !empty($value)) {
                    $this->handle_block_ops($item->mod_settings->{$key}, $op_code, $result);
                }
            }
            foreach (['content_accordion' => 'text_accordion', 'tab_content_tab' => 'text_tab'] as $key => $value) {
                if (isset($item->mod_settings->{$key}) && is_array($item->mod_settings->{$key})) {
                    foreach ($item->mod_settings->{$key} as $k => $v) {
                        if (isset($item->mod_settings->{$key}[$k]->{$value}) && !empty($item->mod_settings->{$key}[$k]->{$value})) {
                            $this->handle_block_ops($item->mod_settings->{$key}[$k]->{$value}, $op_code, $result);
                        }
                    }
                }
            }
        }
        if (isset($item->cols) && is_array($item->cols)) {
            foreach ($item->cols as $value) {
                if (is_object($value)) {
                    $result = array_merge($result, $this->extract_content($value, $op_code));
                }
            }
        }
        if (isset($item->modules) && is_array($item->modules)) {
            foreach ($item->modules as $value) {
                if (is_object($value)) {
                    $result = array_merge($result, $this->extract_content($value, $op_code));
                }
            }
        }
        return $result;
    }
    public function get_content($post_id): string
    {
        // empty already extracted data
        $this->extracted_data = '';
        if (!empty($this->content)) {
            if (is_countable($this->content)) {
                foreach ($this->content as $item) {
                    $this->extracted_data .= implode("\n", $this->extract_content($item));
                }
            }
        }
        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;
        // add link to content
        foreach ($this->content as $item) {
            $this->extract_content($item, 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) {
            // make sure that Themify receives an array, not object
            $themify = json_decode(wp_json_encode($this->content), \true);
            if (!empty($themify)) {
                // save using Themify's data manager to avoid data loss
                \Linksy\SearchAndReplace\ThemifyBuilder_Data_Manager::save_data($themify, $this->post_id);
                $success = \true;
                $this->has_unsaved_changes = \false;
                // refresh linksy links
                $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 that will be used to remove the link
        $this->params = ['link' => $link, 'anchor' => $anchor];
        // remove link from content
        foreach ($this->content as $item) {
            $this->extract_content($item, self::OP_CODES['REMOVE_LINK']);
        }
        if ($this->link_processed) {
            $this->has_unsaved_changes = \true;
            if ($save) {
                $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];
        // replace link in content
        foreach ($this->content as $item) {
            $this->extract_content($item, self::OP_CODES['REPLACE_LINK']);
        }
        if ($this->link_processed) {
            $this->has_unsaved_changes = \true;
            if ($save) {
                return $this->update_post();
            }
            return \true;
        }
        return \false;
    }
}
