<?php

declare(strict_types=1);

namespace App\Framework\FormGenerator;

use App\Framework\LiveComponents\FormBuilder\FieldType;
use App\Framework\View\FormBuilder;

/**
 * Generiert FormBuilder aus Request Object
 */
final readonly class RequestFormGenerator
{
    public function __construct(
        private RequestPropertyAnalyzer $analyzer
    ) {
    }

    /**
     * Generate FormBuilder from Request class
     */
    public function generate(string $requestClass): FormBuilder
    {
        // 1. Analyze Request class
        $schema = $this->analyzer->analyze($requestClass);

        // 2. Create FormBuilder
        $builder = FormBuilder::create();

        // 3. Add fields from schema
        foreach ($schema->fields as $field) {
            $builder = $this->addFieldToBuilder($builder, $field);
        }

        return $builder;
    }

    /**
     * Add single field to FormBuilder based on schema
     */
    private function addFieldToBuilder(FormBuilder $builder, FormFieldSchema $field): FormBuilder
    {
        $label = $field->getLabel();
        $name = $field->name;

        // Create FormElement with attributes applied
        $element = $this->createFormElementWithAttributes($field);

        // Add label if needed
        if ($label && $field->fieldType !== FieldType::HIDDEN) {
            $labelElement = \App\Framework\View\ValueObjects\FormElement::label($label, $name);
            $builder = $builder->addElement($labelElement);
        }

        // Add field element
        return $builder->addElement($element);
    }

    /**
     * Create FormElement with validation attributes applied
     */
    private function createFormElementWithAttributes(FormFieldSchema $field): \App\Framework\View\ValueObjects\FormElement
    {
        $name = $field->name;
        $value = $field->defaultValue ?? '';

        // Create base element
        $element = match ($field->fieldType) {
            FieldType::TEXT => \App\Framework\View\ValueObjects\FormElement::textInput($name, (string) $value),
            FieldType::EMAIL => \App\Framework\View\ValueObjects\FormElement::emailInput($name, (string) $value),
            FieldType::PASSWORD => \App\Framework\View\ValueObjects\FormElement::passwordInput($name),
            FieldType::TEXTAREA => \App\Framework\View\ValueObjects\FormElement::textarea($name, (string) $value),
            FieldType::NUMBER => \App\Framework\View\ValueObjects\FormElement::textInput($name, (string) $value),
            FieldType::CHECKBOX => \App\Framework\View\ValueObjects\FormElement::input('checkbox', $name, (string) $value),
            FieldType::SELECT => \App\Framework\View\ValueObjects\FormElement::input('text', $name, (string) $value), // TODO: Proper select
            FieldType::RADIO => \App\Framework\View\ValueObjects\FormElement::input('radio', $name, (string) $value),
            FieldType::DATE => \App\Framework\View\ValueObjects\FormElement::input('date', $name, (string) $value),
            FieldType::FILE => \App\Framework\View\ValueObjects\FormElement::fileInput($name),
            FieldType::HIDDEN => \App\Framework\View\ValueObjects\FormElement::hiddenInput($name, (string) $value),
        };

        // Add ID attribute
        $element = $element->withId($name);

        // Apply HTML attributes from validation
        foreach ($field->htmlAttributes as $attrName => $attrValue) {
            if ($attrName === 'required' && $attrValue === true) {
                $element = $element->withRequired();
            } elseif ($attrName === 'type') {
                // Type already set during element creation
                continue;
            } else {
                // Generic attribute (minlength, maxlength, pattern, etc.)
                $element = $element->withAttribute($attrName, (string) $attrValue);
            }
        }

        return $element;
    }
}
