<?php

declare(strict_types=1);

namespace App\Framework\EventSourcing\Projections\Examples;

use App\Framework\Database\ConnectionInterface;
use App\Framework\EventSourcing\AggregateEnvelope;
use App\Framework\EventSourcing\Projections\ProjectionInterface;
use App\Framework\EventSourcing\Projections\ProjectionState;

/**
 * User List Projection Example
 *
 * Builds a denormalized user list read model from user events
 * for fast query performance
 */
final class UserListProjection implements ProjectionInterface
{
    private ProjectionState $state;

    public function __construct(
        private readonly ConnectionInterface $connection
    ) {
        $this->state = ProjectionState::initial('user_list');
    }

    public function getName(): string
    {
        return 'user_list';
    }

    public function subscribedTo(): array
    {
        return [
            // Subscribe to user-related events
            // 'App\\Domain\\User\\Events\\UserCreated',
            // 'App\\Domain\\User\\Events\\UserUpdated',
            // 'App\\Domain\\User\\Events\\UserDeleted',
        ];
    }

    public function project(AggregateEnvelope $envelope): void
    {
        $event = $envelope->event;
        $eventClass = get_class($event);

        match ($eventClass) {
            // Handle UserCreated event
            // 'App\\Domain\\User\\Events\\UserCreated' => $this->handleUserCreated($event, $envelope),

            // Handle UserUpdated event
            // 'App\\Domain\\User\\Events\\UserUpdated' => $this->handleUserUpdated($event, $envelope),

            // Handle UserDeleted event
            // 'App\\Domain\\User\\Events\\UserDeleted' => $this->handleUserDeleted($event, $envelope),

            default => null // Ignore unknown events
        };
    }

    public function reset(): void
    {
        // Delete read model table
        $this->connection->exec('DELETE FROM user_list_projection');

        // Reset state
        $this->state = ProjectionState::initial($this->getName());
    }

    public function getState(): ProjectionState
    {
        return $this->state;
    }

    /**
     * Example event handlers
     */

    // private function handleUserCreated($event, AggregateEnvelope $envelope): void
    // {
    //     $this->connection->insert('user_list_projection', [
    //         'user_id' => $event->userId->value,
    //         'email' => $event->email->value,
    //         'name' => $event->name,
    //         'created_at' => $envelope->recordedAt->format('Y-m-d H:i:s'),
    //         'event_version' => $envelope->version
    //     ]);
    // }

    // private function handleUserUpdated($event, AggregateEnvelope $envelope): void
    // {
    //     $this->connection->update('user_list_projection', [
    //         'email' => $event->email->value,
    //         'name' => $event->name,
    //         'updated_at' => $envelope->recordedAt->format('Y-m-d H:i:s'),
    //         'event_version' => $envelope->version
    //     ], ['user_id' => $event->userId->value]);
    // }

    // private function handleUserDeleted($event, AggregateEnvelope $envelope): void
    // {
    //     $this->connection->delete('user_list_projection', [
    //         'user_id' => $event->userId->value
    //     ]);
    // }
}
