# LiveComponent FormBuilder Integration

Elegante Integration zwischen LiveComponent System und bestehendem FormBuilder.

## Architektur

```
┌─────────────────────────┐
│ MultiStepFormDefinition │  ← Value Object mit Steps
└────────────┬────────────┘
             │
             ├─► FormStepDefinition  ← Step-Info + Fields
             │
             └─► FormFieldDefinition ← Field-Config (text, email, etc.)
                      │
                      ├─► FieldType (enum)
                      ├─► FieldCondition (conditional rendering)
                      └─► StepValidator (validation logic)

┌─────────────────────────┐
│ MultiStepFormComponent  │  ← Generic LiveComponent
└────────────┬────────────┘
             │
             └─► LiveFormBuilder ← Erweitert bestehenden FormBuilder
                      │
                      └─► FormBuilder (bestehend, wiederverwendet!)
```

## Verwendungsbeispiel

### 1. Form Definition erstellen (Deklarativ, Type-Safe)

```php
use App\Framework\LiveComponents\FormBuilder\MultiStepFormDefinition;
use App\Framework\LiveComponents\FormBuilder\FormStepDefinition;
use App\Framework\LiveComponents\FormBuilder\FormFieldDefinition;
use App\Framework\LiveComponents\FormBuilder\FieldCondition;

// Deklarative Form-Definition - kein Code-Duplikat!
$userRegistrationForm = new MultiStepFormDefinition(
    steps: [
        // Step 1: Personal Information
        new FormStepDefinition(
            title: 'Persönliche Informationen',
            description: 'Bitte geben Sie Ihre persönlichen Daten ein',
            fields: [
                FormFieldDefinition::text(
                    name: 'first_name',
                    label: 'Vorname',
                    required: true
                ),
                FormFieldDefinition::text(
                    name: 'last_name',
                    label: 'Nachname',
                    required: true
                ),
                FormFieldDefinition::email(
                    name: 'email',
                    label: 'E-Mail Adresse',
                    required: true
                )
            ],
            validator: new PersonalInfoValidator()
        ),

        // Step 2: Account Type
        new FormStepDefinition(
            title: 'Konto-Typ',
            description: 'Wählen Sie Ihren Konto-Typ',
            fields: [
                FormFieldDefinition::radio(
                    name: 'account_type',
                    label: 'Account Type',
                    options: [
                        'personal' => 'Privatkonto',
                        'business' => 'Geschäftskonto'
                    ],
                    required: true
                ),
                // Conditional Field - nur bei Business
                FormFieldDefinition::text(
                    name: 'company_name',
                    label: 'Firmenname',
                    required: true
                )->showWhen(
                    FieldCondition::equals('account_type', 'business')
                ),
                FormFieldDefinition::text(
                    name: 'vat_number',
                    label: 'USt-IdNr.',
                    placeholder: 'DE123456789'
                )->showWhen(
                    FieldCondition::equals('account_type', 'business')
                )
            ],
            validator: new AccountTypeValidator()
        ),

        // Step 3: Preferences
        new FormStepDefinition(
            title: 'Präferenzen',
            description: 'Passen Sie Ihre Einstellungen an',
            fields: [
                FormFieldDefinition::checkbox(
                    name: 'newsletter',
                    label: 'Newsletter abonnieren'
                ),
                FormFieldDefinition::select(
                    name: 'language',
                    label: 'Bevorzugte Sprache',
                    options: [
                        'en' => 'English',
                        'de' => 'Deutsch',
                        'fr' => 'Français'
                    ],
                    defaultValue: 'de'
                )
            ]
        )
    ],
    submitHandler: new UserRegistrationSubmitHandler()
);
```

### 2. Validator implementieren

