<?php

namespace Linksy\SearchAndReplace\Plugli\Linksy\Common\Helpers\Post\Editors;

use Linksy\SearchAndReplace\Plugli\Linksy\Common\Helpers\Settings;
use Linksy\SearchAndReplace\Plugli\Linksy\Common\Helpers\Utils;
class ACF extends Editors
{
    /**
     * Contains the names of the fields associated to the post instance.
     *
     * @var array
     */
    private $field_names = [];
    /**
     * Contains the fields that the admin has ignored
     * 
     * @var array
     */
    private $ignored_fields = [];
    public function __construct($post_id)
    {
        $this->post_id = $post_id;
        if (!empty($this->post_id)) {
            $this->ignored_fields = Settings::get('unsupported_acf_fields', []);
        }
    }
    public static function is_active(string $post_id): bool
    {
        $plugin_activated = Utils::is_plugin_active('advanced-custom-fields-pro/acf.php') || Utils::is_plugin_active('advanced-custom-fields/acf.php');
        return $plugin_activated && get_fields($post_id) !== \false;
    }
    private function extract_content(): array
    {
        $content = [];
        $fields = get_fields($this->post_id);
        foreach ($fields as $field_name => $field_value) {
            if (in_array($field_name, $this->ignored_fields) || empty($field_value)) {
                continue;
            }
            if (!in_array($field_name, $this->field_names)) {
                $this->field_names[] = $field_name;
            }
            if (is_array($field_value)) {
                $content = array_merge($content, $this->flatten_array($field_value));
            } else {
                $content[] = $field_value;
            }
        }
        return $content;
    }
    private function flatten_array(array $field_value): array
    {
        $result = [];
        foreach ($field_value as $item) {
            if (is_array($item)) {
                if (isset($item['acf_fc_layout'])) {
                    unset($item['acf_fc_layout']);
                }
                $result = array_merge($result, $this->flatten_array($item));
            } elseif (is_string($item) && !empty($item)) {
                $result[] = $item;
            }
        }
        return $result;
    }
    public function get_content($post_id): string
    {
        if (!$this->content) {
            $this->content = $this->extract_content();
        }
        return implode(\PHP_EOL, $this->content);
    }
    public function replace_phrase(string $link, string $phrase, string $replacement, $save = \false): bool
    {
        $pattern = '/<a\b[^>]*href="' . preg_quote($link, '/') . '"[^>]*>' . preg_quote($phrase, '/') . '<\/a>/i';
        $blocks = $this->extract_content();
        foreach ($blocks as $idx => $block) {
            $updated_block = preg_replace_callback($pattern, function ($match) use ($link, $replacement) {
                return str_replace($link, $replacement, $match[0]);
            }, $block);
            if (!is_null($updated_block) && $block !== $updated_block) {
                $this->content[$idx] = $updated_block;
                $this->has_unsaved_changes = \true;
                if ($save) {
                    return $this->update_post();
                }
                return \true;
            }
        }
        return \false;
    }
    public function add_link(string $source, string $phrase, string $phrase_replacement): bool
    {
        $blocks = $this->extract_content();
        foreach ($blocks as $idx => $block) {
            $updated_block = self::insert_link_in_content($block, $source, $phrase, $phrase_replacement);
            if ($updated_block !== \false) {
                $this->content[$idx] = $updated_block;
                $this->has_unsaved_changes = \true;
                return $this->update_post();
            }
        }
        return \false;
    }
    public function update_post(?array $suggestions = null): bool
    {
        if (!$this->has_unsaved_changes) {
            return \false;
        }
        $has_been_saved = \false;
        foreach ($this->field_names as $idx => $field_name) {
            $block_content = get_field($field_name);
            if ($block_content !== $this->content[$idx]) {
                update_field($field_name, $this->content[$idx], $this->post_id);
                $has_been_saved = \true;
            }
        }
        $this->has_unsaved_changes = \false;
        return $has_been_saved;
    }
    public function remove_link(string $link, string $anchor, bool $save): bool
    {
        $pattern = '/<a\b[^>]*href="' . preg_quote($link, '/') . '"[^>]*>' . preg_quote($anchor, '/') . '<\/a>/i';
        $blocks = $this->extract_content();
        foreach ($blocks as $idx => $block) {
            $updated_block = preg_replace($pattern, $anchor, $block);
            if (is_null($updated_block) || $block === $updated_block) {
                continue;
            }
            $this->content[$idx] = $updated_block;
            $this->has_unsaved_changes = \true;
            if ($save) {
                return $this->update_post();
            }
            return \true;
        }
        return \false;
    }
}
