<?php
/**
 * ===========================================
 * FLOWBOT DCI - EMBED CODE GENERATOR v2.2
 * ===========================================
 * Generates embed codes for various video and social media platforms
 *
 * v2.2 Changes:
 * - Added Twitter/X embed support
 * - Added Instagram embed support
 * - Added Telegram embed support
 * - Improved embed detection
 */

declare(strict_types=1);

namespace FlowbotDCI\Services;

class EmbedGenerator
{
    private int $defaultWidth = 560;
    private int $defaultHeight = 315;

    /**
     * Generate embed code for URL
     * v2.2: Added Twitter, Instagram, Telegram support
     */
    public function generate(string $url): string
    {
        $host = parse_url($url, PHP_URL_HOST);
        $host = preg_replace('/^www\./', '', $host);

        switch ($host) {
            case 'youtube.com':
            case 'youtu.be':
                return $this->youtubeEmbed($url);

            case 'vimeo.com':
                return $this->vimeoEmbed($url);

            case 'tiktok.com':
            case 'vm.tiktok.com':
                return $this->tiktokEmbed($url);

            case 'dailymotion.com':
                return $this->dailymotionEmbed($url);

            case 'twitch.tv':
                return $this->twitchEmbed($url);

            case 'facebook.com':
            case 'fb.watch':
            case 'fb.com':
                return $this->facebookEmbed($url);

            // v2.2: New social media embeds
            case 'twitter.com':
            case 'x.com':
                return $this->twitterEmbed($url);

            case 'instagram.com':
                return $this->instagramEmbed($url);

            case 't.me':
            case 'telegram.org':
                return $this->telegramEmbed($url);

            default:
                return $this->genericEmbed($url);
        }
    }