```php
use App\Framework\LiveComponents\FormBuilder\StepValidator;

final readonly class PersonalInfoValidator implements StepValidator
{
    public function validate(array $formData): array
    {
        $errors = [];

        if (empty($formData['first_name'] ?? '')) {
            $errors['first_name'] = 'Vorname ist erforderlich';
        }

        if (empty($formData['last_name'] ?? '')) {
            $errors['last_name'] = 'Nachname ist erforderlich';
        }

        if (empty($formData['email'] ?? '')) {
            $errors['email'] = 'E-Mail ist erforderlich';
        } elseif (!filter_var($formData['email'], FILTER_VALIDATE_EMAIL)) {
            $errors['email'] = 'Ungültige E-Mail Adresse';
        }

        return $errors;
    }
}

final readonly class AccountTypeValidator implements StepValidator
{
    public function validate(array $formData): array
    {
        $errors = [];

        if (empty($formData['account_type'] ?? '')) {
            $errors['account_type'] = 'Bitte wählen Sie einen Konto-Typ';
        }

        // Conditional validation für Business
        if (($formData['account_type'] ?? '') === 'business') {
            if (empty($formData['company_name'] ?? '')) {
                $errors['company_name'] = 'Firmenname ist erforderlich';
            }
        }

        return $errors;
    }
}
```

### 3. Submit Handler implementieren

```php
use App\Framework\LiveComponents\FormBuilder\FormSubmitHandler;
use App\Framework\LiveComponents\FormBuilder\SubmitResult;

final readonly class UserRegistrationSubmitHandler implements FormSubmitHandler
{
    public function __construct(
        private UserService $userService
    ) {}

    public function handle(array $formData): SubmitResult
    {
        try {
            $user = $this->userService->registerUser(
                firstName: $formData['first_name'],
                lastName: $formData['last_name'],
                email: $formData['email'],
                accountType: $formData['account_type'],
                companyName: $formData['company_name'] ?? null,
                newsletter: ($formData['newsletter'] ?? 'no') === 'yes',
                language: $formData['language'] ?? 'de'
            );

            return SubmitResult::success(
                message: 'Registrierung erfolgreich!',
                redirectUrl: '/dashboard',
                data: ['user_id' => $user->id]
            );
        } catch (\Exception $e) {
            return SubmitResult::failure(
                message: 'Registrierung fehlgeschlagen: ' . $e->getMessage()
            );
        }
    }
}
```

### 4. Controller Setup

```php
use App\Framework\Http\Attributes\Route;
use App\Framework\Http\Method;
use App\Framework\Http\ViewResult;
use App\Framework\LiveComponents\FormBuilder\MultiStepFormComponent;
use App\Framework\LiveComponents\ValueObjects\ComponentId;

final readonly class UserRegistrationController
{
    #[Route('/register', method: Method::GET)]
    public function showRegistrationForm(): ViewResult
    {
        // Form Definition (könnte auch aus Container kommen)
        $formDefinition = $this->createUserRegistrationForm();

        // Component erstellen
        $component = new MultiStepFormComponent(
            id: ComponentId::generate('user-registration'),
            formDefinition: $formDefinition
        );

        return new ViewResult(
            template: 'pages/register',
            data: [
                'registration_form' => $component
            ]
        );
    }

    private function createUserRegistrationForm(): MultiStepFormDefinition
    {
        return new MultiStepFormDefinition(
            steps: [
                // ... (wie oben)
            ],
            submitHandler: new UserRegistrationSubmitHandler($this->userService)
        );
    }
}
```

### 5. Template Usage

```html
<!-- pages/register.view.php -->
<div class="registration-page">
    <h1>Benutzerregistrierung</h1>

    <!-- LiveComponent einbinden -->
    <livecomponent name="multi-step-form" data="registration_form" />
</div>
```

## Vorteile dieser Lösung

### ✅ Kein Code-Duplikat
- Nutzt bestehenden `FormBuilder` aus View-Modul
- `LiveFormBuilder` erweitert nur mit LiveComponent-Features
- Keine doppelte Field-Rendering-Logik

### ✅ Type-Safe & Framework-Compliant
- Alle Value Objects: `FormFieldDefinition`, `FormStepDefinition`, `MultiStepFormDefinition`
- Readonly Classes überall
- Enums für `FieldType`

### ✅ Deklarativ statt Imperativ
- Form-Definition rein deklarativ (kein Code für Rendering)
- Klare Trennung: Definition vs. Rendering vs. Validation vs. Submission

