using ErsatzTV.Core;
using ErsatzTV.Core.Domain;

namespace ErsatzTV.Application.Channels;

/// <summary>
///     Validation rules shared by <see cref="CreateChannelHandler" /> and
///     <see cref="UpdateChannelHandler" />. These were previously enforced only by the Blazor page
///     (<c>ChannelEditViewModelValidator</c>); porting them into the handlers makes them apply to
///     the REST API as well. Failures map to HTTP 422.
/// </summary>
internal static class ChannelValidations
{
    /// <summary>
    ///     A channel must belong to a non-empty group; the value is used as the M3U
    ///     <c>group-title</c>. Mirrors the Blazor rule <c>RuleFor(x =&gt; x.Group).NotEmpty()</c>.
    /// </summary>
    internal static Validation<BaseError, string> ValidateGroup(string group)
    {
        // Use explicit returns (not a ternary): BaseError has an implicit string conversion, so a
        // ternary would collapse both branches to BaseError and always produce a Fail.
        if (string.IsNullOrWhiteSpace(group))
        {
            return BaseError.New("Channel group is required");
        }

        return group;
    }

    /// <summary>A disabled channel may not be shown in the EPG.</summary>
    internal static Validation<BaseError, bool> ValidateShowInEpg(bool isEnabled, bool showInEpg)
    {
        if (!isEnabled && showInEpg)
        {
            return BaseError.New("Disabled channels cannot be shown in EPG");
        }

        return showInEpg;
    }

    /// <summary>
    ///     A logo path that is an absolute URI must be a valid external (http/https) url.
    ///     Relative/local logo paths and empty values are allowed.
    /// </summary>
    internal static Validation<BaseError, string> ValidateLogo(string logoPath)
    {
        if (string.IsNullOrWhiteSpace(logoPath))
        {
            return string.Empty;
        }

        bool isAbsoluteUri = Uri.TryCreate(logoPath, UriKind.Absolute, out _);
        if (isAbsoluteUri && !Artwork.IsExternalUrl(logoPath))
        {
            return BaseError.New("External logo url is invalid");
        }

        return logoPath;
    }
}
