using Microsoft.Extensions.Logging;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text.Json;

namespace YTExtractor.Services.Handlers
{
    public class YtDlpHandler : YoutubeServiceHandler
    {
        private readonly VttFixerService _vttFixerService;

        public YtDlpHandler(ILogger<YtDlpHandler> logger, VttFixerService vttFixerService) : base(logger)
        {
            _vttFixerService = vttFixerService;
        }

        public override async Task<YtDlpInfo> HandleVideoInfo(string url, string workingDir)
        {
            try
            {
                _logger.LogInformation("Getting video info using yt-dlp for {Url}", url);
                
                var startInfo = new ProcessStartInfo
                {
                    FileName = "yt-dlp",
                    Arguments = $"--dump-json {url}",
                    RedirectStandardOutput = true,
                    UseShellExecute = false,
                    CreateNoWindow = true,
                    WorkingDirectory = workingDir
                };

                using var process = Process.Start(startInfo);
                var output = await process.StandardOutput.ReadToEndAsync();
                await process.WaitForExitAsync();

                if (process.ExitCode != 0)
                    throw new Exception("Failed to get video info using yt-dlp");

                var jsonDoc = JsonDocument.Parse(output);
                var root = jsonDoc.RootElement;

                return new YtDlpInfo(
                    root.GetProperty("title").GetString() ?? "",
                    root.GetProperty("thumbnail").GetString() ?? ""
                );
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting video info with yt-dlp for {Url}", url);
                
                // Pass to the next handler if yt-dlp fails
                if (_nextHandler != null)
                {
                    return await _nextHandler.HandleVideoInfo(url, workingDir);
                }
                
                throw new Exception("Failed to get video info. No more handlers available.");
            }
        }
        
        public override async Task<string> HandleSubtitles(string url, string language, string workingDir)
        {
            try
            {
                _logger.LogInformation("Getting subtitles using yt-dlp for {Url} in language {Language}", url, language);
                
                var pathExe = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                var exePath = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
                    ? Path.Combine(pathExe, "yt-dlp.exe")
                    : "yt-dlp"; 
                
                var startInfo = new ProcessStartInfo
                {
                    FileName = exePath,
                    Arguments = $"--write-sub --write-auto-sub --sub-lang {language} --skip-download {url}",
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    UseShellExecute = false,
                    CreateNoWindow = true,
                    WorkingDirectory = workingDir
                };

                using var process = Process.Start(startInfo);
                var output = await process.StandardOutput.ReadToEndAsync();
                var error = await process.StandardError.ReadToEndAsync();
                await process.WaitForExitAsync();

                var subtitleFile = Directory.GetFiles(workingDir, "*.vtt").FirstOrDefault();
                if (subtitleFile == null)
                    throw new Exception("No subtitles found using yt-dlp");

                // Read the VTT file
                var vttContent = await File.ReadAllTextAsync(subtitleFile);
                
                // Fix the VTT content
                _logger.LogInformation("Fixing VTT subtitles for {Url}", url);
                var serviceSrt = new ConvertTranscriptService();
                var srt = serviceSrt.ConvertToSrt(vttContent);
                var fixedContent = _vttFixerService.FixYoutubeVtt(vttContent);
                
                return fixedContent;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting subtitles with yt-dlp for {Url}", url);
                
                // Pass to the next handler if yt-dlp fails
                if (_nextHandler != null)
                {
                    return await _nextHandler.HandleSubtitles(url, language, workingDir);
                }
                
                throw new Exception("Failed to get subtitles. No more handlers available.");
            }
        }
    }
}