using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using SaasMediaWorker.Configuration;
using SaasMediaWorker.Models;

namespace SaasMediaWorker.Services;

/// <summary>
/// Higgsfield AI API Client — Video klip üretimi.
/// Her sahnenin görsel prompt'unu Higgsfield'a gönderip video dosyası indirir.
/// </summary>
public class HiggsFieldService
{
    private readonly HttpClient _httpClient;
    private readonly ILogger<HiggsFieldService> _logger;
    private readonly ApiSettings _settings;

    public HiggsFieldService(
        HttpClient httpClient,
        ILogger<HiggsFieldService> logger,
        IOptions<ApiSettings> settings)
    {
        _httpClient = httpClient;
        _logger = logger;
        _settings = settings.Value;

        _httpClient.BaseAddress = new Uri(_settings.HiggsFieldBaseUrl);
        _httpClient.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Bearer", _settings.HiggsFieldApiKey);
        _httpClient.Timeout = TimeSpan.FromMinutes(5);
    }

    /// <summary>
    /// Bir sahne için video klip üretir ve dosyayı belirtilen dizine indirir.
    /// </summary>
    public async Task<GeneratedMediaFile> GenerateVideoClipAsync(
        ScenePayload scene,
        string outputDirectory,
        string aspectRatio,
        CancellationToken ct)
    {
        _logger.LogInformation(
            "🎥 Video üretimi — Sahne {Order}: {Prompt}",
            scene.Order, scene.VisualPrompt[..Math.Min(80, scene.VisualPrompt.Length)]);

        var requestBody = new
        {
            prompt = scene.VisualPrompt,
            duration = Math.Max(3, Math.Min(10, (int)scene.Duration)),
            aspect_ratio = MapAspectRatio(aspectRatio),
            style = "cinematic",
            quality = "high"
        };

        var content = new StringContent(
            JsonSerializer.Serialize(requestBody),
            Encoding.UTF8,
            "application/json");

        // Video üretim isteği gönder
        var response = await _httpClient.PostAsync("/generations", content, ct);
        response.EnsureSuccessStatusCode();

        var responseJson = await response.Content.ReadAsStringAsync(ct);
        var result = JsonSerializer.Deserialize<JsonElement>(responseJson);

        // Generation ID al ve polling ile sonucu bekle
        var generationId = result.GetProperty("id").GetString()
            ?? throw new InvalidOperationException("Generation ID alınamadı");

        _logger.LogInformation("Higgsfield generation başlatıldı: {Id}", generationId);

        // Polling — video hazır olana kadar bekle
        var videoUrl = await PollForCompletionAsync(generationId, ct);

        // Video dosyasını indir
        var outputPath = Path.Combine(outputDirectory, $"scene_{scene.Order:D2}_video.mp4");
        await DownloadFileAsync(videoUrl, outputPath, ct);

        var fileInfo = new FileInfo(outputPath);

        return new GeneratedMediaFile
        {
            SceneId = scene.Id,
            SceneOrder = scene.Order,
            Type = MediaFileType.VideoClip,
            LocalPath = outputPath,
            FileSizeBytes = fileInfo.Length,
            DurationSeconds = scene.Duration,
            MimeType = "video/mp4",
            AiProvider = "higgsfield"
        };
    }

    private async Task<string> PollForCompletionAsync(string generationId, CancellationToken ct)
    {
        var maxAttempts = 120; // 10 dakika (5s interval × 120)
        for (var i = 0; i < maxAttempts; i++)
        {
            ct.ThrowIfCancellationRequested();
            await Task.Delay(5000, ct);

            var response = await _httpClient.GetAsync($"/generations/{generationId}", ct);
            response.EnsureSuccessStatusCode();

            var json = await response.Content.ReadAsStringAsync(ct);
            var result = JsonSerializer.Deserialize<JsonElement>(json);
            var status = result.GetProperty("status").GetString();

            if (status == "completed")
            {
                return result.GetProperty("video_url").GetString()
                    ?? throw new InvalidOperationException("Video URL bulunamadı");
            }

            if (status == "failed")
            {
                var errorMsg = result.TryGetProperty("error", out var err)
                    ? err.GetString() : "Bilinmeyen hata";
                throw new InvalidOperationException($"Higgsfield video üretimi başarısız: {errorMsg}");
            }

            if (i % 6 == 0) // Her 30 saniyede bir log
            {
                _logger.LogInformation("Higgsfield polling — {Id}: {Status}", generationId, status);
            }
        }

        throw new TimeoutException($"Higgsfield video üretimi zaman aşımına uğradı: {generationId}");
    }

    private async Task DownloadFileAsync(string url, string outputPath, CancellationToken ct)
    {
        using var response = await _httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, ct);
        response.EnsureSuccessStatusCode();

        await using var fileStream = File.Create(outputPath);
        await response.Content.CopyToAsync(fileStream, ct);

        _logger.LogInformation("Video indirildi: {Path} ({Size} bytes)",
            outputPath, new FileInfo(outputPath).Length);
    }

    private static string MapAspectRatio(string aspectRatio) => aspectRatio switch
    {
        "PORTRAIT_9_16" => "9:16",
        "SQUARE_1_1" => "1:1",
        "LANDSCAPE_16_9" => "16:9",
        _ => "9:16"
    };
}
