import pytest
from django.contrib.auth import get_user_model

from boardgames.models import BoardGame, BoardGameVariant
from boardgames.utils import board_names_to_variants
from scrobbles.models import Scrobble

User = get_user_model()


@pytest.mark.django_db
def test_board_names_to_variants_creates_variant():
    game = BoardGame.objects.create(title="Test Game")
    ids = board_names_to_variants(game, ["Map A"])
    assert len(ids) == 1
    variant = BoardGameVariant.objects.get(id=ids[0])
    assert variant.name == "Map A"
    assert variant.board_game == game


@pytest.mark.django_db
def test_board_names_to_variants_reuses_existing():
    game = BoardGame.objects.create(title="Test Game")
    existing = BoardGameVariant.objects.create(
        name="Map A", board_game=game
    )
    ids = board_names_to_variants(game, ["Map A"])
    assert len(ids) == 1
    assert ids[0] == existing.id


@pytest.mark.django_db
def test_board_names_to_variants_multiple_names():
    game = BoardGame.objects.create(title="Test Game")
    ids = board_names_to_variants(game, ["Map A", "Map B"])
    assert len(ids) == 2
    names = set(BoardGameVariant.objects.filter(id__in=ids).values_list("name", flat=True))
    assert names == {"Map A", "Map B"}


@pytest.mark.django_db
def test_board_names_to_variants_splits_fullwidth_slash():
    game = BoardGame.objects.create(title="Test Game")
    ids = board_names_to_variants(game, ["Map A／Map B"])
    assert len(ids) == 2
    names = set(BoardGameVariant.objects.filter(id__in=ids).values_list("name", flat=True))
    assert names == {"Map A", "Map B"}


@pytest.mark.django_db
def test_board_names_to_variants_skips_empty_parts():
    game = BoardGame.objects.create(title="Test Game")
    ids = board_names_to_variants(game, ["／Map A／"])
    assert len(ids) == 1
    assert BoardGameVariant.objects.get(id=ids[0]).name == "Map A"


@pytest.mark.django_db
def test_board_names_to_variants_different_games_independent():
    game1 = BoardGame.objects.create(title="Game 1")
    game2 = BoardGame.objects.create(title="Game 2")
    ids1 = board_names_to_variants(game1, ["Map A"])
    ids2 = board_names_to_variants(game2, ["Map A"])
    assert ids1 != ids2
    assert BoardGameVariant.objects.count() == 2


@pytest.mark.django_db
def test_management_command_dry_run(capsys):
    from django.core.management import call_command

    game = BoardGame.objects.create(title="Test Game")
    user = User.objects.create(username="tester")
    scrobble = Scrobble.objects.create(
        user=user,
        board_game=game,
        log={"board": "Map A"},
    )

    call_command("convert_board_to_variants")
    captured = capsys.readouterr()
    assert "Would update 1 scrobbles" in captured.out

    scrobble.refresh_from_db()
    assert "board" in scrobble.log


@pytest.mark.django_db
def test_management_command_commit():
    from django.core.management import call_command

    game = BoardGame.objects.create(title="Test Game")
    user = User.objects.create(username="tester")
    scrobble = Scrobble.objects.create(
        user=user,
        board_game=game,
        log={"board": "Map A"},
    )

    call_command("convert_board_to_variants", commit=True)

    scrobble.refresh_from_db()
    assert "board" not in scrobble.log
    assert "variant_ids" in scrobble.log
    variant = BoardGameVariant.objects.get(board_game=game, name="Map A")
    assert variant.id in scrobble.log["variant_ids"]
