<?php

namespace FleekDash\Controllers\Schema\FieldDetectors;

if (!\function_exists('fleekdash_log_debug')) {
    require_once FLEEKDASH_PLUGIN_DIR . 'includes/Core/debug-helpers.php';
}

/**
 * Voxel Field Detector
 *
 * Specialized detector for Voxel theme custom fields.
 * Handles all Voxel field types including repeater/group fields.
 *
 * Supported Voxel Field Types:
 * - Basic: text, textarea, number, email, url, etc.
 * - Media: image, file, gallery
 * - Selection: select, checkbox, radio, taxonomy
 * - Complex: repeater, group, fieldset (with sub-fields)
 * - Voxel Specific: title, description, location, product
 *
 * @since 2.0.0 Extracted from monolithic SchemaController
 */
class VoxelFieldDetector
{
    private $priority = 8;

    /**
     * Check if Voxel is available
     *
     * @return bool
     */
    public function isAvailable()
    {
        return class_exists('\Voxel\Post_Type');
    }

    /**
     * Get detector priority
     *
     * @return int
     */
    public function getPriority()
    {
        return $this->priority;
    }

    /**
     * Get Voxel fields for a post type
     *
     * @param string $post_type
     * @return array
     */
    public function getFields($post_type)
    {
        $fields = [];

        if (!$this->isAvailable()) {
            fleekdash_log_debug("FleekDash [VoxelFieldDetector]: Voxel not available");
            return $fields;
        }

        try {
            fleekdash_log_debug("FleekDash [VoxelFieldDetector]: Detecting fields for post type: {$post_type}");

            $voxel_post_type = \Voxel\Post_Type::get($post_type);

            if (!$voxel_post_type) {
                fleekdash_log_debug("FleekDash [VoxelFieldDetector]: No Voxel post type found for {$post_type}");
                return $fields;
            }

            $voxel_fields = $voxel_post_type->get_fields();
            fleekdash_log_debug("FleekDash [VoxelFieldDetector]: Found " . count($voxel_fields) . " Voxel fields");

            foreach ($voxel_fields as $field) {
                $field_key = $field->get_key();
                $field_type = $field->get_type();
                $field_label = $field->get_label();

                // Skip taxonomy fields - they are handled separately
                if ($field_type === 'taxonomy') {
                    fleekdash_log_debug("FleekDash [VoxelFieldDetector]: Skipping taxonomy field: {$field_key}");
                    continue;
                }

                // Get Voxel field configuration
                $voxel_config = method_exists($field, 'get_props') ? $field->get_props() : [];

                // Create base field configuration
                $field_config = [
                    'name' => $field_key,
                    'label' => $field_label,
                    'type' => $this->mapVoxelType($field_type),
                    'component' => $this->mapVoxelComponent($field_type),
                    'required' => $field->is_required(),
                    'validation' => [],
                    'description' => $field->get_description() ?? '',
                    'default' => null,
                    'meta_key' => $field_key,
                    'source' => 'Voxel',
                    'source_priority' => $this->priority,
                    'voxel_type' => $field_type,
                    'voxel_config' => $voxel_config
                ];

                // Special handling for repeater/group fields
                if ($this->isRepeaterType($field_type)) {
                    $field_config = $this->processRepeaterField($field, $field_config);
                } else {
                    // Handle regular fields with options
                    $options = $this->extractFieldOptions($field, $field_type, $voxel_config);
                    if (!empty($options)) {
                        $field_config['options'] = $options;
                    }
                }

                $fields[$field_key] = $field_config;

                $sub_fields_count = isset($field_config['sub_fields']) ? count($field_config['sub_fields']) : 0;
                $options_count = isset($field_config['options']) ? count($field_config['options']) : 0;

                fleekdash_log_debug("FleekDash [VoxelFieldDetector]: Added field '{$field_key}' " .
                    "(type: {$field_type}, sub_fields: {$sub_fields_count}, options: {$options_count})");
            }

            fleekdash_log_debug("FleekDash [VoxelFieldDetector]: Total fields processed: " . count($fields));

        } catch (\Exception $e) {
            fleekdash_log_error("FleekDash [VoxelFieldDetector]: Error processing Voxel fields: " . $e->getMessage());
        }

        return $fields;
    }

