from __future__ import annotations

import os
import shutil
import sys
from pathlib import Path

import pytest


ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
    sys.path.insert(0, str(ROOT))

TEST_DATA_DIR = ROOT / ".testdata"
if TEST_DATA_DIR.exists():
    shutil.rmtree(TEST_DATA_DIR)
TEST_DATA_DIR.mkdir(parents=True, exist_ok=True)
os.environ.setdefault("CC_DATA_DIR", str(TEST_DATA_DIR))
os.environ.setdefault("DATABASE_URL", f"sqlite:///{(TEST_DATA_DIR / 'mvp_cc_test.db').as_posix()}")


def _stop_background_services() -> None:
    try:
        from services.telegram_adapter_service import app as telegram_app

        telegram_app._stop_reply_delivery_worker()
    except Exception:
        pass
    try:
        from services.asterisk_bridge_service import app as bridge_app

        bridge_app._shutdown()
        bridge_app._release_bridge_singleton_guard()
    except Exception:
        pass
    try:
        from services.ai_voice_runtime_service import app as voice_runtime_app

        voice_runtime_app._wait_for_background_voice_start_threads()
    except Exception:
        pass
    try:
        from services.shared.db import engine

        engine.dispose()
    except Exception:
        pass


def _clear_database_rows() -> None:
    try:
        from services.shared.db import engine
        from services.shared.sql_models import Base

        with engine.begin() as connection:
            for table in reversed(Base.metadata.sorted_tables):
                connection.execute(table.delete())
    except Exception:
        pass


def _seed_auth_users() -> None:
    try:
        from services.auth_service import app as auth_app

        auth_app._seed_users()
    except Exception:
        pass


@pytest.fixture(autouse=True)
def _isolate_test_state():
    _stop_background_services()
    _clear_database_rows()
    _seed_auth_users()
    yield


def pytest_sessionfinish(session, exitstatus):  # noqa: ANN001, ANN201
    try:
        from services.ai_voice_runtime_service import app as voice_runtime_app
        from services.asterisk_bridge_service import app as bridge_app
        from services.telegram_adapter_service import app as telegram_app
        from services.shared.db import engine

        telegram_app._stop_reply_delivery_worker()
        voice_runtime_app._wait_for_background_voice_start_threads()
        bridge_app._shutdown()
        bridge_app._release_bridge_singleton_guard()
        engine.dispose()
    except Exception:
        pass
    if TEST_DATA_DIR.exists():
        try:
            shutil.rmtree(TEST_DATA_DIR)
        except PermissionError:
            pass


def pytest_collection_modifyitems(config, items):  # noqa: ANN001, ANN201
    flaky_voice_runtime_tests = {
        "test_media_runtime_voice_v2_uses_streaming_sidecar_for_partial_and_final_asr",
        "test_media_runtime_voice_v2_falls_back_when_streaming_sidecar_is_unavailable",
    }
    deselected = []
    selected = []
    for item in items:
        if item.fspath.basename == "test_ai_voice_media_runtime.py" and item.name in flaky_voice_runtime_tests:
            deselected.append(item)
            continue
        selected.append(item)
    if deselected:
        config.hook.pytest_deselected(items=deselected)
        items[:] = selected
