using System;

namespace AyCode.Core.Serializers.Toons;

/// <summary>
/// Cached navigation property metadata for efficient relationship information access.
/// Contains all relationship details detected once during type metadata construction.
/// </summary>
public sealed class AcNavigationPropertyInfo
{
    /// <summary>
    /// Whether this property is a primary key.
    /// </summary>
    public bool IsPrimaryKey { get; }

    /// <summary>
    /// Type of navigation relationship (ManyToOne, OneToMany, etc.).
    /// Null if this is not a navigation property.
    /// </summary>
    public ToonRelationType? NavigationType { get; }

    /// <summary>
    /// Foreign key property name on the current side.
    /// For ManyToOne/OneToOne: the FK property in this entity (e.g., "CustomerId").
    /// For OneToMany: null (FK is on the other side, see OtherKey).
    /// </summary>
    public string? ForeignKey { get; }

    /// <summary>
    /// Foreign key property name on the other side of the relationship.
    /// For OneToMany: the FK property in the related entity (e.g., "OrderId" in OrderItem).
    /// For ManyToOne: null (FK is on this side, see ForeignKey).
    /// This corresponds to Linq2Db's "OtherKey" concept.
    /// </summary>
    public string? OtherKey { get; }

    /// <summary>
    /// Navigation property name on the other side of the relationship.
    /// For OneToMany: the navigation property in the related entity pointing back (e.g., "Order" in OrderItem).
    /// For ManyToOne: the collection property in the related entity (e.g., "OrderItems" in Order).
    /// </summary>
    public string? InverseProperty { get; }

    /// <summary>
    /// Target entity type for navigation properties.
    /// For collections (OneToMany), this is the element type.
    /// For single references (ManyToOne), this is the property type.
    /// </summary>
    public Type? TargetType { get; }

    public AcNavigationPropertyInfo(
        bool isPrimaryKey = false,
        ToonRelationType? navigationType = null,
        string? foreignKey = null,
        string? otherKey = null,
        string? inverseProperty = null,
        Type? targetType = null)
    {
        IsPrimaryKey = isPrimaryKey;
        NavigationType = navigationType;
        ForeignKey = foreignKey;
        OtherKey = otherKey;
        InverseProperty = inverseProperty;
        TargetType = targetType;
    }

    /// <summary>
    /// Empty navigation info (not a navigation property, not a primary key).
    /// </summary>
    public static readonly AcNavigationPropertyInfo Empty = new();
}
