<?php

declare(strict_types=1);

namespace App\Application\LiveComponents;

use App\Framework\LiveComponents\Contracts\LiveComponent;
use App\Framework\LiveComponents\Contracts\SupportsSlots;
use App\Framework\LiveComponents\ValueObjects\ComponentId;
use App\Framework\LiveComponents\ValueObjects\ComponentState;
use App\Framework\LiveComponents\ValueObjects\SlotContent;
use App\Framework\LiveComponents\ValueObjects\SlotContext;
use App\Framework\LiveComponents\ValueObjects\SlotDefinition;

/**
 * Modal Component with Scoped Slots
 *
 * Demonstrates scoped slots where the modal provides context data
 * to the parent (e.g., close function, modal ID).
 *
 * Example Usage:
 * ```html
 * <live-component name="modal" id="confirm-modal">
 *     <slot name="title">
 *         Confirm Action
 *     </slot>
 *
 *     <slot name="content" scope="modal">
 *         Are you sure you want to proceed?
 *         <p>Modal ID: {context.modalId}</p>
 *     </slot>
 *
 *     <slot name="actions" scope="modal">
 *         <button onclick="{context.closeFunction}">Cancel</button>
 *         <button>Confirm</button>
 *     </slot>
 * </live-component>
 * ```
 */
final readonly class ModalComponent implements LiveComponent, SupportsSlots
{
    public function __construct(
        public ComponentId $id,
        public ComponentState $state
    ) {
    }

    public function getSlotDefinitions(): array
    {
        return [
            // Title slot - simple named slot
            SlotDefinition::named(
                name: 'title',
                defaultContent: '<h3>Modal Title</h3>'
            ),

            // Content slot - scoped slot with modal context
            SlotDefinition::scoped(
                name: 'content',
                props: ['modalId', 'isOpen', 'closeFunction'],
                defaultContent: '<p>Modal content goes here</p>'
            )->withRequired(true),

            // Actions slot - scoped slot with close function
            SlotDefinition::scoped(
                name: 'actions',
                props: ['closeFunction', 'modalId'],
                defaultContent: '<button onclick="{closeFunction}">Close</button>'
            ),
        ];
    }

    public function getSlotContext(string $slotName): SlotContext
    {
        $modalId = $this->id->toString();
        $isOpen = $this->state->get('isOpen', false);

        return match ($slotName) {
            'content', 'actions' => SlotContext::create([
                'modalId' => $modalId,
                'isOpen' => $isOpen,
                'closeFunction' => "closeModal('{$modalId}')",
            ]),
            default => SlotContext::empty()
        };
    }

    public function processSlotContent(SlotContent $content): SlotContent
    {
        // Apply modal-specific CSS classes
        $wrappedContent = match ($content->slotName) {
            'title' => '<div class="modal-title">' . $content->content . '</div>',
            'content' => '<div class="modal-content">' . $content->content . '</div>',
            'actions' => '<div class="modal-actions">' . $content->content . '</div>',
            default => $content->content
        };

        return $content->withContent($wrappedContent);
    }

    public function validateSlots(array $providedSlots): array
    {
        // No custom validation needed beyond required slots
        return [];
    }

    public function render(): string
    {
        return 'modal';
    }

    public function getComponentType(): string
    {
        return 'modal';
    }

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

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