<?php

namespace FleekDash\Controllers;

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

use FleekDash\Controllers\Schema\SchemaExtractor;
use FleekDash\Controllers\Schema\RESTCrudHandler;
use FleekDash\Controllers\Schema\FileUploadHandler;
use FleekDash\Controllers\Schema\SchemaHelpers;
use FleekDash\Controllers\Schema\FieldProviders\VoxelFieldProvider;
use FleekDash\Libs\API\ResponseService;
use WP_Error;

/**
 * Class SchemaController
 *
 * Main controller for WordPress schema operations.
 * Delegates to specialized services for clean architecture.
 *
 * @package FleekDash\Controllers
 */
class SchemaController
{
    private $schemaExtractor;
    private $restCrudHandler;
    private $fileUploadHandler;
    private $voxelProvider;

    public function __construct()
    {
        $this->schemaExtractor = new SchemaExtractor();
        $this->restCrudHandler = new RESTCrudHandler();
        $this->fileUploadHandler = new FileUploadHandler();
        $this->voxelProvider = new VoxelFieldProvider();
    }

    /**
     * Check permissions - always return true
     * Let AuthMiddleware handle authentication
     *
     * @return bool
     */
    public function check_permissions()
    {
        return true;
    }

    /**
     * Get complete WordPress schema for dynamic form generation
     *
     * @param \WP_REST_Request $request
     * @return \WP_REST_Response
     */
    public function getFormSchema($request)
    {
        try {
            $post_type = $request->get_param('post_type') ?? 'post';

            // Check if post type exists
            if (!\post_type_exists($post_type)) {
                return ResponseService::error("Invalid post type: {$post_type}", null, 400);
            }

            $schema = $this->schemaExtractor->extractFullSchema($post_type);

            return ResponseService::success($schema, 'Schema retrieved successfully');

        } catch (\Exception $e) {
            return ResponseService::error('Failed to fetch schema: ' . $e->getMessage());
        }
    }

    /**
     * Get all available post types with their schemas
     *
     * @param \WP_REST_Request $request
     * @return \WP_REST_Response
     */
    public function getAllSchemas($request)
    {
        try {
            // Get all post types
            $all_post_types = \get_post_types([], 'objects');
            $valid_post_types = [];

            // WordPress core post types to always exclude
            $excluded_core_types = SchemaHelpers::getExcludedCorePostTypes();

            foreach ($all_post_types as $post_type_slug => $post_type_obj) {
                // Skip excluded core types
                if (in_array($post_type_slug, $excluded_core_types)) {
                    continue;
                }

                // Include if public or has show_ui
                if (SchemaHelpers::shouldIncludePostType($post_type_obj)) {
                    $valid_post_types[$post_type_slug] = $post_type_obj;
                }
            }

            // Simple schema response with basic data
            $schemas = [];
            foreach ($valid_post_types as $post_type_slug => $post_type_obj) {
                $schemas[$post_type_slug] = [
                    'name' => $post_type_obj->name,
                    'label' => $post_type_obj->label,
                    'public' => $post_type_obj->public,
                    'show_in_rest' => $post_type_obj->show_in_rest,
                    'description' => $post_type_obj->description,
                    'hierarchical' => $post_type_obj->hierarchical,
                    'show_ui' => $post_type_obj->show_ui,
                    'rest_base' => $post_type_obj->rest_base ?? $post_type_slug,
                    'labels' => $post_type_obj->labels,
                    'supports' => get_all_post_type_supports($post_type_slug),
                    'taxonomies' => get_object_taxonomies($post_type_slug, 'objects'),
                ];
            }

            return ResponseService::success($schemas, 'All schemas retrieved successfully');

        } catch (\Exception $e) {
            fleekdash_log_error("FleekDash getAllSchemas error: " . $e->getMessage());
            return ResponseService::error('Failed to fetch schemas: ' . $e->getMessage());
        }
    }

