import pytest
from app import db


@pytest.fixture
def fresh_db(monkeypatch, tmp_path):
    monkeypatch.setattr(db, "DB_PATH", str(tmp_path / "music.db"))
    db.init_db()
    return db


def test_create_batch_job(fresh_db):
    bid = db.create_batch_job(genre="lo-fi", count=10)
    j = db.get_batch_job(bid)
    assert j["genre"] == "lo-fi"
    assert j["count"] == 10
    assert j["status"] == "queued"
    assert j["track_ids"] == []
    assert j["auto_pipeline"] == 1
    assert j["target_duration_sec"] == 180


def test_create_batch_job_no_auto_pipeline(fresh_db):
    bid = db.create_batch_job(genre="phonk", count=5, auto_pipeline=False)
    j = db.get_batch_job(bid)
    assert j["auto_pipeline"] == 0


def test_update_batch_job(fresh_db):
    bid = db.create_batch_job(genre="phonk", count=5)
    db.update_batch_job(bid, status="generating", current_track_index=2)
    j = db.get_batch_job(bid)
    assert j["status"] == "generating"
    assert j["current_track_index"] == 2


def test_update_batch_rejects_unknown_col(fresh_db):
    bid = db.create_batch_job(genre="lo-fi", count=1)
    with pytest.raises(ValueError):
        db.update_batch_job(bid, evil_col="x")


def test_append_batch_track(fresh_db):
    bid = db.create_batch_job(genre="lo-fi", count=3)
    db.append_batch_track(bid, 101)
    db.append_batch_track(bid, 102)
    j = db.get_batch_job(bid)
    assert j["track_ids"] == [101, 102]
    assert j["completed"] == 2


def test_list_batch_jobs_active_filter(fresh_db):
    b1 = db.create_batch_job(genre="lo-fi", count=1)
    b2 = db.create_batch_job(genre="phonk", count=1)
    db.update_batch_job(b1, status="failed")
    actives = db.list_batch_jobs(active_only=True)
    assert all(j["status"] not in ("failed",) for j in actives)
    assert any(j["id"] == b2 for j in actives)
    assert not any(j["id"] == b1 for j in actives)


def test_random_pools_lofi():
    from app.random_pools import randomize, POOLS
    import random
    rng = random.Random(42)
    result = randomize("lo-fi", rng)
    assert result["bpm"] in range(70, 91)
    assert result["key"] in POOLS["lo-fi"]["keys"]
    assert result["scale"] in POOLS["lo-fi"]["scales"]
    assert len(result["moods"]) == 1
    assert result["moods"][0] in POOLS["lo-fi"]["moods"]
    assert 3 <= len(result["instruments"]) <= 4


def test_random_pools_phonk():
    from app.random_pools import randomize
    import random
    rng = random.Random(0)
    result = randomize("phonk", rng)
    assert result["bpm"] in range(130, 161)
    assert result["scale"] == "minor"


def test_random_pools_unknown_genre_uses_default():
    from app.random_pools import randomize
    import random
    result = randomize("nonexistent", random.Random(0))
    assert result["bpm"] in range(80, 111)


def test_random_pools_seed_reproducible():
    from app.random_pools import randomize
    import random
    a = randomize("lo-fi", random.Random(123))
    b = randomize("lo-fi", random.Random(123))
    assert a == b