    /**
     * Check if field type is a repeater/group type
     *
     * @param string $field_type
     * @return bool
     */
    private function isRepeaterType($field_type)
    {
        return in_array($field_type, [
            'repeater',
            'group',
            'fieldset',
            'repeating-group',
            'event_date',           // Voxel complex date field with subfields
            'recurring-date'        // Voxel complex recurring date field with subfields
        ]);
    }

    /**
     * Process repeater field with sub-fields
     *
     * @param object $field
     * @param array $field_config
     * @return array
     */
    private function processRepeaterField($field, $field_config)
    {
        $field_config['component'] = 'repeater';
        $field_config['type'] = 'repeater';
        $field_config['sub_fields'] = [];

        $field_key = method_exists($field, 'get_key') ? $field->get_key() : 'unknown';
        $field_type = method_exists($field, 'get_type') ? $field->get_type() : 'unknown';

        fleekdash_log_debug("FleekDash [VoxelFieldDetector]: Processing repeater field '{$field_key}' of type '{$field_type}'");

        // Debug: Check available methods
        $available_methods = get_class_methods($field);
        fleekdash_log_debug("FleekDash [VoxelFieldDetector]: Available methods for '{$field_key}': " . implode(', ', $available_methods));

        // Special handling for Voxel date fields
        if (in_array($field_type, ['event_date', 'recurring-date'])) {
            fleekdash_log_debug("FleekDash [VoxelFieldDetector]: Detected Voxel date field '{$field_key}' (type: {$field_type}), using hardcoded subfields");
            $subfields = $this->getVoxelDateSubfields($field_type);
            fleekdash_log_debug("FleekDash [VoxelFieldDetector]: Generated " . count($subfields) . " subfields for {$field_key}");
            $field_config['sub_fields'] = $subfields;
            return $field_config;
        }

        // Get sub-fields if available
        if (method_exists($field, 'get_fields')) {
            $sub_fields = $field->get_fields();
            fleekdash_log_debug("FleekDash [VoxelFieldDetector]: Found " . count($sub_fields) . " sub-fields for '{$field_key}'");

            foreach ($sub_fields as $sub_field) {
                $sub_field_key = $sub_field->get_key();
                $sub_field_type = method_exists($sub_field, 'get_type') ? $sub_field->get_type() : 'text';
                $sub_field_label = method_exists($sub_field, 'get_label') ? $sub_field->get_label() : $this->formatLabel($sub_field_key);

                $sub_field_config = [
                    'name' => $sub_field_key,
                    'label' => $sub_field_label,
                    'type' => $this->mapVoxelType($sub_field_type),
                    'component' => $this->mapVoxelComponent($sub_field_type),
                    'voxel_type' => $sub_field_type,
                    'meta_key' => $sub_field_key,
                    'required' => false,
                    'validation' => []
                ];

                // Add options for sub-fields that need them
                if (method_exists($sub_field, 'get_props')) {
                    $sub_voxel_config = $sub_field->get_props();
                    $sub_options = $this->extractFieldOptions($sub_field, $sub_field_type, $sub_voxel_config);
                    if (!empty($sub_options)) {
                        $sub_field_config['options'] = $sub_options;
                    }
                }

                $field_config['sub_fields'][] = $sub_field_config;
            }

            fleekdash_log_debug("FleekDash [VoxelFieldDetector]: Processed repeater '{$field_key}' " .
                "with " . count($field_config['sub_fields']) . " sub-fields");
        } else {
            fleekdash_log_debug("FleekDash [VoxelFieldDetector]: Field '{$field_key}' does not have get_fields() method");

            // Try alternative methods to get subfields
            if (method_exists($field, 'get_props')) {
                $props = $field->get_props();
                fleekdash_log_debug("FleekDash [VoxelFieldDetector]: Field props for '{$field_key}': " . json_encode($props));

                // Check if props contain field configuration
                if (isset($props['fields']) && is_array($props['fields'])) {
                    fleekdash_log_debug("FleekDash [VoxelFieldDetector]: Found fields in props for '{$field_key}'");
                    $field_config['sub_fields'] = $this->processPropsFields($props['fields']);
                }
            }
        }

        return $field_config;
    }

