<?php

namespace App\Support;

class ProjectTutorialVideo
{
    public static function normalizeLink(string $link): string
    {
        $link = trim($link);
        if ($link === '' || $link === '#') {
            return '';
        }

        if (str_starts_with(strtolower($link), 'javascript:')) {
            return '';
        }

        if (preg_match('~^(?:https?:)?//~i', $link)) {
            return $link;
        }

        if (preg_match('~^(?:mailto|tel):~i', $link)) {
            return $link;
        }

        if (str_starts_with($link, '/')) {
            return $link;
        }

        if (preg_match('~^[a-z][a-z0-9+.-]*:~i', $link)) {
            return $link;
        }

        return 'https://' . ltrim($link, '/');
    }

    /**
     * @return array{type:string, src:string, link:string}
     */
    public static function playerForLink(string $link): array
    {
        $normalizedLink = static::normalizeLink($link);
        if ($normalizedLink === '') {
            return ['type' => '', 'src' => '', 'link' => ''];
        }

        $youtubeId = static::extractYoutubeId($normalizedLink);
        if ($youtubeId !== '') {
            return [
                'type' => 'iframe',
                'src' => 'https://www.youtube.com/embed/' . $youtubeId . '?rel=0',
                'link' => $normalizedLink,
            ];
        }

        $vimeoId = static::extractVimeoId($normalizedLink);
        if ($vimeoId !== '') {
            return [
                'type' => 'iframe',
                'src' => 'https://player.vimeo.com/video/' . $vimeoId,
                'link' => $normalizedLink,
            ];
        }

        $driveFileId = static::extractGoogleDriveFileId($normalizedLink);
        if ($driveFileId !== '') {
            return [
                'type' => 'iframe',
                'src' => 'https://drive.google.com/file/d/' . $driveFileId . '/preview',
                'link' => $normalizedLink,
            ];
        }

        if (static::isDirectVideoFile($normalizedLink)) {
            return [
                'type' => 'video',
                'src' => $normalizedLink,
                'link' => $normalizedLink,
            ];
        }

        return [
            'type' => 'iframe',
            'src' => $normalizedLink,
            'link' => $normalizedLink,
        ];
    }

    public static function thumbnailForLink(string $link): string
    {
        $normalizedLink = static::normalizeLink($link);
        if ($normalizedLink === '') {
            return '';
        }

        $youtubeId = static::extractYoutubeId($normalizedLink);
        if ($youtubeId !== '') {
            return 'https://img.youtube.com/vi/' . $youtubeId . '/hqdefault.jpg';
        }

        $vimeoId = static::extractVimeoId($normalizedLink);
        if ($vimeoId !== '') {
            return 'https://vumbnail.com/' . $vimeoId . '.jpg';
        }

        $driveFileId = static::extractGoogleDriveFileId($normalizedLink);
        if ($driveFileId !== '') {
            return 'https://drive.google.com/thumbnail?id=' . $driveFileId;
        }

        return '';
    }

    private static function extractYoutubeId(string $url): string
    {
        $parts = @parse_url($url);
        if (!is_array($parts)) {
            return '';
        }

        $host = strtolower((string) ($parts['host'] ?? ''));
        $path = trim((string) ($parts['path'] ?? ''), '/');
        $query = (string) ($parts['query'] ?? '');

        if ($host === '') {
            return '';
        }

        if (str_contains($host, 'youtu.be')) {
            $segments = array_values(array_filter(explode('/', $path)));
            return static::sanitizeYoutubeId($segments[0] ?? '');
        }

        if (!str_contains($host, 'youtube.com') && !str_contains($host, 'youtube-nocookie.com')) {
            return '';
        }

        $segments = array_values(array_filter(explode('/', $path)));
        if (($segments[0] ?? '') === 'watch') {
            parse_str($query, $qs);
            return static::sanitizeYoutubeId((string) ($qs['v'] ?? ''));
        }

        if (($segments[0] ?? '') === 'embed' || ($segments[0] ?? '') === 'shorts' || ($segments[0] ?? '') === 'live' || ($segments[0] ?? '') === 'v') {
            return static::sanitizeYoutubeId($segments[1] ?? '');
        }

        parse_str($query, $qs);
        return static::sanitizeYoutubeId((string) ($qs['v'] ?? ''));
    }

    private static function extractVimeoId(string $url): string
    {
        $parts = @parse_url($url);
        if (!is_array($parts)) {
            return '';
        }

        $host = strtolower((string) ($parts['host'] ?? ''));
        $path = trim((string) ($parts['path'] ?? ''), '/');

        if ($host === '' || !str_contains($host, 'vimeo.com')) {
            return '';
        }

        $segments = array_values(array_filter(explode('/', $path)));
        if (count($segments) === 0) {
            return '';
        }

        if (($segments[0] ?? '') === 'video') {
            $candidate = $segments[1] ?? '';
        } else {
            $candidate = end($segments);
        }

        $candidate = preg_replace('/[^0-9]/', '', (string) $candidate);
        return $candidate ?: '';
    }

    private static function sanitizeYoutubeId(string $candidate): string
    {
        $candidate = trim($candidate);
        if ($candidate === '') {
            return '';
        }

        if (!preg_match('/^[A-Za-z0-9_-]{6,20}$/', $candidate)) {
            return '';
        }

        return $candidate;
    }

    private static function extractGoogleDriveFileId(string $url): string
    {
        $parts = @parse_url($url);
        if (!is_array($parts)) {
            return '';
        }

        $host = strtolower((string) ($parts['host'] ?? ''));
        $path = trim((string) ($parts['path'] ?? ''), '/');
        $query = (string) ($parts['query'] ?? '');

        if ($host === '' || (!str_contains($host, 'drive.google.com') && !str_contains($host, 'docs.google.com'))) {
            return '';
        }

        parse_str($query, $qs);
        $fromQuery = static::sanitizeDriveFileId((string) ($qs['id'] ?? ''));
        if ($fromQuery !== '') {
            return $fromQuery;
        }

        $segments = array_values(array_filter(explode('/', $path)));
        foreach ($segments as $idx => $segment) {
            if ($segment === 'd' || ($segment === 'file' && (($segments[$idx + 1] ?? '') === 'd'))) {
                $candidate = $segment === 'd' ? ($segments[$idx + 1] ?? '') : ($segments[$idx + 2] ?? '');
                $id = static::sanitizeDriveFileId((string) $candidate);
                if ($id !== '') {
                    return $id;
                }
            }
        }

        return '';
    }

    private static function sanitizeDriveFileId(string $candidate): string
    {
        $candidate = trim($candidate);
        if ($candidate === '') {
            return '';
        }

        if (!preg_match('/^[A-Za-z0-9_-]{10,}$/', $candidate)) {
            return '';
        }

        return $candidate;
    }

    private static function isDirectVideoFile(string $url): bool
    {
        $path = (string) parse_url($url, PHP_URL_PATH);
        if ($path === '') {
            return false;
        }

        return (bool) preg_match('~\.(mp4|m4v|webm|ogg|ogv|mov)$~i', $path);
    }
}
