<?php

declare(strict_types=1);

namespace App\Application\LiveComponents\DynamicForm;

use App\Framework\LiveComponents\Attributes\Action;
use App\Framework\LiveComponents\Attributes\LiveComponent;
use App\Framework\LiveComponents\Contracts\LiveComponentContract;
use App\Framework\LiveComponents\ValueObjects\ComponentId;
use App\Framework\LiveComponents\ValueObjects\ComponentRenderData;

/**
 * DynamicFormComponent - Multi-step form with conditional fields
 *
 * Demonstrates:
 * - Type-safe state management with DynamicFormState Value Object
 * - Multi-step wizard interface
 * - Conditional field visibility based on selections
 * - Live validation with error handling
 * - Progress tracking across steps
 * - Form state preservation between steps
 * - Compile-time type safety for data access
 */
#[LiveComponent('dynamic-form')]
final readonly class DynamicFormComponent implements LiveComponentContract
{
    public function __construct(
        public ComponentId $id,
        public DynamicFormState $state
    ) {
    }

    public function getRenderData(): ComponentRenderData
    {
        $formData = $this->state->formData;
        $errors = $this->state->errors;

        return new ComponentRenderData(
            templatePath: 'livecomponent-dynamic-form',
            data: [
                // Raw data
                'current_step' => $this->state->currentStep,
                'total_steps' => $this->state->totalSteps,
                'form_data' => $formData,
                'form_data_json' => json_encode($formData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE),
                'errors' => $errors,
                'submitted' => $this->state->submitted,
                'submission_id' => $this->state->submissionId,

                // Flattened form data for placeholders
                'form_first_name' => $formData['first_name'] ?? '',
                'form_last_name' => $formData['last_name'] ?? '',
                'form_email' => $formData['email'] ?? '',
                'form_company_name' => $formData['company_name'] ?? '',
                'form_vat_number' => $formData['vat_number'] ?? '',
                'form_language' => $formData['language'] ?? 'en',
                'form_timezone' => $formData['timezone'] ?? 'UTC',
                'form_full_name' => trim(($formData['first_name'] ?? '') . ' ' . ($formData['last_name'] ?? '')),

                // Display-specific properties
                'stepTitle' => $this->state->getStepTitle($this->state->currentStep),
                'stepDescription' => $this->state->getStepDescription($this->state->currentStep),
                'canGoNext' => $this->state->canGoNext(),
                'canGoPrevious' => $this->state->canGoPrevious(),
                'isFirstStep' => $this->state->isFirstStep(),
                'isSecondStep' => $this->state->currentStep === 2,
                'isThirdStep' => $this->state->currentStep === 3,
                'isLastStep' => $this->state->isLastStep(),
                'isFinalStep' => $this->state->isLastStep(),
                'showBusinessFields' => $this->state->shouldShowBusinessFields(),
                'progressPercentage' => $this->state->getProgressPercentage(),
                'progressText' => $this->state->getProgressText(),
                'hasErrors' => $this->state->hasErrors(),
                'errorCount' => $this->state->getErrorCount(),
                'submitButtonText' => $this->state->getSubmitButtonText(),
                'nextButtonText' => $this->state->getNextButtonText(),
                'steps' => $this->state->getStepsForDisplay(),

                // Input CSS classes
                'first_name_class' => 'form-input' . (isset($errors['first_name']) ? ' error' : ''),
                'last_name_class' => 'form-input' . (isset($errors['last_name']) ? ' error' : ''),
                'email_class' => 'form-input' . (isset($errors['email']) ? ' error' : ''),
                'company_name_class' => 'form-input' . (isset($errors['company_name']) ? ' error' : ''),
                'vat_number_class' => 'form-input' . (isset($errors['vat_number']) ? ' error' : ''),

                // Radio/Checkbox states
                'personal_checked' => ($formData['account_type'] ?? '') === 'personal' ? 'checked' : '',
                'business_checked' => ($formData['account_type'] ?? '') === 'business' ? 'checked' : '',
                'newsletter_checked' => ($formData['newsletter'] ?? 'no') === 'yes' ? 'checked' : '',
                'newsletter_toggle_value' => ($formData['newsletter'] ?? 'no') === 'yes' ? 'no' : 'yes',

                // Select options
                'language_en_selected' => ($formData['language'] ?? 'en') === 'en' ? 'selected' : '',
                'language_de_selected' => ($formData['language'] ?? 'en') === 'de' ? 'selected' : '',
                'language_fr_selected' => ($formData['language'] ?? 'en') === 'fr' ? 'selected' : '',
                'language_es_selected' => ($formData['language'] ?? 'en') === 'es' ? 'selected' : '',

                'timezone_utc_selected' => ($formData['timezone'] ?? 'UTC') === 'UTC' ? 'selected' : '',
                'timezone_berlin_selected' => ($formData['timezone'] ?? 'UTC') === 'Europe/Berlin' ? 'selected' : '',
                'timezone_ny_selected' => ($formData['timezone'] ?? 'UTC') === 'America/New_York' ? 'selected' : '',
                'timezone_tokyo_selected' => ($formData['timezone'] ?? 'UTC') === 'Asia/Tokyo' ? 'selected' : '',

                // Review display
                'account_type_display' => ($formData['account_type'] ?? 'personal') === 'business' ? 'Business' : 'Personal',
                'newsletter_display' => ($formData['newsletter'] ?? 'no') === 'yes' ? 'Subscribed' : 'Not subscribed',
            ]
        );
    }

    // Action methods - Type-safe parameters

    #[Action]
    public function nextStep(array $params = []): DynamicFormState
    {
        error_log('[DynamicForm] nextStep called with params: ' . json_encode($params));
        error_log('[DynamicForm] Current state formData: ' . json_encode($this->state->formData));

        // Update form data with all passed parameters at once
        $newState = ! empty($params)
            ? $this->state->withUpdatedFields($params)
            : $this->state;

        error_log('[DynamicForm] New state formData after update: ' . json_encode($newState->formData));

        // Validate current step with updated data
        $errors = $this->validateStep($newState->currentStep, $newState->formData);

        return $newState->withNextStep($errors);
    }

    #[Action]
    public function previousStep(array $params = []): DynamicFormState
    {
        // Update form data with all passed parameters before going back
        $newState = ! empty($params)
            ? $this->state->withUpdatedFields($params)
            : $this->state;

        return $newState->withPreviousStep();
    }

    #[Action]
    public function updateField(array $params = []): DynamicFormState
    {
        $newState = $this->state;

        // Update all provided fields
        // Note: withUpdatedField already clears errors
        foreach ($params as $field => $value) {
            $newState = $newState->withUpdatedField($field, (string) $value);
        }

        return $newState;
    }

    #[Action]
    public function submit(array $params = []): DynamicFormState
    {
        // Update form data with all passed parameters at once
        $newState = ! empty($params)
            ? $this->state->withUpdatedFields($params)
            : $this->state;

        // Validate all steps with final form data
        $errors = $this->validateAllSteps($newState->formData);

        $submissionId = empty($errors)
            ? 'FORM-' . strtoupper(substr(md5((string) time()), 0, 8))
            : null;

        return $newState->withSubmission($errors, $submissionId);
    }

    #[Action]
    public function reset(): DynamicFormState
    {
        return $this->state->withReset();
    }

    // Validation methods

    private function validateStep(int $step, array $formData): array
    {
        $errors = [];

        switch ($step) {
            case 1:
                // Personal Info Validation
                if (empty($formData['first_name'] ?? '')) {
                    $errors['first_name'] = 'First name is required';
                }
                if (empty($formData['last_name'] ?? '')) {
                    $errors['last_name'] = 'Last name is required';
                }
                if (empty($formData['email'] ?? '')) {
                    $errors['email'] = 'Email is required';
                } elseif (! filter_var($formData['email'], FILTER_VALIDATE_EMAIL)) {
                    $errors['email'] = 'Invalid email format';
                }

                break;

            case 2:
                // Account Type Validation
                if (empty($formData['account_type'] ?? '')) {
                    $errors['account_type'] = 'Please select an account type';
                }

                // Conditional validation based on account type
                if (($formData['account_type'] ?? '') === 'business') {
                    if (empty($formData['company_name'] ?? '')) {
                        $errors['company_name'] = 'Company name is required for business accounts';
                    }
                    if (empty($formData['vat_number'] ?? '')) {
                        $errors['vat_number'] = 'VAT number is required for business accounts';
                    }
                }

                break;

            case 3:
                // Preferences Validation (optional fields, set defaults)
                break;

            case 4:
                // Review - no additional validation needed
                break;
        }

        return $errors;
    }

    private function validateAllSteps(array $formData): array
    {
        $allErrors = [];

        for ($step = 1; $step <= $this->state->totalSteps; $step++) {
            $stepErrors = $this->validateStep($step, $formData);
            $allErrors = array_merge($allErrors, $stepErrors);
        }

        return $allErrors;
    }
}
