<?php

declare(strict_types=1);

namespace App\Framework\LiveComponents\ValueObjects;

use App\Framework\Http\HttpRequest;
use App\Framework\Security\CsrfToken;

/**
 * Value Object representing an action to be performed on a LiveComponent
 */
final readonly class ComponentAction
{
    public function __construct(
        public ComponentId $componentId,
        public string $method,
        public ActionParameters $params
    ) {
    }

    public static function fromRequest(HttpRequest $request, ?string $componentId = null): self
    {
        $data = $request->parsedBody?->toArray() ?? [];

        $idString = $componentId ?? $data['component_id'] ?? '';

        // Extract CSRF token from request body or header
        $csrfTokenString = $data['_csrf_token'] ??
                          $data['csrf_token'] ??
                          $request->headers->getFirst('X-CSRF-Token');

        // Create CsrfToken Value Object if token is present
        $csrfToken = null;
        if ($csrfTokenString !== null && $csrfTokenString !== '') {
            try {
                $csrfToken = CsrfToken::fromString($csrfTokenString);
            } catch (\InvalidArgumentException $e) {
                // Invalid token format - leave as null, will fail validation in handler
                $csrfToken = null;
            }
        }

        return new self(
            componentId: ComponentId::fromString($idString),
            method: $data['method'] ?? '',
            params: ActionParameters::fromArray($data['params'] ?? [], $csrfToken)
        );
    }

    public function toArray(): array
    {
        return [
            'component_id' => $this->componentId->toString(),
            'method' => $this->method,
            'params' => $this->params->toArray(),
        ];
    }
}
