<?php

namespace DropshippingXmlFreeVendor\WPDesk\Library\DropshippingXmlCore\Integration;

use DropshippingXmlFreeVendor\WPDesk\Library\DropshippingXmlCore\Form\Fields\Component\AcfGroupComponent;
use DropshippingXmlFreeVendor\WPDesk\Library\DropshippingXmlCore\Form\ImportMapperForm;
class AcfIntegration
{
    public const ALLOWED_FIELD_TYPES = ['text', 'textarea', 'number', 'range', 'email', 'url', 'password', 'select', 'checkbox', 'radio', 'true_false', 'wysiwyg'];
    private ?array $product_groups = null;
    public function is_active(): bool
    {
        if (defined('DropshippingXmlFreeVendor\ACF_VERSION') || class_exists('DropshippingXmlFreeVendor\ACF') || function_exists('DropshippingXmlFreeVendor\acf_get_field_groups')) {
            return \true;
        }
        if (!function_exists('is_plugin_active')) {
            return \false;
        }
        return \is_plugin_active('advanced-custom-fields/acf.php') || \is_plugin_active('advanced-custom-fields-pro/acf.php');
    }
    /**
     * Returns ACF field groups assigned to post_type=product,
     * containing only fields of allowed basic types.
     *
     * @return array[] Each item: ['key' => string, 'title' => string, 'fields' => array[]]
     */
    public function get_product_field_groups(): array
    {
        if (!$this->is_active()) {
            return [];
        }
        if (!function_exists('DropshippingXmlFreeVendor\acf_get_field_groups') || !function_exists('DropshippingXmlFreeVendor\acf_get_fields')) {
            return $this->get_product_field_groups_from_posts('product');
        }
        $groups = \DropshippingXmlFreeVendor\acf_get_field_groups(['post_type' => 'product']);
        if (empty($groups)) {
            $groups = $this->filter_groups_by_location((array) \DropshippingXmlFreeVendor\acf_get_field_groups(), 'product');
        }
        $result = [];
        foreach ($groups as $group) {
            $entry = $this->build_group_entry_from_acf($group);
            if ($entry !== null) {
                $result[] = $entry;
            }
        }
        return $result;
    }
    private function build_group_entry_from_acf(array $group): ?array
    {
        $group_key = (string) ($group['key'] ?? '');
        if ($group_key === '') {
            return null;
        }
        $all_fields = \DropshippingXmlFreeVendor\acf_get_fields($group_key);
        if (!is_array($all_fields)) {
            return null;
        }
        $fields = $this->filter_and_flatten_fields($all_fields);
        if (empty($fields)) {
            return null;
        }
        return $this->make_group_result($group_key, (string) ($group['title'] ?? ''), $fields);
    }
    private function normalize_acf_field(array $field): ?array
    {
        $key = (string) ($field['key'] ?? '');
        $name = (string) ($field['name'] ?? '');
        $type = (string) ($field['type'] ?? '');
        if ($key === '' || $name === '' || $type === '') {
            return null;
        }
        $label = (string) ($field['label'] ?? '');
        if ($label === '') {
            $label = $name !== '' ? $name : $key;
        }
        $field['key'] = $key;
        $field['name'] = $name;
        $field['type'] = $type;
        $field['label'] = $label;
        return $field;
    }
    /**
     * @param string $post_type WooCommerce post type to filter groups for (typically 'product').
     * @return array[] Each item: ['key' => string, 'title' => string, 'fields' => array[]]
     */
    private function get_product_field_groups_from_posts(string $post_type): array
    {
        if (!function_exists('get_posts') || !function_exists('maybe_unserialize')) {
            return [];
        }
        $group_posts = \get_posts(['post_type' => 'acf-field-group', 'post_status' => 'any', 'posts_per_page' => -1, 'orderby' => 'menu_order', 'order' => 'ASC']);
        if (!is_array($group_posts) || empty($group_posts)) {
            return [];
        }
        $result = [];
        foreach ($group_posts as $group_post) {
            $entry = $this->build_group_entry_from_post($group_post, $post_type);
            if ($entry !== null) {
                $result[] = $entry;
            }
        }
        return $result;
    }
    private function build_group_entry_from_post(object $group_post, string $post_type): ?array
    {
        if (!is_object($group_post) || empty($group_post->ID)) {
            return null;
        }
        $group_data = \maybe_unserialize($group_post->post_content ?? '');
        if (!is_array($group_data)) {
            return null;
        }
        if (isset($group_data['location']) && is_array($group_data['location']) && empty($this->filter_groups_by_location([$group_data], $post_type))) {
            return null;
        }
        $fields = $this->filter_and_flatten_fields($this->get_group_fields_from_posts((int) $group_post->ID));
        if (empty($fields)) {
            return null;
        }
        return $this->make_group_result($this->resolve_group_key($group_data, $group_post), (string) ($group_post->post_title ?? $group_data['title'] ?? ''), $fields);
    }
    private function resolve_group_key(array $group_data, object $group_post): string
    {
        $key = (string) ($group_data['key'] ?? '');
        if ($key !== '') {
            return $key;
        }
        return !empty($group_post->post_name) ? (string) $group_post->post_name : 'group_' . (string) $group_post->ID;
    }
    private function make_group_result(string $key, string $title, array $fields): array
    {
        return ['key' => $key, 'title' => $title, 'fields' => $fields];
    }
    private function get_group_fields_from_posts(int $group_post_id): array
    {
        $field_posts = \get_posts(['post_type' => 'acf-field', 'post_status' => 'any', 'posts_per_page' => -1, 'post_parent' => $group_post_id, 'orderby' => 'menu_order', 'order' => 'ASC']);
        return $this->build_fields_from_posts((array) $field_posts, 0);
    }
    private function get_group_sub_fields_from_posts(int $parent_field_post_id, int $depth): array
    {
        if ($depth > 5) {
            return [];
        }
        $field_posts = \get_posts(['post_type' => 'acf-field', 'post_status' => 'any', 'posts_per_page' => -1, 'post_parent' => $parent_field_post_id, 'orderby' => 'menu_order', 'order' => 'ASC']);
        return $this->build_fields_from_posts((array) $field_posts, $depth);
    }
    private function build_fields_from_posts(array $field_posts, int $depth): array
    {
        $fields = [];
        foreach ($field_posts as $field_post) {
            if (!is_object($field_post) || empty($field_post->ID)) {
                continue;
            }
            $field_data = \maybe_unserialize($field_post->post_content ?? '');
            if (!is_array($field_data)) {
                continue;
            }
            $field_data = $this->enrich_field_data_from_post($field_data, $field_post);
            if (($field_data['type'] ?? '') === 'group') {
                $field_data['sub_fields'] = $this->get_group_sub_fields_from_posts((int) $field_post->ID, $depth + 1);
            }
            $fields[] = $field_data;
        }
        return $fields;
    }
    private function enrich_field_data_from_post(array $field_data, object $post): array
    {
        if (empty($field_data['key']) && !empty($post->post_name)) {
            $field_data['key'] = (string) $post->post_name;
        }
        if (empty($field_data['name']) && !empty($post->post_excerpt)) {
            $field_data['name'] = (string) $post->post_excerpt;
        }
        return $field_data;
    }
    private function filter_and_flatten_fields(array $all_fields): array
    {
        $filtered = [];
        foreach ($all_fields as $field) {
            if (!is_array($field) || empty($field['type'])) {
                continue;
            }
            if (in_array($field['type'], self::ALLOWED_FIELD_TYPES, \true)) {
                $normalized = $this->normalize_acf_field($field);
                if ($normalized !== null) {
                    $filtered[] = $normalized;
                }
                continue;
            }
            if ($field['type'] === 'group') {
                $filtered = array_merge($filtered, $this->flatten_sub_fields($field));
            }
        }
        return array_values($filtered);
    }
    private function flatten_sub_fields(array $parent_field): array
    {
        if (empty($parent_field['sub_fields']) || !is_array($parent_field['sub_fields'])) {
            return [];
        }
        $group_label = (string) ($parent_field['label'] ?? '');
        $result = [];
        foreach ($parent_field['sub_fields'] as $sub_field) {
            if (!is_array($sub_field) || empty($sub_field['type'])) {
                continue;
            }
            if (!in_array($sub_field['type'], self::ALLOWED_FIELD_TYPES, \true)) {
                continue;
            }
            if ($group_label !== '') {
                $sub_label = (string) ($sub_field['label'] ?? '');
                $sub_field['label'] = $sub_label !== '' ? $group_label . ': ' . $sub_label : $group_label;
            }
            $normalized = $this->normalize_acf_field($sub_field);
            if ($normalized !== null) {
                $result[] = $normalized;
            }
        }
        return $result;
    }
    private function filter_groups_by_location(array $groups, string $post_type): array
    {
        $filtered = [];
        foreach ($groups as $group) {
            if ($this->group_matches_post_type($group, $post_type)) {
                $filtered[] = $group;
            }
        }
        return $filtered;
    }
    private function group_matches_post_type($group, string $post_type): bool
    {
        if (!is_array($group) || empty($group['location']) || !is_array($group['location'])) {
            return \false;
        }
        foreach ($group['location'] as $and_group) {
            if (!is_array($and_group)) {
                continue;
            }
            foreach ($and_group as $rule) {
                if ($this->rule_matches_post_type($rule, $post_type)) {
                    return \true;
                }
            }
        }
        return \false;
    }
    private function rule_matches_post_type($rule, string $post_type): bool
    {
        if (!is_array($rule) || ($rule['param'] ?? '') !== 'post_type') {
            return \false;
        }
        return (string) ($rule['operator'] ?? '==') === '==' && (string) ($rule['value'] ?? '') === $post_type;
    }
    public function get_group_form_name(string $group_key): string
    {
        return 'acf_fields_' . $group_key;
    }
    /**
     * @return array[]
     */
    public function get_product_groups(): array
    {
        if (null === $this->product_groups) {
            $this->product_groups = $this->is_active() ? $this->get_product_field_groups() : [];
        }
        return $this->product_groups;
    }
    /**
     * @param array[] $acf_groups
     * @return AcfGroupComponent[]
     */
    public function create_fields_from_groups(array $acf_groups): array
    {
        $fields = [];
        foreach ($acf_groups as $group) {
            if (empty($group['key']) || empty($group['title']) || empty($group['fields'])) {
                continue;
            }
            $fields[] = (new AcfGroupComponent())->set_acf_group((string) $group['key'], (string) $group['title'], (array) $group['fields'])->set_name($this->get_group_form_name((string) $group['key']));
        }
        return $fields;
    }
    /**
     * @param array[] $acf_groups
     */
    public function register_missing_fields(ImportMapperForm $form, array $acf_groups): void
    {
        if (empty($acf_groups)) {
            return;
        }
        $existing = [];
        foreach ($form->get_fields() as $field) {
            $existing[$field->get_name()] = \true;
        }
        foreach ($this->create_fields_from_groups($acf_groups) as $field) {
            if (isset($existing[$field->get_name()])) {
                continue;
            }
            $form->add_field($field);
        }
    }
}