    /**
     * Get predefined subfields for Voxel date fields (using native Voxel format)
     *
     * @param string $field_type
     * @return array
     */
    private function getVoxelDateSubfields($field_type)
    {
        $subfields = [];

        fleekdash_log_debug("FleekDash [VoxelFieldDetector]: getVoxelDateSubfields called with field_type: '{$field_type}'");

        if ($field_type === 'event_date') {
            fleekdash_log_debug("FleekDash [VoxelFieldDetector]: Generating EVENT_DATE subfields");
            // Event date subfields - Native Voxel format
            $subfields = [
                [
                    'name' => 'start',
                    'label' => 'Start Date & Time',
                    'type' => 'datetime-local',
                    'component' => 'datetime-local',
                    'voxel_type' => 'datetime',
                    'meta_key' => 'start',
                    'required' => false,
                    'validation' => []
                ],
                [
                    'name' => 'end',
                    'label' => 'End Date & Time',
                    'type' => 'datetime-local',
                    'component' => 'datetime-local',
                    'voxel_type' => 'datetime',
                    'meta_key' => 'end',
                    'required' => false,
                    'validation' => []
                ],
                [
                    'name' => 'multiday',
                    'label' => 'Multi-day Event',
                    'type' => 'boolean',
                    'component' => 'checkbox',
                    'voxel_type' => 'checkbox',
                    'meta_key' => 'multiday',
                    'required' => false,
                    'validation' => []
                ],
                [
                    'name' => 'allday',
                    'label' => 'All Day Event',
                    'type' => 'boolean',
                    'component' => 'checkbox',
                    'voxel_type' => 'checkbox',
                    'meta_key' => 'allday',
                    'required' => false,
                    'validation' => []
                ]
            ];
        } elseif ($field_type === 'recurring-date') {
            fleekdash_log_debug("FleekDash [VoxelFieldDetector]: Generating RECURRING-DATE subfields");
            // Recurring date subfields - Native Voxel format
            $subfields = [
                [
                    'name' => 'start',
                    'label' => 'Start Date & Time',
                    'type' => 'datetime-local',
                    'component' => 'datetime-local',
                    'voxel_type' => 'datetime',
                    'meta_key' => 'start',
                    'required' => false,
                    'validation' => []
                ],
                [
                    'name' => 'end',
                    'label' => 'End Date & Time',
                    'type' => 'datetime-local',
                    'component' => 'datetime-local',
                    'voxel_type' => 'datetime',
                    'meta_key' => 'end',
                    'required' => false,
                    'validation' => []
                ],
                [
                    'name' => 'frequency',
                    'label' => 'Frequency (Number)',
                    'type' => 'number',
                    'component' => 'number',
                    'voxel_type' => 'number',
                    'meta_key' => 'frequency',
                    'required' => false,
                    'validation' => []
                ],
                [
                    'name' => 'unit',
                    'label' => 'Frequency Unit',
                    'type' => 'select',
                    'component' => 'select',
                    'voxel_type' => 'select',
                    'meta_key' => 'unit',
                    'required' => false,
                    'validation' => [],
                    'options' => [
                        ['value' => 'day', 'label' => 'Days'],
                        ['value' => 'week', 'label' => 'Weeks'],
                        ['value' => 'month', 'label' => 'Months'],
                        ['value' => 'year', 'label' => 'Years']
                    ]
                ],
                [
                    'name' => 'until',
                    'label' => 'Repeat Until',
                    'type' => 'datetime-local',
                    'component' => 'datetime-local',
                    'voxel_type' => 'datetime',
                    'meta_key' => 'until',
                    'required' => false,
                    'validation' => []
                ],
                [
                    'name' => 'multiday',
                    'label' => 'Multi-day Event',
                    'type' => 'boolean',
                    'component' => 'checkbox',
                    'voxel_type' => 'checkbox',
                    'meta_key' => 'multiday',
                    'required' => false,
                    'validation' => []
                ],
                [
                    'name' => 'allday',
                    'label' => 'All Day Event',
                    'type' => 'boolean',
                    'component' => 'checkbox',
                    'voxel_type' => 'checkbox',
                    'meta_key' => 'allday',
                    'required' => false,
                    'validation' => []
                ]
            ];
        }

        fleekdash_log_debug("FleekDash [VoxelFieldDetector]: Generated " . count($subfields) . " subfields for {$field_type} (NATIVE VOXEL FORMAT)");
        return $subfields;
    }

