<?php

declare(strict_types=1);

use App\Framework\LiveComponents\Contracts\LifecycleAware;
use App\Framework\LiveComponents\Contracts\LiveComponentContract;
use App\Framework\LiveComponents\LiveComponentHandler;
use App\Framework\LiveComponents\ValueObjects\ActionParameters;
use App\Framework\LiveComponents\ValueObjects\ComponentData;
use App\Framework\LiveComponents\ValueObjects\ComponentId;
use App\Framework\LiveComponents\ValueObjects\RenderData;
use Tests\Framework\LiveComponents\ComponentTestCase;

uses(ComponentTestCase::class);

beforeEach(function () {
    $this->setUpComponentTest();
});

it('onUpdate() is called after action execution', function () {
    // Track if onUpdate was called
    $GLOBALS['test_update_called'] = false;

    // Create component that implements LifecycleAware
    $component = new class (ComponentId::fromString('test:update')) implements LiveComponentContract, LifecycleAware {
        public function __construct(
            private ComponentId $id
        ) {
        }

        public function getId(): ComponentId
        {
            return $this->id;
        }

        public function getData(): ComponentData
        {
            return ComponentData::fromArray(['count' => 0]);
        }

        public function getRenderData(): RenderData
        {
            return new RenderData('test', ['count' => 0]);
        }

        public function increment(): ComponentData
        {
            return ComponentData::fromArray(['count' => 1]);
        }

        public function onMount(): void
        {
        }

        public function onUpdate(): void
        {
            $GLOBALS['test_update_called'] = true;
        }

        public function onDestroy(): void
        {
        }
    };

    // Execute action
    $handler = $this->container->get(LiveComponentHandler::class);
    $params = ActionParameters::fromArray(['_csrf_token' => $this->generateCsrfToken($component)]);

    $result = $handler->handle($component, 'increment', $params);

    // Verify onUpdate was called
    expect($GLOBALS['test_update_called'])->toBeTrue();
    expect($result->state->data['count'])->toBe(1);

    unset($GLOBALS['test_update_called']);
});

it('works with Timer component', function () {
    $timer = new \App\Application\LiveComponents\Timer\TimerComponent(
        id: ComponentId::fromString('timer:test')
    );

    expect($timer)->toBeInstanceOf(LifecycleAware::class);
    expect($timer)->toBeInstanceOf(LiveComponentContract::class);

    $data = $timer->getData();
    expect($data->toArray())->toHaveKeys(['seconds', 'isRunning', 'startedAt', 'logs']);
});
