using MaBibli.Shared.Textes;
namespace MaBibli.Shared.Entites;
///
/// Un regroupement ordonné de livres : trilogie, série, cycle, intégrale.
///
///
/// C'est la première notion du projet qui porte sur une relation entre livres plutôt que
/// sur un livre. Trois choses en découlent, et un simple champ texte « série » sur
/// n'en couvrirait aucune.
///
/// 1. Deux niveaux, au moins. La Légende de Drizzt regroupe plusieurs trilogies.
/// D'où , une auto-référence : un cycle est une série qui
/// contient des séries. Un champ « cycle » séparé figerait la profondeur à deux et obligerait à
/// tout refaire au troisième niveau.
///
///
/// 2. L'ordre de lecture n'est pas l'ordre de publication. L'Elfe noir est une
/// préquelle écrite après. C'est précisément l'information qu'on vient chercher : elle est
/// stockée (), jamais déduite d'une année.
///
///
/// 3. La portée est COMMUNE au foyer, comme le catalogue et les prêts, contrairement au
/// statut de lecture et à la liste d'envies. L'ordre de lecture d'une saga est une propriété de
/// l'œuvre : il ne change pas selon qui regarde. est donc une trace,
/// pas une frontière — ne jamais filtrer dessus, comme .
///
///
public class Serie
{
public int Id { get; set; }
public string Titre { get; set; } = string.Empty;
///
/// Titre mis à plat. Porte un index unique : une série, une fiche.
///
///
/// L'unicité est globale et non « par série parente », parce que
/// est nullable et que SQLite tient deux NULL pour
/// distincts : une unicité incluant le parent laisserait passer autant de doublons qu'on
/// veut à la racine — exactement le piège documenté sur LivreSouhaite.AuteurNormalise.
///
public string TitreNormalise { get; set; } = string.Empty;
/// La série qui contient celle-ci, quand c'en est une partie d'un cycle.
public int? SerieParenteId { get; set; }
public Serie? SerieParente { get; set; }
public List SousSeries { get; set; } = [];
/// Rang de cette série dans sa série parente. Sans objet à la racine.
public int Position { get; set; }
public List Elements { get; set; } = [];
public DateTime DateAjout { get; set; }
/// Qui a créé la série. Trace, pas frontière : la série est commune.
public string? AjoutePar { get; set; }
public void RecalculerFormes()
{
Titre = Titre.Trim();
TitreNormalise = NormalisationTexte.Normaliser(Titre);
}
}
///
/// Une position dans une série : le tome n, qu'on le possède ou non.
///
///
/// ⚠️ Ce n'est pas « un livre de la série » mais une place dans l'ordre de lecture. La
/// nuance est tout l'intérêt de l'écran : sans position sans livre, on ne pourrait pas montrer
/// les trous — « il vous manque le tome 3 » —, qui est la demande d'origine. Aucune source ne
/// donne l'ordre de lecture d'une saga (la BnF ne l'expose pas, et l'ordre de publication est
/// justement faux pour une préquelle) : les tomes absents n'existent que si on les saisit.
///
/// est donc toujours renseigné, y compris quand
/// l'est : c'est ce qui permet à la suppression d'un livre de laisser un
/// trou nommé plutôt qu'une ligne muette. La clé étrangère est en SetNull pour cette
/// raison précise — supprimer un livre ne doit pas trouer la structure de la saga.
///
///
public class ElementSerie
{
public int Id { get; set; }
public int SerieId { get; set; }
public Serie? Serie { get; set; }
/// Rang dans l'ordre de lecture, à partir de 0.
public int Position { get; set; }
/// Le livre du catalogue, s'il est possédé. null = un trou.
public int? LivreId { get; set; }
public Livre? Livre { get; set; }
///
/// Titre du tome. Renseigné même quand le livre est là, pour survivre à sa suppression.
///
public string Titre { get; set; } = string.Empty;
public void RecalculerFormes() => Titre = Titre.Trim();
}