    /**
     * Process fields from props array
     *
     * @param array $props_fields
     * @return array
     */
    private function processPropsFields($props_fields)
    {
        $subfields = [];

        foreach ($props_fields as $field_key => $field_config) {
            $field_type = isset($field_config['type']) ? $field_config['type'] : 'text';
            $field_label = isset($field_config['label']) ? $field_config['label'] : $this->formatLabel($field_key);

            $subfield_config = [
                'name' => $field_key,
                'label' => $field_label,
                'type' => $this->mapVoxelType($field_type),
                'component' => $this->mapVoxelComponent($field_type),
                'voxel_type' => $field_type,
                'meta_key' => $field_key,
                'required' => isset($field_config['required']) ? $field_config['required'] : false,
                'validation' => []
            ];

            // Add options if available
            if (isset($field_config['choices']) && is_array($field_config['choices'])) {
                $options = [];
                foreach ($field_config['choices'] as $choice_key => $choice_label) {
                    $options[] = [
                        'value' => $choice_key,
                        'label' => $choice_label
                    ];
                }
                $subfield_config['options'] = $options;
            }

            $subfields[] = $subfield_config;
        }

        fleekdash_log_debug("FleekDash [VoxelFieldDetector]: Processed " . count($subfields) . " fields from props");
        return $subfields;
    }

    /**
     * Map Voxel field type to our standardized type
     *
     * @param string $voxel_type
     * @return string
     */
    private function mapVoxelType($voxel_type)
    {
        $type_map = [
            // Basic types
            'text' => 'text',
            'textarea' => 'textarea',
            'number' => 'number',
            'email' => 'email',
            'url' => 'url',
            'wysiwyg' => 'richtext',
            'date' => 'date',
            'color' => 'color',
            'range' => 'range',

            // Media types
            'image' => 'media',
            'file' => 'file',
            'gallery' => 'media',

            // Selection types
            'select' => 'select',
            'checkbox' => 'checkbox',
            'radio' => 'radio',
            'switch' => 'boolean',

            // Voxel specific types
            'title' => 'text',
            'description' => 'textarea',
            'location' => 'text',
            'product' => 'select',
            'relation' => 'select',
            'taxonomy' => 'select',

            // Voxel date repeaters (complex date fields with subfields)
            'event_date' => 'repeater',
            'recurring-date' => 'repeater',

            // Repeater/Group types
            'repeater' => 'repeater',
            'group' => 'repeater',
            'fieldset' => 'repeater',
            'repeating-group' => 'repeater',

            // UI elements
            'ui-step' => 'text',
            'ui-image' => 'media',
            'ui-heading' => 'text',
        ];

        return $type_map[$voxel_type] ?? 'text';
    }

