<?php

declare(strict_types=1);

namespace App\Application\LiveComponents\TodoList;

use App\Framework\LiveComponents\Attributes\Action;
use App\Framework\LiveComponents\Attributes\LiveComponent;
use App\Framework\LiveComponents\Contracts\LiveComponentContract;
use App\Framework\LiveComponents\NestedComponentEventDispatcher;
use App\Framework\LiveComponents\ValueObjects\ComponentId;
use App\Framework\LiveComponents\ValueObjects\ComponentRenderData;

/**
 * TodoItemComponent - Child component for individual todo items
 *
 * Demonstrates child component pattern:
 * - Manages own display state (editing mode)
 * - Dispatches events to parent for state changes
 * - Event bubbling for parent-child communication
 * - Minimal local state, parent owns the data
 */
#[LiveComponent('todo-item')]
final readonly class TodoItemComponent implements LiveComponentContract
{
    public function __construct(
        public ComponentId $id,
        public TodoItemState $state,
        private readonly NestedComponentEventDispatcher $eventDispatcher
    ) {
    }

    public function getRenderData(): ComponentRenderData
    {
        return new ComponentRenderData(
            templatePath: 'todo-item',
            data: [
                'id' => $this->state->id,
                'title' => $this->state->title,
                'completed' => $this->state->completed,
                'is_editing' => $this->state->isEditing,
                'created_at' => $this->state->createdAt,
                'formatted_date' => date('Y-m-d H:i', $this->state->createdAt),
            ]
        );
    }

    // Action Methods

    /**
     * Toggle todo completed status
     * Dispatches event to parent for state synchronization
     */
    #[Action]
    public function toggle(): TodoItemState
    {
        $newState = $this->state->withToggled();

        // Dispatch event to parent
        $this->eventDispatcher->dispatch(
            componentId: $this->id,
            eventName: 'todo-completed',
            payload: [
                'todo_id' => $this->state->id,
                'completed' => $newState->completed,
            ]
        );

        return $newState;
    }

    /**
     * Delete todo
     * Dispatches event to parent which owns the list
     */
    #[Action]
    public function delete(): TodoItemState
    {
        // Dispatch delete event to parent
        $this->eventDispatcher->dispatch(
            componentId: $this->id,
            eventName: 'todo-deleted',
            payload: [
                'todo_id' => $this->state->id,
            ]
        );

        // Return current state (parent will remove this component)
        return $this->state;
    }

    /**
     * Enter edit mode
     */
    #[Action]
    public function startEdit(): TodoItemState
    {
        return $this->state->withEditing(true);
    }

    /**
     * Save edited title
     * Dispatches event to parent for persistence
     */
    #[Action]
    public function saveEdit(string $newTitle): TodoItemState
    {
        // Validate title
        $trimmedTitle = trim($newTitle);

        if (empty($trimmedTitle)) {
            // If empty, cancel edit without changes
            return $this->state->withEditing(false);
        }

        // Update local state
        $newState = $this->state
            ->withTitle($trimmedTitle)
            ->withEditing(false);

        // Dispatch event to parent for persistence
        $this->eventDispatcher->dispatch(
            componentId: $this->id,
            eventName: 'todo-title-changed',
            payload: [
                'todo_id' => $this->state->id,
                'title' => $trimmedTitle,
            ]
        );

        return $newState;
    }

    /**
     * Cancel edit without saving
     */
    #[Action]
    public function cancelEdit(): TodoItemState
    {
        return $this->state->withEditing(false);
    }
}
