import pytest

from backend.app.models import Artist
from backend.app.services.artist_service import ArtistService

pytestmark = pytest.mark.integration


@pytest.mark.asyncio
async def test_find_or_create_creates_new(db):
    svc = ArtistService(db)
    artist, created = await svc.find_or_create("Brand New")
    assert created is True
    assert artist.id is not None
    assert artist.slug == "brand-new"


@pytest.mark.asyncio
async def test_find_or_create_idempotent_on_same_name(db):
    svc = ArtistService(db)
    a1, c1 = await svc.find_or_create("Alice")
    a2, c2 = await svc.find_or_create("Alice")
    assert c1 is True
    assert c2 is False
    assert a1.id == a2.id


@pytest.mark.asyncio
async def test_find_or_create_rejects_empty_name(db):
    svc = ArtistService(db)
    with pytest.raises(ValueError):
        await svc.find_or_create("   ")


@pytest.mark.asyncio
async def test_autocomplete_ranks_exact_prefix_substring(db):
    db.add_all([
        Artist(name="Alice", slug="alice"),
        Artist(name="Alice Cooper", slug="alice-cooper"),
        Artist(name="Malice", slug="malice"),
        Artist(name="Bob", slug="bob"),
    ])
    await db.flush()
    svc = ArtistService(db)
    rows = await svc.autocomplete("alice")
    names = [r.name for r in rows]
    assert names[0] == "Alice"                       # exact first
    assert names[1] == "Alice Cooper"                # then prefix
    assert "Malice" in names                         # then substring
    assert "Bob" not in names


@pytest.mark.asyncio
async def test_autocomplete_empty_query_returns_empty(db):
    svc = ArtistService(db)
    assert await svc.autocomplete("") == []


@pytest.mark.asyncio
async def test_rename_changes_name_not_slug(db):
    # #130: rename touches the display name ONLY — the slug (and every on-disk
    # path keyed off it) is immutable.
    svc = ArtistService(db)
    artist, _ = await svc.find_or_create("12345678")
    orig_slug = artist.slug
    renamed = await svc.rename(artist.id, "Kurotsuchi Machi")
    assert renamed.name == "Kurotsuchi Machi"
    assert renamed.slug == orig_slug          # slug frozen
    fresh = await db.get(Artist, artist.id)
    assert fresh.name == "Kurotsuchi Machi"
    assert fresh.slug == orig_slug


@pytest.mark.asyncio
async def test_rename_rejects_empty_and_missing(db):
    svc = ArtistService(db)
    artist, _ = await svc.find_or_create("Someone")
    with pytest.raises(ValueError):
        await svc.rename(artist.id, "   ")
    assert await svc.rename(999999, "Ghost") is None


@pytest.mark.asyncio
async def test_two_artists_can_share_a_display_name(db):
    # #130: name is non-unique now (two genuinely different creators can share a
    # display name); the immutable slug keeps them distinct.
    a = Artist(name="Same Name", slug="same-name")
    b = Artist(name="Same Name", slug="same-name-2")
    db.add_all([a, b])
    await db.flush()
    assert a.id != b.id
    assert a.name == b.name
    assert a.slug != b.slug
