<?php

declare(strict_types=1);

namespace App\Application\LiveComponents\Modal;

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

/**
 * ModalComponent - Dynamic modal dialog with configurable content
 *
 * Demonstrates:
 * - Type-safe state management with ModalState Value Object
 * - Multiple modal sizes (small, medium, large, fullscreen)
 * - Customizable header, body, footer with buttons
 * - Close behavior configuration (backdrop, ESC key)
 * - Animation transitions (fade, slide, zoom)
 * - Specialized modal types (confirm, alert)
 * - Compile-time type safety for data access
 */
#[LiveComponent('modal')]
final readonly class ModalComponent implements LiveComponentContract
{
    public ComponentId $id;

    public ModalState $state;

    public function __construct(
        ComponentId $id,
        ?ComponentData $initialData = null,
        bool $isOpen = false,
        string $title = '',
        string $content = '',
        string $size = 'medium',
        array $buttons = [],
        bool $showCloseButton = true,
        bool $closeOnBackdrop = true,
        bool $closeOnEscape = true,
        string $animation = 'fade',
        int $zIndex = 1000,
        ?string $modalType = null
    ) {
        $this->id = $id;

        // If initialData is provided (from state update), use it
        if ($initialData !== null) {
            $this->state = ModalState::fromComponentData($initialData);

            return;
        }

        // Otherwise, initialize with provided parameters
        $this->state = new ModalState(
            isOpen: $isOpen,
            title: $title,
            content: $content,
            size: $size,
            buttons: $buttons,
            showCloseButton: $showCloseButton,
            closeOnBackdrop: $closeOnBackdrop,
            closeOnEscape: $closeOnEscape,
            animation: $animation,
            zIndex: $zIndex,
            modalType: $modalType
        );
    }
    public function getRenderData(): ComponentRenderData
    {
        return new ComponentRenderData(
            templatePath: 'livecomponent-modal',
            data: [
                // LiveComponent integration
                'componentId' => $this->id->toString(),
                'stateJson' => json_encode($this->state->toArray()),

                // Raw data
                'is_open' => $this->state->isOpen,
                'title' => $this->state->title,
                'content' => $this->state->content,
                'size' => $this->state->size,
                'buttons' => $this->state->buttons,
                'show_close_button' => $this->state->showCloseButton,
                'close_on_backdrop' => $this->state->closeOnBackdrop,
                'close_on_escape' => $this->state->closeOnEscape,
                'animation' => $this->state->animation,
                'z_index' => $this->state->zIndex,
                'modal_type' => $this->state->modalType,

                // Display-specific properties
                'is_confirmation' => $this->state->isConfirmation(),
                'is_alert' => $this->state->isAlert(),
                'has_buttons' => $this->state->hasButtons(),
                'size_class' => $this->state->getSizeClass(),
                'animation_class' => $this->state->getAnimationClass(),
                'backdrop_class' => $this->state->isOpen ? 'modal-backdrop show' : 'modal-backdrop',
                'modal_class' => $this->state->isOpen ? 'modal show d-block' : 'modal',
                'dialog_class' => 'modal-dialog ' . $this->state->getSizeClass(),
            ]
        );
    }

    // Action methods

    public function open(
        string $title,
        string $content,
        string $size = 'medium',
        string|array $buttons = []
    ): ModalState {
        // Parse buttons from JSON string if needed
        if (is_string($buttons) && ! empty($buttons)) {
            $parsedButtons = json_decode($buttons, true);
            $buttons = is_array($parsedButtons) ? $parsedButtons : [];
        }

        $newState = $this->state->withOpen($title, $content, $size, $buttons);

        return $newState;
    }

    public function close(): ModalState
    {
        return $this->state->withClosed();
    }

    public function updateContent(string $content): ModalState
    {
        return $this->state->withUpdatedContent($content);
    }

    public function changeSize(string $size): ModalState
    {
        return $this->state->withSize($size);
    }

    public function confirm(string $title, string $message): ModalState
    {
        return ModalState::forConfirmation(
            $title,
            $message,
            $this->state->closeOnBackdrop,
            $this->state->closeOnEscape,
            $this->state->animation,
            $this->state->zIndex
        );
    }

    public function alert(string $title, string $message, string $type = 'info'): ModalState
    {
        return ModalState::forAlert(
            $title,
            $message,
            $type,
            $this->state->animation,
            $this->state->zIndex
        );
    }
}
