<?php

declare(strict_types=1);

namespace App\Framework\Notification\Channels\Telegram\ValueObjects;

/**
 * Telegram Inline Keyboard Button Value Object
 *
 * Represents a single button in an inline keyboard
 */
final readonly class InlineKeyboardButton
{
    /**
     * @param string $text Button label (visible text)
     * @param string|null $url HTTP(S) URL to open (mutually exclusive with callbackData)
     * @param string|null $callbackData Data to send in callback query (mutually exclusive with url)
     */
    public function __construct(
        public string $text,
        public ?string $url = null,
        public ?string $callbackData = null
    ) {
        if (empty($text)) {
            throw new \InvalidArgumentException('Button text cannot be empty');
        }

        if ($url === null && $callbackData === null) {
            throw new \InvalidArgumentException('Button must have either url or callbackData');
        }

        if ($url !== null && $callbackData !== null) {
            throw new \InvalidArgumentException('Button cannot have both url and callbackData');
        }

        if ($callbackData !== null && strlen($callbackData) > 64) {
            throw new \InvalidArgumentException('Callback data cannot exceed 64 bytes');
        }
    }

    /**
     * Create button with URL
     */
    public static function withUrl(string $text, string $url): self
    {
        return new self(text: $text, url: $url);
    }

    /**
     * Create button with callback data
     */
    public static function withCallback(string $text, string $callbackData): self
    {
        return new self(text: $text, callbackData: $callbackData);
    }

    /**
     * Convert to Telegram API format
     */
    public function toArray(): array
    {
        $button = ['text' => $this->text];

        if ($this->url !== null) {
            $button['url'] = $this->url;
        }

        if ($this->callbackData !== null) {
            $button['callback_data'] = $this->callbackData;
        }

        return $button;
    }

    public function isUrlButton(): bool
    {
        return $this->url !== null;
    }

    public function isCallbackButton(): bool
    {
        return $this->callbackData !== null;
    }
}
