using Jellyfin.Plugin.SRFPlay.Api;
using Jellyfin.Plugin.SRFPlay.Channels;
using Jellyfin.Plugin.SRFPlay.Providers;
using Jellyfin.Plugin.SRFPlay.ScheduledTasks;
using Jellyfin.Plugin.SRFPlay.Services;
using Jellyfin.Plugin.SRFPlay.Services.Interfaces;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Model.Tasks;
using Microsoft.Extensions.DependencyInjection;

namespace Jellyfin.Plugin.SRFPlay;

/// <summary>
/// Service registrator for dependency injection.
/// </summary>
public class ServiceRegistrator : IPluginServiceRegistrator
{
    /// <inheritdoc />
    public void RegisterServices(IServiceCollection serviceCollection, IServerApplicationHost applicationHost)
    {
        // Register API client factory
        serviceCollection.AddSingleton<ISRFApiClientFactory, SRFApiClientFactory>();

        // Register core services with interfaces
        serviceCollection.AddSingleton<IMetadataCache, MetadataCache>();
        serviceCollection.AddSingleton<IStreamUrlResolver, StreamUrlResolver>();
        serviceCollection.AddSingleton<IMediaCompositionFetcher, MediaCompositionFetcher>();
        serviceCollection.AddSingleton<IStreamProxyService, StreamProxyService>();
        serviceCollection.AddSingleton<IMediaSourceFactory, MediaSourceFactory>();
        serviceCollection.AddSingleton<IContentExpirationService, ContentExpirationService>();
        serviceCollection.AddSingleton<IContentRefreshService, ContentRefreshService>();
        serviceCollection.AddSingleton<ICategoryService, CategoryService>();
        serviceCollection.AddSingleton<IResumeCleanupService, ResumeCleanupService>();

        // Clears livestream resume points the moment playback stops, so ended broadcasts never
        // linger in "Continue Watching" waiting for the nightly cleanup task.
        serviceCollection.AddHostedService<PlaybackResumeGuard>();

        // Register metadata providers
        serviceCollection.AddSingleton<SRFSeriesProvider>();
        serviceCollection.AddSingleton<SRFEpisodeProvider>();
        serviceCollection.AddSingleton<SRFImageProvider>();

        // Register media source provider
        serviceCollection.AddSingleton<SRFMediaProvider>();

        // Register recording service
        serviceCollection.AddSingleton<IRecordingService, RecordingService>();

        // Register scheduled tasks
        serviceCollection.AddSingleton<IScheduledTask, ContentRefreshTask>();
        serviceCollection.AddSingleton<IScheduledTask, ExpirationCheckTask>();
        serviceCollection.AddSingleton<IScheduledTask, RecordingSchedulerTask>();
        serviceCollection.AddSingleton<IScheduledTask, ResumeCleanupTask>();

        // Register one channel (tile) per SRG business unit. Each must be registered as IChannel
        // for Jellyfin to discover it. A unit that is not in EnabledBusinessUnits returns no
        // content (its tile appears empty) - see SrgChannelBase.
        serviceCollection.AddSingleton<IChannel, SrfChannel>();
        serviceCollection.AddSingleton<IChannel, RtsChannel>();
        serviceCollection.AddSingleton<IChannel, RsiChannel>();
        serviceCollection.AddSingleton<IChannel, RtrChannel>();
        serviceCollection.AddSingleton<IChannel, SwiChannel>();
    }
}
