using MaBibli.Shared.Textes;

namespace MaBibli.Shared.Entites;

/// <summary>
/// Un livre que l'on aimerait acquérir. <b>Personnel</b> : chacun sa liste.
/// </summary>
/// <remarks>
/// <b>Pourquoi une entité séparée plutôt qu'un statut de plus sur <see cref="Livre"/> ?</b>
/// Un livre souhaité n'est pas un livre possédé. S'il était une ligne de <c>Livres</c>, il
/// entrerait mécaniquement dans le catalogue, dans les compteurs, dans les prêts et dans le
/// cache hors-ligne — et il faudrait ajouter « et qui n'est pas souhaité » à <b>chaque</b>
/// lecture du catalogue. Un invariant qu'il faut réécrire à chaque requête finit toujours par
/// être oublié quelque part ; ici l'inventaire et l'envie ne se croisent tout simplement pas,
/// parce qu'ils ne vivent pas dans la même table.
/// <para>
/// C'est aussi la seule forme qui accepte une envie <b>sans ISBN ni édition arrêtée</b> : on
/// souhaite une œuvre (« le dernier Werber »), on possède un exemplaire. Un souhait n'a donc
/// ni <see cref="Format"/> ni couverture obligatoire, et ne peut pas être prêté.
/// </para>
/// <para>
/// La portée personnelle suit <see cref="StatutLecture"/>, dont la documentation annonçait déjà
/// ce voisinage : <see cref="Utilisateur"/> <b>est</b> une frontière, contrairement à
/// <see cref="Livre.AjoutePar"/>. On ne lit jamais la liste d'envies de quelqu'un d'autre —
/// c'est précisément ce qui permet d'offrir un livre sans vendre la mèche.
/// </para>
/// </remarks>
public class LivreSouhaite
{
    public int Id { get; set; }

    /// <summary>
    /// <c>YNH_USER</c> du propriétaire de l'envie. <b>Frontière</b> : toute lecture filtre dessus.
    /// </summary>
    public string Utilisateur { get; set; } = string.Empty;

    public string Titre { get; set; } = string.Empty;

    /// <summary>
    /// Titre mis à plat, servant à la fois au dédoublonnage et au rapprochement avec le
    /// catalogue (« ai-je déjà ce livre ? »). Recalculé à chaque écriture.
    /// </summary>
    public string TitreNormalise { get; set; } = string.Empty;

    /// <summary>
    /// Auteur en <b>texte libre</b>, volontairement pas une clé étrangère vers <see cref="Auteur"/>.
    /// </summary>
    /// <remarks>
    /// La table <c>Auteurs</c> décrit qui est <i>dans la bibliothèque</i> : y insérer les auteurs
    /// souhaités les ferait apparaître sur l'écran des auteurs avec « 0 livre », et exposerait la
    /// liste d'envies d'une personne à tout le foyer — l'inverse de ce qu'on veut. Le texte libre
    /// survit en outre à la disparition de l'auteur du catalogue.
    /// </remarks>
    public string? Auteur { get; set; }

    /// <summary>
    /// Auteur mis à plat. <b>Jamais <c>null</c></b> (chaîne vide si l'auteur est inconnu) :
    /// SQLite considère deux <c>NULL</c> comme distincts, et l'index unique laisserait alors
    /// passer des doublons d'envies sans auteur.
    /// </summary>
    public string AuteurNormalise { get; set; } = string.Empty;

    public string? Editeur { get; set; }

    /// <summary>Année de publication, telle que la source la donne. Texte : la BnF écrit « 2012 », mais aussi « [DL 2012] ».</summary>
    public string? Annee { get; set; }

    /// <summary>ISBN d'une édition repérée, quand il y en a une. Facultatif : on souhaite une œuvre, pas forcément une édition.</summary>
    public string? Isbn { get; set; }

    public string? CoverUrl { get; set; }

    /// <summary>Note libre : « demandé à Noël », « en poche seulement », « chez Untel ».</summary>
    public string? Note { get; set; }

    public DateTime DateAjout { get; set; }

    public void RecalculerFormes()
    {
        Titre = Titre.Trim();
        TitreNormalise = CleOeuvre.Cle(Titre);
        Auteur = string.IsNullOrWhiteSpace(Auteur) ? null : Auteur.Trim();
        AuteurNormalise = RapprochementAuteurs.Cle(Auteur);
    }
}
