<?php

namespace FleekDash\Controllers\Schema\FieldDetectors;

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

/**
 * Field Detector Factory
 *
 * Manages and coordinates all field detection sources with priority system.
 * Higher priority detectors override lower priority ones.
 *
 * Priority Order:
 * 1. ACF (10) - Advanced Custom Fields
 * 2. Meta Box (9) - Meta Box plugin
 * 3. Voxel (8) - Voxel theme fields (including repeaters)
 * 4. WordPress REST (7) - Native REST API meta
 * 5. Database Meta (1) - Raw database meta scan
 *
 * @since 2.0.0 Refactored from monolithic SchemaController
 */
class FieldDetectorFactory
{
    private $detectors = [];

    public function __construct()
    {
        $this->initializeDetectors();
    }

    /**
     * Initialize all available field detectors
     */
    private function initializeDetectors()
    {
        // Initialize detectors in priority order (highest first)

        // ACF Detector (Priority: 10)
        if (class_exists('ACF')) {
            $this->detectors['acf'] = [
                'class' => 'ACFFieldDetector',
                'priority' => 10,
                'active' => true
            ];
        }

        // Meta Box Detector (Priority: 9)
        if (class_exists('RWMB_Loader')) {
            $this->detectors['metabox'] = [
                'class' => 'MetaBoxFieldDetector',
                'priority' => 9,
                'active' => true
            ];
        }

        // Voxel Detector (Priority: 8) - Includes repeater support
        if (class_exists('\Voxel\Post_Type')) {
            $this->detectors['voxel'] = [
                'class' => 'VoxelFieldDetector',
                'priority' => 8,
                'active' => true
            ];
        }

        // WordPress REST Detector (Priority: 7)
        $this->detectors['rest'] = [
            'class' => 'RestFieldDetector',
            'priority' => 7,
            'active' => true
        ];

        // Database Meta Detector (Priority: 1) - Fallback
        $this->detectors['database'] = [
            'class' => 'DatabaseFieldDetector',
            'priority' => 1,
            'active' => true
        ];
    }

    /**
     * Detect all custom fields for a post type using priority system
     *
     * @param string $post_type
     * @return array
     */
    public function detectCustomFields($post_type)
    {
        $all_fields = [];
        $field_sources = [];


        // Sort detectors by priority (highest first)
        $sorted_detectors = $this->detectors;
        uasort($sorted_detectors, function ($a, $b) {
            return $b['priority'] - $a['priority'];
        });

        // Run each detector and collect fields
        foreach ($sorted_detectors as $detector_key => $detector_config) {
            if (!$detector_config['active']) {
                continue;
            }

            try {
                $detector = $this->getDetectorInstance($detector_key);
                if (!$detector) {
                    continue;
                }

                $fields = $detector->getFields($post_type);

                foreach ($fields as $field_key => $field_data) {
                    // Only add field if not already detected by higher priority detector
                    if (!isset($all_fields[$field_key])) {
                        $all_fields[$field_key] = $field_data;
                        $field_sources[$field_key] = $detector_key;
                    }
                }



            } catch (\Exception $e) {
                fleekdash_log_error("FleekDash [FieldDetectorFactory]: Error in {$detector_key} detector: " .
                    $e->getMessage());
            }
        }


        return $all_fields;
    }

    /**
     * Get a specific detector instance
     *
     * @param string $detector_key
     * @return object|null
     */
    public function getDetectorInstance($detector_key)
    {
        if (!isset($this->detectors[$detector_key])) {
            return null;
        }

        $detector_config = $this->detectors[$detector_key];
        $class_name = $detector_config['class'];
        $full_class_name = __NAMESPACE__ . '\\' . $class_name;

        if (!class_exists($full_class_name)) {
            fleekdash_log_error("FleekDash [FieldDetectorFactory]: Detector class not found: {$full_class_name}");
            return null;
        }

        return new $full_class_name();
    }

    /**
     * Check if a specific detector is available
     *
     * @param string $detector_key
     * @return bool
     */
    public function hasDetector($detector_key)
    {
        return isset($this->detectors[$detector_key]) && $this->detectors[$detector_key]['active'];
    }

    /**
     * Get all available detectors info
     *
     * @return array
     */
    public function getAvailableDetectors()
    {
        return $this->detectors;
    }

    /**
     * Get debug information about field detection
     *
     * @param string $post_type
     * @return array
     */
    public function getDebugInfo($post_type = 'post')
    {
        $debug = [
            'available_detectors' => $this->detectors,
            'detection_results' => []
        ];

        foreach ($this->detectors as $detector_key => $detector_config) {
            if (!$detector_config['active']) {
                continue;
            }

            try {
                $detector = $this->getDetectorInstance($detector_key);
                if ($detector) {
                    $fields = $detector->getFields($post_type);
                    $debug['detection_results'][$detector_key] = [
                        'field_count' => count($fields),
                        'field_keys' => array_keys($fields),
                        'priority' => $detector_config['priority']
                    ];
                }
            } catch (\Exception $e) {
                $debug['detection_results'][$detector_key] = [
                    'error' => $e->getMessage(),
                    'priority' => $detector_config['priority']
                ];
            }
        }

        return $debug;
    }
}
