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

namespace Jellyfin.Plugin.SRFPlay.Providers;

/// <summary>
/// Provides metadata for SRF Play episodes.
/// </summary>
public class SRFEpisodeProvider : IRemoteMetadataProvider<Episode, EpisodeInfo>
{
    private readonly ILogger<SRFEpisodeProvider> _logger;
    private readonly IMediaCompositionFetcher _compositionFetcher;

    /// <summary>
    /// Initializes a new instance of the <see cref="SRFEpisodeProvider"/> class.
    /// </summary>
    /// <param name="logger">The logger.</param>
    /// <param name="compositionFetcher">The media composition fetcher.</param>
    public SRFEpisodeProvider(
        ILogger<SRFEpisodeProvider> logger,
        IMediaCompositionFetcher compositionFetcher)
    {
        _logger = logger;
        _compositionFetcher = compositionFetcher;
    }

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

    /// <inheritdoc />
    public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(EpisodeInfo searchInfo, CancellationToken cancellationToken)
    {
        var results = new List<RemoteSearchResult>();

        try
        {
            // Check if we have a URN to search with
            if (searchInfo.ProviderIds.TryGetValue("SRF", out var urn) && !string.IsNullOrEmpty(urn))
            {
                _logger.LogDebug("Searching for episode with URN: {Urn}", urn);

                var mediaComposition = await _compositionFetcher.GetMediaCompositionAsync(urn, cancellationToken).ConfigureAwait(false);

                if (mediaComposition?.HasChapters == true)
                {
                    var chapter = mediaComposition.ChapterList[0];
                    results.Add(new RemoteSearchResult
                    {
                        Name = chapter.Title,
                        Overview = chapter.Description ?? chapter.Lead,
                        ImageUrl = chapter.ImageUrl,
                        SearchProviderName = Name,
                        ProviderIds = new Dictionary<string, string>
                        {
                            { "SRF", chapter.Urn }
                        }
                    });
                }
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error searching for episode: {Name}", searchInfo.Name);
        }

        return results;
    }

    /// <inheritdoc />
    public async Task<MetadataResult<Episode>> GetMetadata(EpisodeInfo info, CancellationToken cancellationToken)
    {
        var result = new MetadataResult<Episode>();

        try
        {
            // Check if we have a URN
            if (!info.ProviderIds.TryGetValue("SRF", out var urn) || string.IsNullOrEmpty(urn))
            {
                _logger.LogDebug("No SRF URN found for episode: {Name}", info.Name);
                return result;
            }

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

            var mediaComposition = await _compositionFetcher.GetMediaCompositionAsync(urn, cancellationToken).ConfigureAwait(false);

            if (mediaComposition?.HasChapters != true)
            {
                _logger.LogWarning("No chapter information found for URN: {Urn}", urn);
                return result;
            }

            // Get the first chapter (main video)
            var chapter = mediaComposition.ChapterList[0];

            result.Item = new Episode
            {
                Name = chapter.Title,
                Overview = chapter.Description ?? chapter.Lead,
                ProviderIds = new Dictionary<string, string>
                {
                    { "SRF", chapter.Urn }
                }
            };

            // Set episode and season numbers if available
            if (chapter.EpisodeNumber.HasValue)
            {
                result.Item.IndexNumber = chapter.EpisodeNumber;
            }

            if (chapter.SeasonNumber.HasValue)
            {
                result.Item.ParentIndexNumber = chapter.SeasonNumber;
            }

            // Set premiere date if available
            if (chapter.Date.HasValue)
            {
                result.Item.PremiereDate = chapter.Date;
            }

            // Set runtime (convert from milliseconds to ticks)
            if (chapter.Duration > 0)
            {
                result.Item.RunTimeTicks = TimeSpan.FromMilliseconds(chapter.Duration).Ticks;
            }

            // Set series information if available
            if (mediaComposition.Show != null)
            {
                result.Item.SeriesName = mediaComposition.Show.Title;

                // Set series provider ID on the episode
                if (!string.IsNullOrEmpty(mediaComposition.Show.Urn))
                {
                    result.Item.SetProviderId("SRF_Series", mediaComposition.Show.Urn);
                }
            }

            result.HasMetadata = true;
            _logger.LogDebug("Successfully fetched metadata for episode: {Title}", chapter.Title);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error fetching metadata for episode: {Name}", info.Name);
        }

        return result;
    }

    /// <inheritdoc />
    public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
    {
        throw new NotImplementedException("Image handling is done by SRFImageProvider");
    }
}