    /**
     * YouTube embed
     */
    private function youtubeEmbed(string $url): string
    {
        $videoId = $this->getYoutubeVideoId($url);

        if (!$videoId) {
            return $this->genericEmbed($url);
        }

        return $this->buildIframe(
            "https://www.youtube.com/embed/$videoId",
            ['allow' => 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture']
        );
    }

    /**
     * Vimeo embed
     */
    private function vimeoEmbed(string $url): string
    {
        $videoId = $this->getVimeoVideoId($url);

        if (!$videoId) {
            return $this->genericEmbed($url);
        }

        return $this->buildIframe(
            "https://player.vimeo.com/video/$videoId",
            ['allow' => 'autoplay; fullscreen; picture-in-picture']
        );
    }

    /**
     * TikTok embed
     */
    private function tiktokEmbed(string $url): string
    {
        $videoId = $this->getTiktokVideoId($url);

        if (!$videoId) {
            return $this->genericEmbed($url);
        }

        return $this->buildIframe(
            "https://www.tiktok.com/embed/v2/$videoId",
            ['style' => 'width:325px; height:578px;']
        );
    }

    /**
     * Dailymotion embed
     */
    private function dailymotionEmbed(string $url): string
    {
        preg_match('/video\/([a-zA-Z0-9]+)/', $url, $matches);
        $videoId = $matches[1] ?? null;

        if (!$videoId) {
            return $this->genericEmbed($url);
        }

        return $this->buildIframe("https://www.dailymotion.com/embed/video/$videoId");
    }

    /**
     * Twitch embed
     */
    private function twitchEmbed(string $url): string
    {
        $path = parse_url($url, PHP_URL_PATH);
        $channel = trim($path, '/');

        if (empty($channel)) {
            return $this->genericEmbed($url);
        }

        return $this->buildIframe(
            "https://player.twitch.tv/?channel=$channel&parent=" . ($_SERVER['HTTP_HOST'] ?? 'localhost')
        );
    }

    /**
     * Facebook embed
     */
    private function facebookEmbed(string $url): string
    {
        $encodedUrl = urlencode($url);
        return $this->buildIframe(
            "https://www.facebook.com/plugins/video.php?href=$encodedUrl&show_text=false",
            ['style' => 'border:none;overflow:hidden', 'scrolling' => 'no']
        );
    }

    /**
     * v2.2: Twitter/X embed
     * Uses Twitter's official oEmbed widget
     */
    private function twitterEmbed(string $url): string
    {
        // Extract tweet ID from URL
        if (preg_match('#(?:twitter\.com|x\.com)/\w+/status/(\d+)#i', $url, $matches)) {
            $tweetId = $matches[1];

            // Twitter oEmbed - renders properly with JavaScript
            $escapedUrl = htmlspecialchars($url, ENT_QUOTES);
            return <<<HTML
<blockquote class="twitter-tweet" data-theme="dark">
    <a href="{$escapedUrl}">View Tweet</a>
</blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
HTML;
        }

        return $this->genericEmbed($url);
    }

    /**
     * v2.2: Instagram embed
     * Uses Instagram's official oEmbed widget
     */
    private function instagramEmbed(string $url): string
    {
        // Extract shortcode from URL
        if (preg_match('#instagram\.com/(?:p|reel|tv)/([A-Za-z0-9_-]+)#i', $url, $matches)) {
            $shortcode = $matches[1];
            $embedUrl = "https://www.instagram.com/p/{$shortcode}/embed/";

            // Instagram oEmbed - renders properly with JavaScript
            $escapedUrl = htmlspecialchars($url, ENT_QUOTES);
            return <<<HTML
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-permalink="{$escapedUrl}" data-instgrm-version="14" style="max-width:540px; min-width:326px; width:calc(100% - 2px);">
    <a href="{$escapedUrl}" target="_blank">View on Instagram</a>
</blockquote>
<script async src="https://www.instagram.com/embed.js"></script>
HTML;
        }

        return $this->genericEmbed($url);
    }

    /**
     * v2.2: Telegram embed
     * Uses Telegram's widget for public posts
     */
    private function telegramEmbed(string $url): string
    {
        // Extract channel and message ID from URL
        if (preg_match('#t\.me/([^/]+)/(\d+)#i', $url, $matches)) {
            $channel = $matches[1];
            $messageId = $matches[2];

            // Telegram official widget
            return <<<HTML
<script async src="https://telegram.org/js/telegram-widget.js?22" data-telegram-post="{$channel}/{$messageId}" data-width="100%"></script>
HTML;
        }

        // Channel link without message
        if (preg_match('#t\.me/([^/?]+)#i', $url, $matches)) {
            $channel = $matches[1];
            $escapedUrl = htmlspecialchars($url, ENT_QUOTES);

            return <<<HTML
<div class="telegram-channel-link">
    <a href="{$escapedUrl}" target="_blank" rel="noopener noreferrer">
        View Telegram Channel: @{$channel}
    </a>
</div>
HTML;
        }

        return $this->genericEmbed($url);
    }

    /**
     * v2.2: Check if URL is embeddable
     */
    public function isEmbeddable(string $url): bool
    {
        $host = parse_url($url, PHP_URL_HOST);
        $host = preg_replace('/^www\./', '', $host);

        $embeddableHosts = [
            'youtube.com', 'youtu.be', 'vimeo.com', 'tiktok.com', 'vm.tiktok.com',
            'dailymotion.com', 'twitch.tv', 'facebook.com', 'fb.watch', 'fb.com',
            'twitter.com', 'x.com', 'instagram.com', 't.me', 'telegram.org'
        ];

        return in_array($host, $embeddableHosts);
    }

    /**
     * v2.2: Get embed type for URL
     */
    public function getEmbedType(string $url): ?string
    {
        $host = parse_url($url, PHP_URL_HOST);
        $host = preg_replace('/^www\./', '', $host);

        $typeMap = [
            'youtube.com' => 'youtube',
            'youtu.be' => 'youtube',
            'vimeo.com' => 'vimeo',
            'tiktok.com' => 'tiktok',
            'vm.tiktok.com' => 'tiktok',
            'dailymotion.com' => 'dailymotion',
            'twitch.tv' => 'twitch',
            'facebook.com' => 'facebook',
            'fb.watch' => 'facebook',
            'fb.com' => 'facebook',
            'twitter.com' => 'twitter',
            'x.com' => 'twitter',
            'instagram.com' => 'instagram',
            't.me' => 'telegram',
            'telegram.org' => 'telegram',
        ];

        return $typeMap[$host] ?? null;
    }

    /**
     * Generic iframe embed
     */
    private function genericEmbed(string $url): string
    {
        return $this->buildIframe($url);
    }

    /**
     * Build iframe HTML
     */
    private function buildIframe(string $src, array $extraAttrs = []): string
    {
        $attrs = [
            'src'             => $src,
            'width'           => $this->defaultWidth,
            'height'          => $this->defaultHeight,
            'frameborder'     => '0',
            'allowfullscreen' => 'allowfullscreen',
        ];

        $attrs = array_merge($attrs, $extraAttrs);

        $attrString = '';
        foreach ($attrs as $key => $value) {
            if ($value === true) {
                $attrString .= " $key";
            } else {
                $attrString .= " $key=\"" . htmlspecialchars((string)$value, ENT_QUOTES) . "\"";
            }
        }

        return "<iframe$attrString></iframe>";
    }

    /**
     * Extract YouTube video ID
     */
    private function getYoutubeVideoId(string $url): ?string
    {
        // Standard watch URL
        parse_str(parse_url($url, PHP_URL_QUERY) ?? '', $params);
        if (!empty($params['v'])) {
            return $params['v'];
        }

        // Shortened URL (youtu.be)
        if (strpos($url, 'youtu.be') !== false) {
            $path = parse_url($url, PHP_URL_PATH);
            return trim($path, '/');
        }

        // Embed URL
        if (preg_match('/embed\/([a-zA-Z0-9_-]+)/', $url, $matches)) {
            return $matches[1];
        }

        // Shorts URL
        if (preg_match('/shorts\/([a-zA-Z0-9_-]+)/', $url, $matches)) {
            return $matches[1];
        }

        return null;
    }

    /**
     * Extract Vimeo video ID
     */
    private function getVimeoVideoId(string $url): ?string
    {
        $path = parse_url($url, PHP_URL_PATH);
        $parts = explode('/', trim($path, '/'));

        foreach ($parts as $part) {
            if (is_numeric($part)) {
                return $part;
            }
        }

        return null;
    }

    /**
     * Extract TikTok video ID
     */
    private function getTiktokVideoId(string $url): ?string
    {
        if (preg_match('/video\/(\d+)/', $url, $matches)) {
            return $matches[1];
        }

        // Short URL format
        $path = parse_url($url, PHP_URL_PATH);
        $id = trim($path, '/');

        return !empty($id) ? $id : null;
    }

    /**
     * Set default dimensions
     */
    public function setDimensions(int $width, int $height): self
    {
        $this->defaultWidth = $width;
        $this->defaultHeight = $height;
        return $this;
    }
}
