using MaBibli.Shared.Isbn;

namespace MaBibli.Tests;

public class IsbnUtilsTests
{
    [Theory]
    [InlineData("978-2-253-00422-6", "9782253004226")]
    [InlineData(" 9782253004226 ", "9782253004226")]
    [InlineData("2-08-070409-5", "2080704095")]
    [InlineData("080442957x", "080442957X")]
    public void Normaliser_retire_la_ponctuation(string brut, string attendu)
        => Assert.Equal(attendu, IsbnUtils.Normaliser(brut));

    [Theory]
    [InlineData(null)]
    [InlineData("")]
    [InlineData("   ")]
    [InlineData("---")]
    public void Normaliser_renvoie_null_si_rien_dexploitable(string? brut)
        => Assert.Null(IsbnUtils.Normaliser(brut));

    // Les quatre ISBN de vérification du projet, plus un cas à clé X.
    [Theory]
    [InlineData("9782070612758", "2070612759")]  // Le Petit Prince
    [InlineData("9782253004226", "2253004227")]  // Germinal — valeur confirmée par la BnF
    [InlineData("9782080704092", "2080704095")]  // Le Horla — valeur confirmée par la BnF
    [InlineData("9780262033848", "0262033844")]  // Introduction to Algorithms
    public void Convertir_13_vers_10_donne_la_bonne_cle(string isbn13, string attendu)
    {
        Assert.True(IsbnUtils.TryConvertirEnIsbn10(isbn13, out var isbn10));
        Assert.Equal(attendu, isbn10);
    }

    [Theory]
    [InlineData("9780804429573", "080442957X")]  // clé = 10 → X
    [InlineData("9780000000064", "000000006X")]  // second cas à clé X, construit à la main
    public void Convertir_13_vers_10_produit_un_X_quand_la_cle_vaut_10(string isbn13, string attendu)
    {
        Assert.True(IsbnUtils.TryConvertirEnIsbn10(isbn13, out var isbn10));
        Assert.Equal(attendu, isbn10);
        Assert.True(IsbnUtils.EstIsbn10Valide(isbn10), "l'ISBN-10 produit doit être valide");
    }

    [Fact]
    public void Convertir_refuse_le_prefixe_979()
    {
        // 979 n'a aucun équivalent ISBN-10 : « convertir » y produirait un identifiant inventé.
        const string isbn13 = "9791023507027";
        Assert.True(IsbnUtils.EstIsbn13Valide(isbn13), "l'ISBN-13 de test doit être valide");
        Assert.False(IsbnUtils.TryConvertirEnIsbn10(isbn13, out var isbn10));
        Assert.Null(isbn10);
    }

    [Theory]
    [InlineData(null)]
    [InlineData("")]
    [InlineData("2253004227")]     // déjà un ISBN-10
    [InlineData("978225300422")]   // trop court
    [InlineData("9782253004227")]  // clé EAN-13 fausse
    public void Convertir_refuse_les_entrees_invalides(string? entree)
    {
        Assert.False(IsbnUtils.TryConvertirEnIsbn10(entree, out var isbn10));
        Assert.Null(isbn10);
    }

    [Theory]
    [InlineData("2253004227", true)]
    [InlineData("2080704095", true)]
    [InlineData("080442957X", true)]
    [InlineData("2253004228", false)]  // clé fausse
    [InlineData("22530042X7", false)]  // X ailleurs qu'en clé
    [InlineData("225300422", false)]   // trop court
    public void EstIsbn10Valide(string isbn, bool attendu)
        => Assert.Equal(attendu, IsbnUtils.EstIsbn10Valide(isbn));

    [Theory]
    [InlineData("9782253004226", true)]
    [InlineData("9782070612758", true)]
    [InlineData("9782253004225", false)]  // clé fausse
    [InlineData("978225300422X", false)]  // pas de X en ISBN-13
    public void EstIsbn13Valide(string isbn, bool attendu)
        => Assert.Equal(attendu, IsbnUtils.EstIsbn13Valide(isbn));

    [Fact]
    public void UrlCouverture_porte_toujours_default_false()
    {
        // Sans ?default=false, OpenLibrary renvoie un placeholder au lieu d'un 404 :
        // on afficherait des couvertures vides sans le savoir.
        var url = IsbnUtils.UrlCouverture("9782253004226");
        Assert.Equal("https://covers.openlibrary.org/b/isbn/9782253004226-L.jpg?default=false", url);
    }
}
