using System.Net.Http.Json;
using System.Text.Json;
using Microsoft.Extensions.Logging;

namespace YTExtractor.Services.YouExpose
{
    /// <summary>
    /// Cliente para a API YouExpose - biblioteca para acessar dados do YouTube
    /// </summary>
    public class Client
    {
        private readonly ILogger<Client> _logger;
        private readonly HttpClient _httpClient;
        private readonly string _apiKey;
        private readonly JsonSerializerOptions _jsonOptions;

        /// <summary>
        /// Construtor do cliente YouExpose
        /// </summary>
        /// <param name="logger">Logger para registro de eventos</param>
        /// <param name="httpClient">Cliente HTTP opcional (útil para testes)</param>
        /// <param name="apiKey">Chave de API do YouExpose (opcional)</param>
        public Client(ILogger<Client> logger, HttpClient? httpClient = null, string? apiKey = null)
        {
            _logger = logger;
            _httpClient = httpClient ?? new HttpClient();
            _apiKey = apiKey ?? Environment.GetEnvironmentVariable("YOUEXPOSE_API_KEY") ?? "";
            
            // Configurar base URL se necessário
            if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("YOUEXPOSE_API_URL")))
            {
                _httpClient.BaseAddress = new Uri(Environment.GetEnvironmentVariable("YOUEXPOSE_API_URL"));
            }
            else
            {
                _httpClient.BaseAddress = new Uri("https://api.youexpose.com/");
            }

            _jsonOptions = new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                PropertyNameCaseInsensitive = true
            };
        }

        /// <summary>
        /// Obtém informações de um vídeo do YouTube
        /// </summary>
        /// <param name="url">URL do vídeo do YouTube</param>
        /// <returns>Informações básicas do vídeo</returns>
        public async Task<VideoInfo?> GetVideoInfoAsync(string url)
        {
            try
            {
                _logger.LogInformation("Obtendo informações do vídeo via YouExpose: {Url}", url);
                
                // Extrair ID do vídeo da URL
                var videoId = ExtractVideoId(url);
                if (string.IsNullOrEmpty(videoId))
                {
                    _logger.LogWarning("ID do vídeo não pôde ser extraído da URL: {Url}", url);
                    return null;
                }

                // Fazer requisição à API
                var response = await _httpClient.GetAsync($"api/videos/{videoId}?key={_apiKey}");
                
                if (!response.IsSuccessStatusCode)
                {
                    _logger.LogWarning("Falha ao obter informações do vídeo: {StatusCode}", response.StatusCode);
                    return null;
                }

                // Deserializar resposta
                var result = await response.Content.ReadFromJsonAsync<ApiResponse<VideoInfo>>(_jsonOptions);
                return result?.Data;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Erro ao obter informações do vídeo: {Url}", url);
                return null;
            }
        }

        /// <summary>
        /// Obtém legendas de um vídeo do YouTube
        /// </summary>
        /// <param name="url">URL do vídeo do YouTube</param>
        /// <param name="language">Código do idioma (ex: "pt", "en")</param>
        /// <returns>Conteúdo das legendas</returns>
        public async Task<string?> GetSubtitlesAsync(string url, string language)
        {
            try
            {
                _logger.LogInformation("Obtendo legendas via YouExpose: {Url}, Idioma: {Language}", url, language);
                
                // Extrair ID do vídeo da URL
                var videoId = ExtractVideoId(url);
                if (string.IsNullOrEmpty(videoId))
                {
                    _logger.LogWarning("ID do vídeo não pôde ser extraído da URL: {Url}", url);
                    return null;
                }

                // Fazer requisição à API
                var response = await _httpClient.GetAsync($"api/videos/{videoId}/subtitles?lang={language}&key={_apiKey}");
                
                if (!response.IsSuccessStatusCode)
                {
                    _logger.LogWarning("Falha ao obter legendas: {StatusCode}", response.StatusCode);
                    return null;
                }

                // Obter conteúdo das legendas
                var result = await response.Content.ReadFromJsonAsync<ApiResponse<SubtitleResponse>>(_jsonOptions);
                return result?.Data?.Content;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Erro ao obter legendas: {Url}, Idioma: {Language}", url, language);
                return null;
            }
        }

        /// <summary>
        /// Extrai o ID do vídeo de uma URL do YouTube
        /// </summary>
        /// <param name="url">URL do YouTube</param>
        /// <returns>ID do vídeo ou null se não encontrado</returns>
        private string? ExtractVideoId(string url)
        {
            try
            {
                // Verificar se é uma URL válida
                if (!Uri.TryCreate(url, UriKind.Absolute, out var uri))
                {
                    return null;
                }

                // Para URLs como: https://www.youtube.com/watch?v=VIDEO_ID
                if (uri.Host.Contains("youtube.com") && uri.AbsolutePath.Contains("watch"))
                {
                    var query = System.Web.HttpUtility.ParseQueryString(uri.Query);
                    return query["v"];
                }
                
                // Para URLs como: https://youtu.be/VIDEO_ID
                if (uri.Host.Contains("youtu.be"))
                {
                    return uri.AbsolutePath.TrimStart('/');
                }
                
                return null;
            }
            catch
            {
                return null;
            }
        }
    }

    /// <summary>
    /// Informações básicas de um vídeo
    /// </summary>
    public class VideoInfo
    {
        /// <summary>
        /// Título do vídeo
        /// </summary>
        public string Title { get; set; } = string.Empty;
        
        /// <summary>
        /// URL da miniatura do vídeo
        /// </summary>
        public string ThumbnailUrl { get; set; } = string.Empty;
        
        /// <summary>
        /// Duração do vídeo em segundos
        /// </summary>
        public int Duration { get; set; }
        
        /// <summary>
        /// Nome do canal
        /// </summary>
        public string ChannelName { get; set; } = string.Empty;
    }

    /// <summary>
    /// Resposta de legendas
    /// </summary>
    public class SubtitleResponse
    {
        /// <summary>
        /// Idioma das legendas
        /// </summary>
        public string Language { get; set; } = string.Empty;
        
        /// <summary>
        /// Conteúdo das legendas
        /// </summary>
        public string Content { get; set; } = string.Empty;
        
        /// <summary>
        /// Indica se são legendas geradas automaticamente
        /// </summary>
        public bool IsAutoGenerated { get; set; }
    }

    /// <summary>
    /// Estrutura genérica para resposta da API
    /// </summary>
    /// <typeparam name="T">Tipo de dados na resposta</typeparam>
    public class ApiResponse<T>
    {
        /// <summary>
        /// Status da requisição
        /// </summary>
        public bool Success { get; set; }
        
        /// <summary>
        /// Mensagem (em caso de erro)
        /// </summary>
        public string Message { get; set; } = string.Empty;
        
        /// <summary>
        /// Dados retornados
        /// </summary>
        public T? Data { get; set; }
    }
}