<?php

declare(strict_types=1);

use App\Application\Components\CounterComponent;
use App\Application\Components\StatsComponent;

beforeEach(function () {
    // Skip for now - these are template tests
    // Full integration testing würde das gesamte Framework bootstrappen erfordern
    $this->markTestSkipped('LiveComponents integration testing requires full framework bootstrap');
});

describe('LiveComponents Integration', function () {
    it('renders counter component', function () {
        $component = new CounterComponent(
            id: 'counter:test',
            initialData: ['count' => 0]
        );

        $html = $this->registry->render($component);

        expect($html)->toContain('Count: 0');
        expect($html)->not->toBeEmpty();
    });

    it('handles counter increment action', function () {
        $result = $this->handler->handleAction(
            componentId: 'counter:test',
            action: 'increment',
            params: [],
            currentState: ['count' => 5]
        );

        expect($result->state)->toBe(['count' => 6]);
        expect($result->html)->toContain('Count: 6');
        expect($result->success)->toBeTrue();
    });

    it('handles counter decrement action', function () {
        $result = $this->handler->handleAction(
            componentId: 'counter:test',
            action: 'decrement',
            params: [],
            currentState: ['count' => 10]
        );

        expect($result->state)->toBe(['count' => 9]);
        expect($result->html)->toContain('Count: 9');
    });

    it('renders component with wrapper', function () {
        $component = new CounterComponent(
            id: 'counter:wrapper-test',
            initialData: ['count' => 42]
        );

        $html = $this->registry->renderWithWrapper($component);

        expect($html)->toContain('data-live-component="counter:wrapper-test"');
        expect($html)->toContain('data-component-state');
        expect($html)->toContain('Count: 42');
    });

    it('dispatches component events', function () {
        $result = $this->handler->handleAction(
            componentId: 'counter:events-test',
            action: 'increment',
            params: [],
            currentState: ['count' => 0]
        );

        expect($result->events)->toHaveCount(1);
        expect($result->events[0]->name)->toBe('counter:incremented');
        expect($result->events[0]->data)->toBe(['count' => 1]);
    });
});

describe('LiveComponents Caching', function () {
    it('caches stats component output', function () {
        $component = new StatsComponent(
            id: 'stats:cache-test',
            initialData: ['cache_enabled' => true]
        );

        // First render - should be slow (500ms delay)
        $start = microtime(true);
        $html1 = $this->registry->render($component);
        $time1 = (microtime(true) - $start) * 1000;

        expect($html1)->toContain('Total Users');
        expect($time1)->toBeGreaterThan(400); // Should take ~500ms

        // Second render - should be fast (cached)
        $start = microtime(true);
        $html2 = $this->registry->render($component);
        $time2 = (microtime(true) - $start) * 1000;

        expect($html2)->toBe($html1); // Same HTML
        expect($time2)->toBeLessThan(50); // Should be <50ms from cache
    });

    it('respects shouldCache flag', function () {
        $component = new StatsComponent(
            id: 'stats:no-cache',
            initialData: ['cache_enabled' => false]
        );

        // Both renders should be slow (no caching)
        $start = microtime(true);
        $html1 = $this->registry->render($component);
        $time1 = (microtime(true) - $start) * 1000;

        $start = microtime(true);
        $html2 = $this->registry->render($component);
        $time2 = (microtime(true) - $start) * 1000;

        expect($time1)->toBeGreaterThan(400);
        expect($time2)->toBeGreaterThan(400); // No cache benefit
    });

    it('invalidates component cache', function () {
        $component = new StatsComponent(
            id: 'stats:invalidate-test',
            initialData: ['cache_enabled' => true]
        );

        // Render and cache
        $html1 = $this->registry->render($component);

        // Invalidate
        $result = $this->registry->invalidateCache($component);
        expect($result)->toBeTrue();

        // Next render should be slow again
        $start = microtime(true);
        $html2 = $this->registry->render($component);
        $time = (microtime(true) - $start) * 1000;

        expect($time)->toBeGreaterThan(400); // Cache was invalidated
    });

    it('invalidates cache by tag', function () {
        $component1 = new StatsComponent(
            id: 'stats:tag1',
            initialData: ['cache_enabled' => true]
        );

        $component2 = new StatsComponent(
            id: 'stats:tag2',
            initialData: ['cache_enabled' => true]
        );

        // Cache both components
        $this->registry->render($component1);
        $this->registry->render($component2);

        // Invalidate all stats components by tag
        $result = $this->registry->invalidateCacheByTag('stats');
        expect($result)->toBeTrue();

        // Both should render slowly now
        $start = microtime(true);
        $this->registry->render($component1);
        $time1 = (microtime(true) - $start) * 1000;

        $start = microtime(true);
        $this->registry->render($component2);
        $time2 = (microtime(true) - $start) * 1000;

        expect($time1)->toBeGreaterThan(400);
        expect($time2)->toBeGreaterThan(400);
    });
});
