<?php

namespace Daylight\Core\Http\Requests\Store\Categories;

use Daylight\Core\Http\Requests\Concerns\HandlesSeoRequest;
use Daylight\Core\Models\Enums\DisplayType;
use Daylight\Core\Modules\PageBuilder\Concerns\InteractsWithPageBuilder;
use Daylight\Core\Modules\PageBuilder\Contracts\HasPageBuilder;
use Daylight\Core\Modules\PageBuilder\Registries\ComponentRegistry;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class UpdateCategoryRequest extends FormRequest implements HasPageBuilder
{
    use HandlesSeoRequest;
    use InteractsWithPageBuilder;

    public function authorize(): bool
    {
        return auth()->check() && auth()->user()->can('update:categories');
    }

    public function rules(): array
    {
        return [
            'parent_id' => ['nullable', 'exists:categories,id'],
            'order' => ['required', 'integer'],
            'display' => ['required', Rule::in(DisplayType::cases())],
            'manual_sorting' => ['required', 'boolean'],
            'name' => ['required', 'string', 'max:255'],
            'locale' => ['required', 'string', 'max:255'],
            'image' => ['nullable'],
            'image.*.id' => ['exists:media,id'],
            ...$this->getSeoRules(),
            ...$this->getPageBuilderRules(
                required: false
            ),
        ];
    }

    public function prepareForValidation(): void
    {

        $components = $this->input('components');
        if (is_string($components)) {
            $components = json_decode($components, true);
        }

        if (is_array($components)) {
            foreach ($components as $key => $component) {
                if (isset($component['data']['image'])) {
                    // Als image een string is, decodeer het
                    if (is_string($component['data']['image'])) {
                        $component['data']['image'] = json_decode($component['data']['image'], true);
                    }
                    // Zorg ervoor dat image altijd een array is
                    if ($component['data']['image'] === null) {
                        $component['data']['image'] = [];
                    }
                    $components[$key] = $component;
                }
            }
        }

        $this->merge([
            'components' => $components,
            'image' => json_decode($this->input('image'), true),
        ]);

    }

    public function messages(): array
    {
        $messages = [
            'components.required' => __('At least one component is required.'),
            'components.*.type.required' => __('Component type is required.'),
            'components.*.data.required' => __('Component data is required.'),
        ];

        // Generate messages for component fields dynamically
        $registry = app(ComponentRegistry::class);
        $components = $this->input('components', []);

        if (is_string($components)) {
            $components = json_decode($components, true) ?: [];
        }

        if (! is_array($components)) {
            return $messages;
        }

        foreach ($components as $index => $component) {
            if (! isset($component['type']) || ! is_array($component)) {
                continue;
            }

            $definition = $registry->getDefinition($component['type']);
            if (! $definition) {
                continue;
            }

            $componentName = $definition->name();

            foreach ($definition->fields() as $field) {
                $fieldPath = "components.{$index}.data.{$field->name}";
                $fieldLabel = $field->label;

                // Required messages
                $messages["{$fieldPath}.required"] = __('The :field field in component \':component\' (:index) is required.', [
                    'field' => strtolower($fieldLabel),
                    'component' => $componentName,
                    'index' => $index + 1,
                ]);

                // Type-specific messages
                switch ($field->type) {
                    case 'media':
                        $messages["{$fieldPath}.min"] = __('The :field field in component \':component\' (:index) must have at least (.min) item(s).', [
                            'field' => strtolower($fieldLabel),
                            'component' => $componentName,
                            'min' => 1,
                            'index' => $index + 1,
                        ]);
                        $messages["{$fieldPath}.*.id.required"] = __('The :field field in component \':component\' (:index) contains invalid media.', [
                            'field' => strtolower($fieldLabel),
                            'component' => $componentName,
                            'index' => $index + 1,
                        ]);
                        $messages["{$fieldPath}.*.id.exists"] = __('The :field field in component \':component\' (:index) contains invalid media.', [
                            'field' => strtolower($fieldLabel),
                            'component' => $componentName,
                            'index' => $index + 1,
                        ]);
                        break;

                    case 'related':
                        $messages["{$fieldPath}.*.id.required"] = __('The :field field in component :\'component\' (:index) is invalid.', [
                            'field' => strtolower($fieldLabel),
                            'component' => $componentName,
                            'index' => $index + 1,
                        ]);
                        $messages["{$fieldPath}.*.id.integer"] = __('The :field field in component \':component\' (:index) must be valid.', [
                            'field' => strtolower($fieldLabel),
                            'component' => $componentName,
                            'index' => $index + 1,
                        ]);
                        break;

                    case 'repeater':
                        foreach ($field->items as $subField) {
                            $subFieldPath = "{$fieldPath}.*.{$subField->name}";
                            $subFieldLabel = $subField->label;

                            $messages["{$subFieldPath}.required"] = __('The :field field in component \':component\' (:index) row is required.', [
                                'field' => strtolower($subFieldLabel),
                                'component' => $componentName,
                                'index' => $index + 1,
                            ]);

                            if ($subField->type === 'media') {
                                $messages["{$subFieldPath}.*.id.required"] = __('The :field field in component \':component\' (:index) row contains invalid media.', [
                                    'field' => strtolower($subFieldLabel),
                                    'component' => $componentName,
                                    'index' => $index + 1,
                                ]);
                                $messages["{$subFieldPath}.*.id.exists"] = __('The :field field in component \':component\' (:index) row contains invalid media.', [
                                    'field' => strtolower($subFieldLabel),
                                    'component' => $componentName,
                                    'index' => $index + 1,
                                ]);
                            }
                        }
                        break;
                }
            }
        }

        return $messages;
    }

    public function attributes(): array
    {
        $attributes = [
            'locale' => __('Locale'),
            'name' => __('Name'),
            'slug' => __('Slug'),
            'template' => __('Template'),
            'components' => __('Components'),
        ];

        // Generate friendly attribute names for component fields
        $registry = app(ComponentRegistry::class);
        $components = $this->input('components', []);

        if (is_string($components)) {
            $components = json_decode($components, true) ?: [];
        }

        if (! is_array($components)) {
            return $attributes;
        }

        foreach ($components as $index => $component) {
            if (! isset($component['type']) || ! is_array($component)) {
                continue;
            }

            $definition = $registry->getDefinition($component['type']);
            if (! $definition) {
                continue;
            }

            $componentName = $definition->name();

            foreach ($definition->fields() as $field) {
                $fieldPath = "components.{$index}.data.{$field->name}";
                $attributes[$fieldPath] = "{$field->label} ({$componentName})";

                // Handle nested fields (buttons, repeaters, etc.)
                if ($field->type === 'button') {
                    $attributes["{$fieldPath}.url"] = "{$field->label} - " . __('URL');
                    $attributes["{$fieldPath}.label"] = "{$field->label} - " . __('Label');
                }

                if ($field->type === 'repeater') {
                    foreach ($field->items as $subField) {
                        $subFieldPath = "{$fieldPath}.*.{$subField->name}";
                        $attributes[$subFieldPath] = "{$field->label} - {$subField->label} ({$componentName})";
                    }
                }
            }
        }

        return $attributes;
    }
}
