<?php

declare(strict_types=1);

namespace App\Framework\Http\Session\ValueObjects;

/**
 * Value Object representing a collection of form data
 */
final readonly class FormDataCollection
{
    /**
     * @param array<string, FormData> $forms Form data indexed by form ID
     */
    public function __construct(public array $forms = [])
    {
    }

    /**
     * Create from raw array
     * @param array<string, array<string, mixed>> $rawData
     */
    public static function fromArray(array $rawData): self
    {
        $forms = [];
        foreach ($rawData as $formId => $formData) {
            if (is_array($formData)) {
                $forms[$formId] = FormData::fromArray($formData);
            }
        }

        return new self($forms);
    }

    /**
     * Convert to array
     * @return array<string, array<string, mixed>>
     */
    public function toArray(): array
    {
        $result = [];
        foreach ($this->forms as $formId => $formData) {
            $result[$formId] = $formData->toArray();
        }

        return $result;
    }

    /**
     * Get form data by ID
     */
    public function get(string $formId): ?FormData
    {
        return $this->forms[$formId] ?? null;
    }

    /**
     * Check if form exists
     */
    public function has(string $formId): bool
    {
        return isset($this->forms[$formId]);
    }

    /**
     * Add or update form data
     */
    public function with(string $formId, FormData $formData): self
    {
        $forms = $this->forms;
        $forms[$formId] = $formData;

        return new self($forms);
    }

    /**
     * Remove form data
     */
    public function without(string $formId): self
    {
        $forms = $this->forms;
        unset($forms[$formId]);

        return new self($forms);
    }

    /**
     * Get all form IDs
     * @return array<string>
     */
    public function getFormIds(): array
    {
        return array_keys($this->forms);
    }

    /**
     * Check if collection is empty
     */
    public function isEmpty(): bool
    {
        return empty($this->forms);
    }

    /**
     * Get form count
     */
    public function count(): int
    {
        return count($this->forms);
    }

    /**
     * Get all forms as array
     * @return array<string, FormData>
     */
    public function all(): array
    {
        return $this->forms;
    }
}
