using System.Text.Json.Serialization;
using MaBibli.Shared.Entites;

namespace MaBibli.Shared.Dtos;

/// <summary>
/// Charge utile de création et de modification d'un livre.
/// </summary>
/// <remarks>
/// <see cref="Livre.AjoutePar"/> n'y figure pas volontairement : il est déterminé par le serveur
/// à partir de l'utilisateur authentifié, jamais par le client.
/// </remarks>
public record EnregistrementLivre
{
    /// <summary>Séparateur des auteurs dans la forme texte d'un champ de saisie.</summary>
    /// <remarks>
    /// Le point-virgule, et non la virgule : celle-ci est déjà prise par la forme
    /// bibliographique « Zola, Émile », qu'on doit pouvoir taper telle quelle.
    /// </remarks>
    public const char SeparateurAuteurs = ';';

    /// <summary>Facultatif : certains livres n'ont pas d'ISBN. Normalisé par le serveur.</summary>
    public string? Isbn { get; set; }

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

    /// <summary>
    /// Noms des auteurs, dans l'ordre de la couverture. Le serveur les rattache aux fiches
    /// existantes quand c'est sûr, et en crée sinon.
    /// </summary>
    public List<string> Auteurs { get; set; } = [];

    public string? Editeur { get; set; }

    public Format Format { get; set; }

    /// <summary>
    /// Statut de lecture <b>de l'appelant</b>. <c>null</c> = non commencé, et aucune ligne n'est
    /// alors écrite en base.
    /// </summary>
    public Statut? Statut { get; set; }

    public string? CoverUrl { get; set; }

    /// <summary>
    /// Vue « une seule ligne » de <see cref="Auteurs"/>, pour les champs de saisie simples.
    /// </summary>
    /// <remarks>
    /// Non sérialisée : <see cref="Auteurs"/> est la forme de référence sur le fil. Cette
    /// propriété existe pour que l'interface puisse lier un <c>&lt;input&gt;</c> unique sans
    /// avoir à gérer une liste dynamique — un foyer saisit un auteur dans l'immense majorité
    /// des cas, et les rares livres à quatre auteurs se tapent avec des « ; ».
    /// </remarks>
    [JsonIgnore]
    public string? Auteur
    {
        get => Auteurs.Count == 0 ? null : string.Join($"{SeparateurAuteurs} ", Auteurs);
        set => Auteurs = Decouper(value);
    }

    /// <summary>Découpe une saisie texte en noms d'auteurs, en écartant les entrées vides.</summary>
    public static List<string> Decouper(string? saisie) =>
        string.IsNullOrWhiteSpace(saisie)
            ? []
            : saisie.Split(SeparateurAuteurs, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
                    .ToList();
}

/// <summary>Charge utile du changement de statut de lecture — l'action la plus fréquente.</summary>
/// <remarks>
/// Le statut posé est toujours celui de l'appelant : il n'y a pas de champ « utilisateur »,
/// et il ne doit jamais y en avoir. Personne ne coche « lu » à la place d'un autre.
/// </remarks>
public record ChangementStatut
{
    /// <summary><c>null</c> retire le statut : le livre redevient « non commencé » pour l'appelant.</summary>
    public Statut? Statut { get; set; }
}
