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

namespace MaBibli.Shared.Dtos;

/// <summary>Un auteur tel qu'exposé par l'API : de quoi l'afficher et cliquer dessus.</summary>
public record AuteurDto
{
    public required int Id { get; init; }

    public required string Nom { get; init; }

    /// <summary>Nombre de livres du catalogue rattachés à cet auteur. Renseigné par la liste des auteurs.</summary>
    public int NombreDeLivres { get; init; }
}

/// <summary>
/// Un livre tel qu'exposé par l'API. Volontairement <b>sans</b> la collection de ses prêts :
/// le catalogue n'a besoin que de savoir si le livre est dehors, et l'historique complet se
/// demande à part (<c>GET /api/livres/{id}/prets</c>) pour ne pas alourdir chaque liste.
/// </summary>
public record LivreDto
{
    public required int Id { get; init; }

    public string? Isbn { get; init; }

    public required string Titre { get; init; }

    /// <summary>Auteurs, dans l'ordre de la couverture. Peut être vide.</summary>
    public IReadOnlyList<AuteurDto> Auteurs { get; init; } = [];

    public string? Editeur { get; init; }

    public required Format Format { get; init; }

    /// <summary>
    /// Statut de lecture <b>de l'utilisateur courant</b>, ou <c>null</c> s'il n'en a jamais posé
    /// (« non commencé »).
    /// </summary>
    /// <remarks>
    /// Ce champ dépend de qui appelle : le même livre remonte « Lu » pour l'un et <c>null</c>
    /// pour l'autre. C'est voulu — le livre est commun, sa lecture ne l'est pas.
    /// </remarks>
    public Statut? Statut { get; init; }

    public string? CoverUrl { get; init; }

    public required DateTime DateAjout { get; init; }

    /// <summary>
    /// Qui a saisi le livre. <b>Information d'affichage, pas une frontière</b> :
    /// la bibliothèque est commune et aucune lecture ne filtre sur ce champ.
    /// </summary>
    public string? AjoutePar { get; init; }

    /// <summary>
    /// Nom de la personne qui a le livre en ce moment, ou <c>null</c> s'il est à la maison.
    /// </summary>
    /// <remarks>
    /// <b>Commun à tout le foyer</b>, contrairement au statut de lecture : un livre absent l'est
    /// pour tout le monde. Renseigné depuis le prêt ouvert du livre — il ne peut y en avoir qu'un.
    /// </remarks>
    public string? PreteA { get; init; }

    /// <summary>Date du prêt en cours, s'il y en a un.</summary>
    public DateTime? PreteDepuis { get; init; }

    [JsonIgnore]
    public bool EstPrete => PreteA is not null;

    /// <summary>Auteurs sur une ligne, pour un affichage compact.</summary>
    [JsonIgnore]
    public string? AuteursAffiches =>
        Auteurs.Count == 0 ? null : string.Join(", ", Auteurs.Select(a => a.Nom));
}
