using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Plugin.SRFPlay.Services.Interfaces;
using Jellyfin.Plugin.SRFPlay.Utilities;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Providers;
using Microsoft.Extensions.Logging;

namespace Jellyfin.Plugin.SRFPlay.Providers;

/// <summary>
/// Provides images for SRF Play content.
/// </summary>
public class SRFImageProvider : IRemoteImageProvider, IHasOrder
{
    private readonly IHttpClientFactory _httpClientFactory;
    private readonly ILogger<SRFImageProvider> _logger;
    private readonly IMediaCompositionFetcher _compositionFetcher;

    /// <summary>
    /// Initializes a new instance of the <see cref="SRFImageProvider"/> class.
    /// </summary>
    /// <param name="httpClientFactory">The HTTP client factory.</param>
    /// <param name="loggerFactory">The logger factory.</param>
    /// <param name="compositionFetcher">The media composition fetcher.</param>
    public SRFImageProvider(
        IHttpClientFactory httpClientFactory,
        ILoggerFactory loggerFactory,
        IMediaCompositionFetcher compositionFetcher)
    {
        _httpClientFactory = httpClientFactory;
        _logger = loggerFactory.CreateLogger<SRFImageProvider>();
        _compositionFetcher = compositionFetcher;
    }

    /// <inheritdoc />
    public string Name => "SRF Play";

    /// <inheritdoc />
    public int Order => 0;

    /// <inheritdoc />
    public bool Supports(BaseItem item)
    {
        // Support movies and episodes for now
        return item is MediaBrowser.Controller.Entities.Movies.Movie ||
               item is MediaBrowser.Controller.Entities.TV.Episode ||
               item is MediaBrowser.Controller.Entities.TV.Series;
    }

    /// <inheritdoc />
    public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
    {
        return new List<ImageType>
        {
            ImageType.Primary,
            ImageType.Backdrop,
            ImageType.Thumb
        };
    }

    /// <inheritdoc />
    public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
    {
        var list = new List<RemoteImageInfo>();

        try
        {
            // Check if item has SRF URN in provider IDs
            if (!item.ProviderIds.TryGetValue("SRF", out var urn) || string.IsNullOrEmpty(urn))
            {
                _logger.LogDebug("No SRF URN found for item: {ItemName}", item.Name);
                return list;
            }

            _logger.LogDebug("Fetching images for SRF URN: {Urn}", urn);

            // Fetch media composition to get image URLs
            var mediaComposition = await _compositionFetcher.GetMediaCompositionAsync(urn, cancellationToken).ConfigureAwait(false);

            if (mediaComposition == null)
            {
                _logger.LogWarning("Failed to fetch media composition for URN: {Urn}", urn);
                return list;
            }

            // Extract images from chapters
            if (mediaComposition.HasChapters)
            {
                var chapter = mediaComposition.ChapterList[0];
                if (!string.IsNullOrEmpty(chapter.ImageUrl))
                {
                    _logger.LogDebug("URN {Urn}: Adding chapter image: {ImageUrl}", urn, chapter.ImageUrl);
                    list.Add(new RemoteImageInfo
                    {
                        Url = chapter.ImageUrl,
                        Type = ImageType.Primary,
                        ProviderName = Name
                    });

                    list.Add(new RemoteImageInfo
                    {
                        Url = chapter.ImageUrl,
                        Type = ImageType.Thumb,
                        ProviderName = Name
                    });
                }
                else
                {
                    _logger.LogDebug("URN {Urn}: No chapter image available", urn);
                }
            }

            // Extract images from show
            if (mediaComposition.Show != null)
            {
                if (!string.IsNullOrEmpty(mediaComposition.Show.ImageUrl))
                {
                    _logger.LogDebug("URN {Urn}: Adding show image: {ImageUrl}", urn, mediaComposition.Show.ImageUrl);
                    list.Add(new RemoteImageInfo
                    {
                        Url = mediaComposition.Show.ImageUrl,
                        Type = ImageType.Primary,
                        ProviderName = Name
                    });
                }

                if (!string.IsNullOrEmpty(mediaComposition.Show.BannerImageUrl))
                {
                    _logger.LogDebug("URN {Urn}: Adding show banner: {BannerUrl}", urn, mediaComposition.Show.BannerImageUrl);
                    list.Add(new RemoteImageInfo
                    {
                        Url = mediaComposition.Show.BannerImageUrl,
                        Type = ImageType.Backdrop,
                        ProviderName = Name
                    });
                }
            }

            _logger.LogInformation("URN {Urn}: Found {Count} images for '{ItemName}'", urn, list.Count, item.Name);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error fetching images for item: {ItemName}", item.Name);
        }

        return list;
    }

    /// <inheritdoc />
    public async Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
    {
        _logger.LogDebug("Fetching image from URL: {Url}", url);

        var httpClient = _httpClientFactory.CreateClient(NamedClient.Default);

        // Create request with proper headers - SRF CDN requires User-Agent
        var request = new HttpRequestMessage(HttpMethod.Get, new Uri(url));
        request.Headers.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36");
        request.Headers.Accept.ParseAdd("image/jpeg, image/png, image/webp, image/*;q=0.8");

        var response = await httpClient.SendAsync(request, cancellationToken).ConfigureAwait(false);

        var originalContentType = response.Content.Headers.ContentType?.MediaType;
        _logger.LogDebug(
            "Image response status: {StatusCode}, Content-Type: {ContentType}, Content-Length: {Length}",
            response.StatusCode,
            originalContentType ?? "null",
            response.Content.Headers.ContentLength);

        // Fix Content-Type if it's not a proper image type - SRF CDN often returns wrong content type
        // Jellyfin needs correct Content-Type to process images
        if (response.IsSuccessStatusCode)
        {
            var needsContentTypeFix = string.IsNullOrEmpty(originalContentType) ||
                                      originalContentType == "binary/octet-stream" ||
                                      originalContentType == "application/octet-stream" ||
                                      !originalContentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase);

            if (needsContentTypeFix)
            {
                // Determine correct content type from URL extension or default to JPEG
                var contentType = MimeTypeHelper.GetImageContentType(url);
                if (!string.IsNullOrEmpty(contentType))
                {
                    _logger.LogInformation(
                        "Fixing Content-Type from '{OriginalType}' to '{NewType}' for {Url}",
                        originalContentType ?? "null",
                        contentType,
                        url);
                    response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
                }
            }
        }

        return response;
    }
}
