@page "/ajout/isbn"
@inject ServiceLivresApi Api
@inject NavigationManager Navigation

<PageTitle>MaBibli — ajouter par ISBN</PageTitle>

<h1 class="titre-page">Ajouter par ISBN</h1>

@if (_etape == Etape.Saisie)
{
    <p class="message-discret">
        Scannez le code-barres, ou saisissez l'ISBN imprimé sur le livre.
    </p>

    <div class="barre-recherche">
        <input class="champ-saisie" type="text" inputmode="numeric" placeholder="978…"
               @bind="_isbn" @bind:event="oninput" @onkeydown="SurTouche"
               aria-label="ISBN" autocomplete="off" />
    </div>

    <div class="actions-formulaire">
        <button type="button" class="bouton bouton-principal"
                disabled="@(_chargement || string.IsNullOrWhiteSpace(_isbn))"
                @onclick="ChercherAsync">
            @(_chargement ? "Recherche…" : "Chercher")
        </button>
        @* La saisie manuelle reste le recours quand le code-barres est abîmé, absent,
           ou que la caméra est indisponible : elle ne disparaît jamais derrière le scan. *@
        <button type="button" class="bouton bouton-discret" @onclick="OuvrirScanner">
            Scanner
        </button>
        <a class="bouton bouton-discret" href="ajout/manuel">Saisir à la main</a>
    </div>
}

@if (_etape == Etape.Scan)
{
    <ScannerCodeBarres OnCodeDetecte="SurCodeDetecteAsync" OnAnnuler="Recommencer" />
}

@if (_erreur is not null)
{
    <p class="message-erreur" role="alert">@_erreur</p>
}

@foreach (var avertissement in _avertissements)
{
    <p class="message-avertissement">@avertissement</p>
}

@if (_etape == Etape.Choix)
{
    @* Décision actée dans CLAUDE.md : plusieurs notices pour un même ISBN (rééditions
       successives partageant l'ISBN), on ne choisit JAMAIS à la place de l'utilisateur.
       Les candidats partagent titre et auteur : ce sont l'éditeur et l'année qui départagent,
       donc ils sont mis en avant. *@
    <p class="message-discret">
        @_candidats.Count notices correspondent à cet ISBN. Elles se distinguent par l'éditeur et l'année.
    </p>

    <ul class="liste-candidats">
        @foreach (var (candidat, index) in _candidats.Select((c, i) => (c, i)))
        {
            <li class="carte-candidat" @key="index">
                <Couverture Url="@candidat.CoverUrl" Titre="@candidat.Titre" Classe="couverture-petite" />

                <div class="carte-corps">
                    <p class="carte-titre">@candidat.Titre</p>
                    @if (!string.IsNullOrWhiteSpace(candidat.Auteur))
                    {
                        <p class="carte-auteur">@candidat.Auteur</p>
                    }

                    <p class="candidat-distinction">
                        <span class="candidat-editeur">@(candidat.Editeur ?? "éditeur inconnu")</span>
                        <span class="candidat-annee">@(candidat.Annee ?? "année inconnue")</span>
                    </p>

                    <p class="carte-details">
                        <span class="etiquette">@candidat.Source</span>
                        @if (!string.IsNullOrWhiteSpace(candidat.IsbnInterroge))
                        {
                            <span>trouvé via @candidat.IsbnInterroge</span>
                        }
                    </p>

                    <button type="button" class="bouton bouton-principal"
                            @onclick="() => Choisir(candidat)">
                        Choisir cette édition
                    </button>
                </div>
            </li>
        }
    </ul>

    <div class="actions-formulaire">
        <button type="button" class="bouton bouton-discret" @onclick="Recommencer">Aucune : saisir à la main</button>
    </div>
}

@if (_etape == Etape.Formulaire)
{
    <p class="message-discret">
        Vérifiez et complétez la fiche : tout reste modifiable.
    </p>

    <FormulaireLivre Saisie="_saisie"
                     LibelleValidation="Ajouter au catalogue"
                     Erreur="@_erreurFormulaire"
                     EnCours="_enregistrement"
                     OnValider="EnregistrerAsync"
                     OnAnnuler="Recommencer" />
}

@code {
    private enum Etape { Saisie, Scan, Choix, Formulaire }

    private Etape _etape = Etape.Saisie;
    private string _isbn = string.Empty;
    private bool _chargement;
    private bool _enregistrement;
    private string? _erreur;
    private string? _erreurFormulaire;
    private IReadOnlyList<CandidatLivre> _candidats = [];
    private IReadOnlyList<string> _avertissements = [];
    private EnregistrementLivre _saisie = new();

    private void OuvrirScanner()
    {
        _erreur = null;
        _avertissements = [];
        _etape = Etape.Scan;
    }

    // Le scan enchaîne directement sur le flux de lookup existant : l'utilisateur
    // ne retape jamais ce qui vient d'être scanné.
    private async Task SurCodeDetecteAsync(string isbn)
    {
        _isbn = isbn;
        _etape = Etape.Saisie;
        await ChercherAsync();
    }

    private async Task SurTouche(KeyboardEventArgs e)
    {
        if (e.Key == "Enter" && !string.IsNullOrWhiteSpace(_isbn))
        {
            await ChercherAsync();
        }
    }

    private async Task ChercherAsync()
    {
        _chargement = true;
        _erreur = null;
        _avertissements = [];

        try
        {
            var resultat = await Api.ChercherIsbnAsync(_isbn.Trim());

            if (resultat is null)
            {
                _erreur = $"« {_isbn} » n'est pas un ISBN valide.";
                return;
            }

            _avertissements = resultat.Avertissements;
            _candidats = resultat.Candidats;

            if (_candidats.Count == 0)
            {
                // Aucune notice : on ne bloque pas, le formulaire manuel reste la porte de sortie.
                _erreur = "Aucune notice trouvée pour cet ISBN. Complétez la fiche à la main.";
                _saisie = new EnregistrementLivre { Isbn = resultat.IsbnDemande };
                _etape = Etape.Formulaire;
                return;
            }

            if (_candidats.Count == 1)
            {
                Choisir(_candidats[0]);
                return;
            }

            _etape = Etape.Choix;
        }
        catch (Exception ex)
        {
            _erreur = $"La recherche a échoué : {ex.Message}";
        }
        finally
        {
            _chargement = false;
        }
    }

    private void Choisir(CandidatLivre candidat)
    {
        _saisie = new EnregistrementLivre
        {
            Isbn = _isbn.Trim(),
            Titre = candidat.Titre,
            Auteur = candidat.Auteur,
            Editeur = candidat.Editeur,
            CoverUrl = candidat.CoverUrl,
            Format = Format.Physique,
            Statut = Statut.ALire,
        };

        _erreur = null;
        _etape = Etape.Formulaire;
    }

    private void Recommencer()
    {
        _etape = Etape.Saisie;
        _erreur = null;
        _erreurFormulaire = null;
        _candidats = [];
    }

    private async Task EnregistrerAsync()
    {
        _enregistrement = true;
        _erreurFormulaire = null;

        var resultat = await Api.CreerAsync(_saisie);

        _enregistrement = false;

        if (!resultat.EstOk)
        {
            _erreurFormulaire = resultat.Erreur;
            return;
        }

        Navigation.NavigateTo("/");
    }
}
