using MediaBrowser.Model.Plugins;

namespace Jellyfin.Plugin.SRFPlay.Configuration;

/// <summary>
/// Business unit options for SRF content.
/// </summary>
public enum BusinessUnit
{
    /// <summary>
    /// SRF (Swiss Radio and Television - German).
    /// </summary>
    SRF,

    /// <summary>
    /// RTS (Radio Télévision Suisse - French).
    /// </summary>
    RTS,

    /// <summary>
    /// RSI (Radiotelevisione svizzera - Italian).
    /// </summary>
    RSI,

    /// <summary>
    /// RTR (Radiotelevisiun Svizra Rumantscha - Romansh).
    /// </summary>
    RTR,

    /// <summary>
    /// SWI (Swiss World International).
    /// </summary>
    SWI
}

/// <summary>
/// Quality preference for video streams.
/// </summary>
public enum QualityPreference
{
    /// <summary>
    /// Automatic quality selection.
    /// </summary>
    Auto,

    /// <summary>
    /// Standard definition.
    /// </summary>
    SD,

    /// <summary>
    /// High definition.
    /// </summary>
    HD
}

/// <summary>
/// Plugin configuration.
/// </summary>
public class PluginConfiguration : BasePluginConfiguration
{
    /// <summary>
    /// Initializes a new instance of the <see cref="PluginConfiguration"/> class.
    /// </summary>
    public PluginConfiguration()
    {
        // Set default options
        BusinessUnit = BusinessUnit.SRF;
        QualityPreference = QualityPreference.Auto;
        ContentRefreshIntervalHours = 6;
        ExpirationCheckIntervalHours = 24;
        CacheDurationMinutes = 60;
        EnableLatestContent = true;
        EnableTrendingContent = true;
        EnableCategoryFolders = true;
        EnabledTopics = new System.Collections.Generic.List<string>();
        GenerateTitleCards = true;
        LiveStartSegmentsBack = 3;
        CleanUpResumePoints = true;
        ClearLiveStreamResumePoints = true;
        ResumePointMaxAgeDays = 30;
        ResumePointMinPositionSeconds = 60;
        ResumePointCompletedPercent = 92;
    }

    /// <summary>
    /// Gets or sets the legacy single business unit. Retained only for backwards compatibility
    /// with older configs; every unit now has its own always-on channel.
    /// </summary>
    public BusinessUnit BusinessUnit { get; set; }

    /// <summary>
    /// Gets or sets the preferred video quality.
    /// </summary>
    public QualityPreference QualityPreference { get; set; }

    /// <summary>
    /// Gets or sets the content refresh interval in hours.
    /// </summary>
    public int ContentRefreshIntervalHours { get; set; }

    /// <summary>
    /// Gets or sets the expiration check interval in hours.
    /// </summary>
    public int ExpirationCheckIntervalHours { get; set; }

    /// <summary>
    /// Gets or sets the metadata cache duration in minutes.
    /// </summary>
    public int CacheDurationMinutes { get; set; }

    /// <summary>
    /// Gets or sets a value indicating whether to enable latest content discovery.
    /// </summary>
    public bool EnableLatestContent { get; set; }

    /// <summary>
    /// Gets or sets a value indicating whether to enable trending content discovery.
    /// </summary>
    public bool EnableTrendingContent { get; set; }

    /// <summary>
    /// Gets or sets a value indicating whether to use a proxy for API requests.
    /// </summary>
    public bool UseProxy { get; set; }

    /// <summary>
    /// Gets or sets the proxy server address (e.g., http://proxy.example.com:8080).
    /// </summary>
    public string ProxyAddress { get; set; } = string.Empty;

    /// <summary>
    /// Gets or sets the proxy username (optional).
    /// </summary>
    public string ProxyUsername { get; set; } = string.Empty;

    /// <summary>
    /// Gets or sets the proxy password (optional).
    /// </summary>
    public string ProxyPassword { get; set; } = string.Empty;

    /// <summary>
    /// Gets or sets a value indicating whether to enable category/topic folders in the channel.
    /// </summary>
    public bool EnableCategoryFolders { get; set; }

    /// <summary>
    /// Gets or sets the list of enabled topic IDs. If empty, all topics are shown.
    /// </summary>
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Required for configuration serialization")]
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1002:Do not expose generic lists", Justification = "Configuration DTO")]
    public System.Collections.Generic.List<string> EnabledTopics { get; set; }

    /// <summary>
    /// Gets or sets the public/external server URL for remote clients (e.g., https://jellyfin.example.com:8920).
    /// If not set, the plugin will use Jellyfin's GetSmartApiUrl() which may return local addresses.
    /// This is important for Android and other remote clients to access streams.
    /// </summary>
    public string PublicServerUrl { get; set; } = string.Empty;

    /// <summary>
    /// Gets or sets a value indicating whether to generate title card images with the content title.
    /// When enabled, generates custom thumbnails instead of using SRF-provided images.
    /// </summary>
    public bool GenerateTitleCards { get; set; }

    /// <summary>
    /// Gets or sets the output directory for sport livestream recordings.
    /// </summary>
    public string RecordingOutputPath { get; set; } = string.Empty;

    /// <summary>
    /// Gets or sets how many segments back from the live edge livestream playback should start.
    /// Injected as <c>#EXT-X-START:TIME-OFFSET=-(N * targetDuration)</c> into the live media
    /// playlist. This keeps the start point out of the volatile live edge, which on Android TV
    /// (ExoPlayer) otherwise causes stalling/jumping until a manual skip. RFC 8216 requires the
    /// offset to stay at least 3 target durations from the edge, so values below 3 are clamped.
    /// Set to 0 to disable injection entirely.
    /// </summary>
    public int LiveStartSegmentsBack { get; set; }

    /// <summary>
    /// Gets or sets a value indicating whether the "Clean Up SRF Play Continue Watching" task
    /// removes stale resume points. When false the task inspects nothing and clears nothing.
    /// </summary>
    public bool CleanUpResumePoints { get; set; }

    /// <summary>
    /// Gets or sets a value indicating whether resume points for livestreams are cleared.
    /// A livestream has no meaningful resume position, so stopping one otherwise leaves it
    /// pinned in "Continue Watching" forever. When enabled the position is also cleared
    /// immediately on playback stop, not just by the scheduled task.
    /// </summary>
    public bool ClearLiveStreamResumePoints { get; set; }

    /// <summary>
    /// Gets or sets the age in days after which an untouched resume point is cleared.
    /// Measured from the last time the item was played. Set to 0 to disable the age rule.
    /// </summary>
    public int ResumePointMaxAgeDays { get; set; }

    /// <summary>
    /// Gets or sets the minimum resume position in seconds. Anything at or below this is
    /// treated as an accidental start rather than something worth resuming.
    /// Set to 0 to disable the rule.
    /// </summary>
    public int ResumePointMinPositionSeconds { get; set; }

    /// <summary>
    /// Gets or sets the percentage of runtime at or beyond which playback counts as finished.
    /// Only applied to items with a known runtime. Set to 0 to disable the rule.
    /// </summary>
    public int ResumePointCompletedPercent { get; set; }
}