    /**
     * Map Voxel field type to component
     *
     * @param string $voxel_type
     * @return string
     */
    private function mapVoxelComponent($voxel_type)
    {
        $component_map = [
            // Basic input types
            'text' => 'input',
            'textarea' => 'textarea',
            'number' => 'input',
            'email' => 'input',
            'url' => 'input',
            'wysiwyg' => 'textarea',
            'date' => 'date',
            'color' => 'input',
            'range' => 'input',

            // Media types
            'image' => 'file',
            'file' => 'file',
            'gallery' => 'file',

            // Selection types
            'select' => 'select',
            'checkbox' => 'checkbox',
            'radio' => 'radio',
            'switch' => 'checkbox',

            // Voxel specific types
            'title' => 'input',
            'description' => 'textarea',
            'location' => 'input',
            'product' => 'select',
            'relation' => 'select',
            'taxonomy' => 'select',

            // Voxel date repeaters (complex date fields with subfields)
            'event_date' => 'repeater',
            'recurring-date' => 'repeater',

            // Repeater/Group types
            'repeater' => 'repeater',
            'group' => 'repeater',
            'fieldset' => 'repeater',
            'repeating-group' => 'repeater',

            // UI elements
            'ui-step' => 'input',
            'ui-image' => 'file',
            'ui-heading' => 'input',
        ];

        return $component_map[$voxel_type] ?? 'input';
    }

    /**
     * Extract field options from Voxel configuration
     *
     * @param object $field
     * @param string $field_type
     * @param array $voxel_config
     * @return array
     */
    private function extractFieldOptions($field, $field_type, $voxel_config)
    {
        $options = [];

        try {
            switch ($field_type) {
                case 'product':
                    // Extract product types
                    if (!empty($voxel_config['product-types'])) {
                        foreach ($voxel_config['product-types'] as $product_type) {
                            $options[] = [
                                'value' => $product_type,
                                'label' => ucfirst(str_replace(['_', '-'], ' ', $product_type))
                            ];
                        }
                    }
                    break;

                case 'select':
                case 'radio':
                case 'checkbox':
                    // Extract choice options
                    if (!empty($voxel_config['choices'])) {
                        foreach ($voxel_config['choices'] as $choice_key => $choice_label) {
                            $options[] = [
                                'value' => $choice_key,
                                'label' => $choice_label
                            ];
                        }
                    }
                    break;

                case 'relation':
                    // Extract relation options (related post types)
                    if (!empty($voxel_config['post-type'])) {
                        $related_post_type = $voxel_config['post-type'];
                        $posts = \get_posts([
                            'post_type' => $related_post_type,
                            'posts_per_page' => 50,
                            'post_status' => 'publish',
                            'fields' => 'ids',
                            'no_found_rows' => true,
                            'update_post_meta_cache' => false,
                            'update_post_term_cache' => false,
                        ]);

                        foreach ($posts as $post_id) {
                            $options[] = [
                                'value' => $post_id,
                                'label' => get_the_title($post_id)
                            ];
                        }
                    }
                    break;

                case 'taxonomy':
                    // Extract taxonomy terms
                    if (!empty($voxel_config['taxonomy'])) {
                        $taxonomy_slug = $voxel_config['taxonomy'];
                        $terms = \get_terms([
                            'taxonomy' => $taxonomy_slug,
                            'hide_empty' => false,
                            'number' => 100
                        ]);

                        if (!is_wp_error($terms)) {
                            foreach ($terms as $term) {
                                $options[] = [
                                    'value' => $term->term_id,
                                    'label' => $term->name
                                ];
                            }
                        }
                    }
                    break;

                default:
                    // Check if field has method to get choices
                    if (method_exists($field, 'get_choices')) {
                        $choices = $field->get_choices();
                        if (is_array($choices)) {
                            foreach ($choices as $choice_key => $choice_label) {
                                $options[] = [
                                    'value' => $choice_key,
                                    'label' => $choice_label
                                ];
                            }
                        }
                    }
                    break;
            }
        } catch (\Exception $e) {
            fleekdash_log_error("FleekDash [VoxelFieldDetector]: Error extracting options for {$field_type}: " . $e->getMessage());
        }

        return $options;
    }

    /**
     * Format field label from key
     *
     * @param string $key
     * @return string
     */
    private function formatLabel($key)
    {
        return ucwords(str_replace(['_', '-'], ' ', $key));
    }