    /**
     * Debug method to check post types
     *
     * @param \WP_REST_Request $request
     * @return \WP_REST_Response
     */
    public function debugPostTypes($request)
    {
        try {
            $all_post_types = \get_post_types([], 'objects');
            $public_post_types = \get_post_types(['public' => true], 'objects');
            $rest_enabled_post_types = \get_post_types(['show_in_rest' => true], 'objects');
            $final_post_types = \get_post_types(['public' => true, 'show_in_rest' => true], 'objects');

            $debug_info = [
                'wp_debug' => defined('WP_DEBUG') ? WP_DEBUG : false,
                'counts' => [
                    'all' => count($all_post_types),
                    'public' => count($public_post_types),
                    'rest_enabled' => count($rest_enabled_post_types),
                    'final' => count($final_post_types)
                ],
                'all_post_types' => array_keys($all_post_types),
                'public_post_types' => array_keys($public_post_types),
                'rest_enabled_post_types' => array_keys($rest_enabled_post_types),
                'final_post_types' => array_keys($final_post_types),
                'final_post_types_details' => []
            ];

            foreach ($final_post_types as $slug => $post_type_obj) {
                $debug_info['final_post_types_details'][$slug] = [
                    'name' => $post_type_obj->name,
                    'label' => $post_type_obj->label,
                    'public' => $post_type_obj->public,
                    'show_in_rest' => $post_type_obj->show_in_rest,
                    'rest_base' => $post_type_obj->rest_base
                ];
            }

            // Add Voxel investigation
            $debug_info['voxel_investigation'] = $this->voxelProvider->investigateVoxelFields();

            return ResponseService::success($debug_info, 'Debug info retrieved successfully');

        } catch (\Exception $e) {
            return ResponseService::error('Failed to fetch debug info: ' . $e->getMessage());
        }
    }

    /**
     * Get status of auto-registered REST endpoints
     */
    public function autoRegisterRestEndpoints()
    {
        try {
            $post_types = \get_post_types([], 'objects');
            $total_custom = 0;
            $already_registered = 0;
            $auto_registered = 0;

            foreach ($post_types as $post_type_slug => $post_type_obj) {
                // Skip built-in types
                if (in_array($post_type_slug, ['post', 'page', 'attachment', 'revision', 'nav_menu_item', 'custom_css', 'customize_changeset', 'oembed_cache', 'user_request', 'wp_block'])) {
                    continue;
                }

                $total_custom++;

                if ($post_type_obj->show_in_rest && !empty($post_type_obj->rest_base)) {
                    $already_registered++;
                } else {
                    $auto_registered++;
                }
            }

            return ResponseService::success([
                'total_custom_post_types' => $total_custom,
                'already_registered' => $already_registered,
                'auto_registered' => $auto_registered,
                'auto_registration_active' => true
            ], "REST endpoints are automatically registered. {$auto_registered} custom post types have auto-generated endpoints.");

        } catch (\Exception $e) {
            return ResponseService::error('Failed to get REST endpoint status: ' . $e->getMessage());
        }
    }

    /**
     * Upload files endpoint
     *
     * @param \WP_REST_Request $request
     * @return \WP_REST_Response
     */
    public function uploadFiles($request)
    {
        return $this->fileUploadHandler->uploadFiles($request);
    }

    /**
     * Investigate Voxel repeaters
     *
     * @param \WP_REST_Request $request
     * @return \WP_REST_Response
     */
    public function investigateVoxelRepeaters($request)
    {
        try {
            $results = [
                'voxel_available' => false,
                'post_types_with_repeaters' => [],
                'sample_repeater_data' => [],
                'repeater_field_configs' => []
            ];

            if (!class_exists('\Voxel\Post_Type')) {
                return ResponseService::success($results, 'Voxel not available');
            }

            $results['voxel_available'] = true;

            $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();

                    if (in_array($field_type, ['repeater', 'group', 'fieldset', 'repeating-group'])) {
                        $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() : [],
                        ];

                        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
                    ];
                }
            }

            return ResponseService::success($results, 'Voxel repeater investigation completed');

        } catch (\Exception $e) {
            fleekdash_log_error("FleekDash: Voxel repeater investigation error: " . $e->getMessage());
            return ResponseService::error('Investigation failed: ' . $e->getMessage(), [], 500);
        }
    }

    /**
     * Auto-register REST endpoints during rest_api_init hook
     */
    public static function initRestEndpoints()
    {
        $controller = new self();

        $post_types = \get_post_types([], 'objects');
        $registered_count = 0;

        foreach ($post_types as $post_type_slug => $post_type_obj) {
            // Skip built-in types
            if (in_array($post_type_slug, ['post', 'page', 'attachment', 'revision', 'nav_menu_item', 'custom_css', 'customize_changeset', 'oembed_cache', 'user_request', 'wp_block'])) {
                continue;
            }

            // Check if needs REST API registration
            if (!$post_type_obj->show_in_rest || empty($post_type_obj->rest_base)) {
                $controller->restCrudHandler->registerCustomPostTypeRest($post_type_slug, $post_type_obj);
                $registered_count++;
            }
        }
    }

    /**
     * Register test custom post types for demonstration
     */
    public static function registerTestPostTypes()
    {
        SchemaHelpers::registerTestPostTypes();
    }
}
