// Copyright (c) Barry Dorrans. All rights reserved.
// Licensed under the MIT License.

namespace idunno.Bluesky.RichText;

/// <summary>
/// Provides an object representation of a hash tag in a Bluesky post.
/// </summary>
public record Link : PostBuilderFacetFeature
{
    /// <summary>
    /// Creates a new instance of <see cref="Link"/>.
    /// </summary>
    /// <param name="uri">The <see cref="System.Uri"/> to add to a post.</param>
    /// <exception cref="ArgumentException">Thrown when <paramref name="uri"/> is <see langword="null"/> or is not a valid <see cref="System.Uri"/>.</exception>
    public Link(string uri) : base()
    {
        ArgumentException.ThrowIfNullOrWhiteSpace(uri);

        if (!Uri.TryCreate(uri, UriKind.Absolute, out Uri? createdUri))
        {
            throw new ArgumentException("cannot be parsed as a Uri.", nameof(uri));
        }

        Uri = createdUri;
        Text = uri;
    }

    /// <summary>
    /// Creates a new instance of <see cref="Link"/>.
    /// </summary>
    /// <param name="uri">The <see cref="System.Uri"/> to add to a post.</param>
    /// <exception cref="ArgumentNullException">Thrown when <paramref name="uri"/> is <see langword="null"/>.</exception>
    public Link(Uri uri)
    {
        ArgumentNullException.ThrowIfNull(uri);

        string uriAsString = uri.ToString();

        Uri = uri;
        Text = uriAsString;
    }

    /// <summary>
    /// Creates a new instance of <see cref="Link"/>.
    /// </summary>
    /// <param name="uri">The <see cref="Uri"/> to add to a post.</param>
    /// <param name="text">The text to wrap the hashtag around.</param>
    /// <exception cref="ArgumentException">Thrown when <paramref name="text"/> is <see langword="null"/> or white space.</exception>
    /// <exception cref="ArgumentNullException">Thrown when <paramref name="uri"/> is <see langword="null"/>.</exception>
    public Link(Uri uri, string text) : base(text)
    {
        ArgumentNullException.ThrowIfNull(uri);
        ArgumentException.ThrowIfNullOrWhiteSpace(text);

        Uri = uri;
    }

    /// <summary>
    /// Creates a new instance of <see cref="Link"/>.
    /// </summary>
    /// <param name="uri">The <see cref="System.Uri"/> to add to a post.</param>
    /// <param name="text">The text to wrap the hashtag around, if any. If not specified the <paramref name="uri"/> will be used..</param>
    /// <exception cref="ArgumentException"> when <paramref name="uri"/> or <paramref name="text"/> is <see langword="null"/> or white space.</exception>
    public Link(string uri, string text) : base(text)
    {
        ArgumentException.ThrowIfNullOrWhiteSpace(uri);
        ArgumentException.ThrowIfNullOrWhiteSpace(text);

        if (!Uri.TryCreate(uri, UriKind.Absolute, out Uri? createdUri))
        {
            throw new ArgumentException("cannot be parsed as a Uri.", nameof(uri));
        }

        Uri = createdUri;
    }

    /// <summary>
    /// Gets the <see cref="Uri"/> the facet feature links to.
    /// </summary>
    public Uri Uri { get; init; }
}