    /**
     * Get field information for a specific field key
     *
     * @param string $field_key
     * @param string $post_type
     * @return array|null
     */
    public function getFieldInfo($field_key, $post_type)
    {
        $fields = $this->getFields($post_type);
        return $fields[$field_key] ?? null;
    }

    /**
     * Investigate repeater fields structure (for debugging)
     *
     * @return array
     */
    public function investigateRepeaterFields()
    {
        $results = [
            'voxel_available' => $this->isAvailable(),
            'post_types_with_repeaters' => [],
            'sample_repeater_data' => [],
            'repeater_field_configs' => []
        ];

        if (!$this->isAvailable()) {
            return $results;
        }

        try {
            // Get all Voxel post types
            $voxel_post_types = \Voxel\Post_Type::get_all();

            foreach ($voxel_post_types as $post_type) {
                $post_type_key = $post_type->get_key();
                $fields = $post_type->get_fields();

                $repeater_fields = [];

                foreach ($fields as $field) {
                    $field_type = $field->get_type();
                    $field_key = $field->get_key();

                    // Look for repeater/group type fields
                    if ($this->isRepeaterType($field_type)) {
                        $repeater_config = [
                            'key' => $field_key,
                            'type' => $field_type,
                            'label' => $field->get_label(),
                            'props' => method_exists($field, 'get_props') ? $field->get_props() : [],
                            'config' => method_exists($field, 'get_config') ? $field->get_config() : [],
                        ];

                        // Try to get sub-fields
                        if (method_exists($field, 'get_fields')) {
                            $sub_fields = $field->get_fields();
                            $repeater_config['sub_fields'] = [];
                            foreach ($sub_fields as $sub_field) {
                                $repeater_config['sub_fields'][] = [
                                    'key' => $sub_field->get_key(),
                                    'type' => $sub_field->get_type(),
                                    'label' => $sub_field->get_label()
                                ];
                            }
                        }

                        $repeater_fields[] = $repeater_config;
                    }
                }

                if (!empty($repeater_fields)) {
                    $results['post_types_with_repeaters'][$post_type_key] = [
                        'label' => $post_type->get_label(),
                        'repeater_fields' => $repeater_fields
                    ];
                }
            }

            // Get sample data from existing posts
            if (!empty($results['post_types_with_repeaters'])) {
                foreach ($results['post_types_with_repeaters'] as $post_type_key => $type_data) {
                    $posts = \get_posts([
                        'post_type' => $post_type_key,
                        'posts_per_page' => 3,
                        'post_status' => 'any',
                        'fields' => 'ids',
                        'no_found_rows' => true,
                        'update_post_meta_cache' => false,
                        'update_post_term_cache' => false,
                    ]);

                    foreach ($posts as $post_id) {
                        foreach ($type_data['repeater_fields'] as $repeater_field) {
                            $field_key = $repeater_field['key'];
                            $meta_value = \get_post_meta($post_id, $field_key, true);

                            if (!empty($meta_value)) {
                                $results['sample_repeater_data'][] = [
                                    'post_id' => $post_id,
                                    'post_type' => $post_type_key,
                                    'field_key' => $field_key,
                                    'field_type' => $repeater_field['type'],
                                    'raw_value' => $meta_value,
                                    'is_serialized' => is_serialized($meta_value),
                                    'is_json' => $this->isJson($meta_value),
                                    'data_type' => gettype($meta_value)
                                ];
                                break;
                            }
                        }
                    }
                }
            }

        } catch (\Exception $e) {
            fleekdash_log_error("FleekDash [VoxelFieldDetector]: Error investigating repeaters: " . $e->getMessage());
            $results['error'] = $e->getMessage();
        }

        return $results;
    }

    /**
     * Check if string is valid JSON
     *
     * @param string $string
     * @return bool
     */
    private function isJson($string)
    {
        if (!is_string($string)) {
            return false;
        }

        json_decode($string);
        return (json_last_error() == JSON_ERROR_NONE);
    }
}
