using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
using Microsoft.Extensions.Configuration;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;

namespace YouTubeAPIClient
{
    public class YouTubeDataService
    {
        private readonly string _apiKey;
        private readonly YouTubeService _youtubeService;

        public YouTubeDataService(string apiKey)
        {
            _apiKey = apiKey;
            _youtubeService = new YouTubeService(new BaseClientService.Initializer()
            {
                ApiKey = apiKey,
                ApplicationName = "YouTubeAPIClient"
            });
        }

        public static bool IsValidYouTubeUrl(string urlx)
        {
            return Regex.IsMatch(urlx, @"^(https?\:\/\/)?(www\.)?(youtube\.com|youtu\.?be)\/.+$");
        }

        public static async Task<YtDlpInfo> GetVideoInfo(string url, string workingDir)
        {
            string videoId = ExtractVideoId(url);
            if (string.IsNullOrEmpty(videoId))
            {
                throw new ArgumentException("URL inválida ou não foi possível extrair o ID do vídeo");
            }

            var youtubeService = new YouTubeService(new BaseClientService.Initializer
            {
                ApiKey = Environment.GetEnvironmentVariable("YOUTUBE_API_KEY"),
                ApplicationName = "YouTubeAPIClient"
            });

            var videoRequest = youtubeService.Videos.List("snippet");
            videoRequest.Id = videoId;

            var response = await videoRequest.ExecuteAsync();

            if (response.Items.Count == 0)
                throw new Exception("Vídeo não encontrado");

            var video = response.Items[0];
            var thumbnailUrl = video.Snippet.Thumbnails.High?.Url ??
                              video.Snippet.Thumbnails.Medium?.Url ??
                              video.Snippet.Thumbnails.Default__?.Url ?? "";

            return new YtDlpInfo(
                video.Snippet.Title,
                thumbnailUrl
            );
        }

        public static async Task<string> GetSubtitles(string url, string language, string workingDir)
        {
            string videoId = ExtractVideoId(url);
            if (string.IsNullOrEmpty(videoId))
            {
                throw new ArgumentException("URL inválida ou não foi possível extrair o ID do vídeo");
            }

            var youtubeService = new YouTubeService(new BaseClientService.Initializer
            {
                ApiKey = Environment.GetEnvironmentVariable("YOUTUBE_API_KEY"),
                ApplicationName = "YouTubeAPIClient"
            });

            var captionRequest = youtubeService.Captions.List("snippet", videoId);
            var captionResponse = await captionRequest.ExecuteAsync();

            var caption = captionResponse.Items.FirstOrDefault(c =>
                c.Snippet.Language.ToLower() == language.ToLower() ||
                (c.Snippet.Language.ToLower().StartsWith(language.ToLower()) && c.Snippet.TrackKind == "asr"));

            if (caption == null)
                throw new Exception($"Nenhuma legenda encontrada para o idioma {language}");

            var captionDownloadRequest = youtubeService.Captions.Download(caption.Id);
            captionDownloadRequest.Tfmt = "vtt"; // Fix: Use string "vtt" instead of non-existent TfmtEnum

            var captionStream = await captionDownloadRequest.ExecuteAsStreamAsync();

            string vttFilePath = Path.Combine(workingDir, $"{videoId}_{language}.vtt");
            using (var fileStream = new FileStream(vttFilePath, FileMode.Create, FileAccess.Write))
            {
                await captionStream.CopyToAsync(fileStream);
            }

            return await File.ReadAllTextAsync(vttFilePath);
        }

        private static string ExtractVideoId(string url)
        {
            var youtubeIdRegex = new Regex(@"(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^""&?\/\s]{11})");
            var match = youtubeIdRegex.Match(url);

            return match.Success ? match.Groups[1].Value : null;
        }
    }

    // Classe com a mesma assinatura da original
    public record YtDlpInfo(string Title, string ThumbnailUrl);
}