### ✅ Conditional Fields eingebaut
```php
FormFieldDefinition::text('company_name', 'Firma', required: true)
    ->showWhen(FieldCondition::equals('account_type', 'business'))
```

### ✅ Wiederverwendbare Validators
```php
final readonly class EmailValidator implements StepValidator
{
    public function validate(array $formData): array
    {
        // Wiederverwendbare Validation-Logic
    }
}
```

### ✅ Testbar
```php
// Unit Test für Validator
it('validates email format', function () {
    $validator = new PersonalInfoValidator();

    $errors = $validator->validate(['email' => 'invalid']);

    expect($errors)->toHaveKey('email');
});

// Integration Test für Component
it('moves to next step after validation', function () {
    $component = new MultiStepFormComponent(
        id: ComponentId::generate('test'),
        formDefinition: $this->testFormDef
    );

    $result = $component->nextStep([
        'first_name' => 'John',
        'last_name' => 'Doe',
        'email' => 'john@example.com'
    ]);

    expect($result->get('current_step'))->toBe(2);
});
```

## Erweiterungsmöglichkeiten

### Custom Field Types

```php
// Neuen FieldType hinzufügen
enum FieldType: string
{
    case TEXT = 'text';
    case EMAIL = 'email';
    // ... existing types
    case DATE = 'date';
    case PHONE = 'phone';
    case CURRENCY = 'currency';
}

// LiveFormBuilder erweitern
final readonly class LiveFormBuilder
{
    public function addLiveDateInput(
        string $name,
        string $label,
        ?string $value = null
    ): self {
        // Implementation
    }
}
```

### Multi-Field Conditions

```php
final readonly class AndCondition implements FieldConditionContract
{
    public function __construct(
        private FieldCondition $left,
        private FieldCondition $right
    ) {}

    public function matches(array $formData): bool
    {
        return $this->left->matches($formData)
            && $this->right->matches($formData);
    }
}

// Usage
FormFieldDefinition::text('special_field', 'Special')
    ->showWhen(
        new AndCondition(
            FieldCondition::equals('account_type', 'business'),
            FieldCondition::equals('country', 'DE')
        )
    );
```

### Custom Renderers

```php
interface FieldRenderer
{
    public function render(FormFieldDefinition $field, mixed $value): string;
}

final readonly class CustomTextRenderer implements FieldRenderer
{
    public function render(FormFieldDefinition $field, mixed $value): string
    {
        // Custom rendering logic
    }
}
```

## Vergleich: Vorher vs. Nachher

### ❌ Vorher (Code-Duplikat)

```php
// Hardcoded Form in Component
public function getRenderData(): ComponentRenderData
{
    return new ComponentRenderData(
        templatePath: 'livecomponent-dynamic-form',
        data: [
            'form_first_name' => $formData['first_name'] ?? '',
            'form_last_name' => $formData['last_name'] ?? '',
            // ... 50 weitere Zeilen hardcoded mappings
        ]
    );
}
```

### ✅ Nachher (Wiederverwendbar)

```php
// Deklarative Definition
$formDef = new MultiStepFormDefinition(
    steps: [
        new FormStepDefinition(
            title: 'Personal Info',
            fields: [
                FormFieldDefinition::text('first_name', 'First Name'),
                FormFieldDefinition::text('last_name', 'Last Name')
            ]
        )
    ]
);

// Generic Component - keine Anpassungen nötig!
$component = new MultiStepFormComponent(
    id: ComponentId::generate('my-form'),
    formDefinition: $formDef
);
```

## Zusammenfassung

Diese Integration:
- ✅ Nutzt bestehenden `FormBuilder` (keine Code-Duplizierung)
- ✅ Erweitert ihn minimal für LiveComponent-Features
- ✅ Vollständig type-safe mit Value Objects
- ✅ Framework-compliant (readonly, final, composition)
- ✅ Deklarative Form-Definitionen
- ✅ Conditional Fields eingebaut
- ✅ Wiederverwendbare Validators
- ✅ Generische Component (kein Custom-Code pro Form)
- ✅ Einfach testbar
- ✅ Leicht erweiterbar
