"""Tests for the repository layer."""

from __future__ import annotations

from pathlib import Path

from conftest import init_test_db
from database.models import TrackStatus
from database.repositories import (
    DEFAULT_PROJECT_NAME,
    ProjectRepository,
    TrackRepository,
)


def test_get_default_project_creates_if_missing(tmp_path: Path) -> None:
    """Verify that get_default_project creates a project when none exists."""
    session = init_test_db(tmp_path)
    try:
        project = ProjectRepository.get_default_project(session)
        assert project is not None
        assert project.name == DEFAULT_PROJECT_NAME
    finally:
        session.close()


def test_get_default_project_is_idempotent(tmp_path: Path) -> None:
    """Verify that calling get_default_project twice returns the same project."""
    session = init_test_db(tmp_path)
    try:
        project1 = ProjectRepository.get_default_project(session)
        project2 = ProjectRepository.get_default_project(session)
        assert project1.id == project2.id
    finally:
        session.close()


def test_create_track(tmp_path: Path) -> None:
    """Verify that a track can be created and persisted."""
    session = init_test_db(tmp_path)
    try:
        project = ProjectRepository.get_default_project(session)
        track = TrackRepository.create_track(
            session,
            project_id=project.id,
            relative_path="song.wav",
            original_filename="song.wav",
            sha256="abc123",
            file_size=1024,
        )
        assert track.id is not None
        assert track.relative_path == "song.wav"
        assert track.status == TrackStatus.ACTIVE
    finally:
        session.close()


def test_find_by_path(tmp_path: Path) -> None:
    """Verify that find_by_path returns the correct track."""
    session = init_test_db(tmp_path)
    try:
        project = ProjectRepository.get_default_project(session)
        TrackRepository.create_track(
            session,
            project_id=project.id,
            relative_path="album/song.wav",
            original_filename="song.wav",
            sha256="hash1",
            file_size=100,
        )

        found = TrackRepository.find_by_path(session, "album/song.wav")
        assert found is not None
        assert found.sha256 == "hash1"

        not_found = TrackRepository.find_by_path(session, "nonexistent.wav")
        assert not_found is None
    finally:
        session.close()


def test_find_by_sha256(tmp_path: Path) -> None:
    """Verify that find_by_sha256 returns the correct tracks."""
    session = init_test_db(tmp_path)
    try:
        project = ProjectRepository.get_default_project(session)
        TrackRepository.create_track(
            session,
            project_id=project.id,
            relative_path="song.wav",
            original_filename="song.wav",
            sha256="unique_hash",
            file_size=100,
        )

        found = TrackRepository.find_by_sha256(session, "unique_hash")
        assert len(found) == 1
        assert found[0].relative_path == "song.wav"

        not_found = TrackRepository.find_by_sha256(session, "no_such_hash")
        assert len(not_found) == 0
    finally:
        session.close()


def test_list_tracks(tmp_path: Path) -> None:
    """Verify that list_tracks returns all tracks for a project."""
    session = init_test_db(tmp_path)
    try:
        project = ProjectRepository.get_default_project(session)
        TrackRepository.create_track(
            session,
            project_id=project.id,
            relative_path="a.wav",
            original_filename="a.wav",
            sha256="h1",
            file_size=100,
        )
        TrackRepository.create_track(
            session,
            project_id=project.id,
            relative_path="b.wav",
            original_filename="b.wav",
            sha256="h2",
            file_size=200,
        )

        tracks = TrackRepository.list_tracks(session, project.id)
        assert len(tracks) == 2
    finally:
        session.close()


def test_mark_as_missing(tmp_path: Path) -> None:
    """Verify that mark_as_missing sets the track status to MISSING."""
    session = init_test_db(tmp_path)
    try:
        project = ProjectRepository.get_default_project(session)
        track = TrackRepository.create_track(
            session,
            project_id=project.id,
            relative_path="song.wav",
            original_filename="song.wav",
            sha256="h1",
            file_size=100,
        )

        assert track.status == TrackStatus.ACTIVE
        TrackRepository.mark_as_missing(session, track)
        assert track.status == TrackStatus.MISSING
    finally:
        session.close()
