"""Shared pytest fixtures."""

from __future__ import annotations

import json
from pathlib import Path

import pytest
import pytest_asyncio
from httpx import ASGITransport, AsyncClient
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine

from packages.db.models import Base
from packages.db.session import reset_engine
from packages.integrations.jira import JiraIssue, reset_mock_jira
from packages.integrations.git import reset_mock_git
from packages.integrations.confluence import reset_mock_confluence_publisher

FIXTURES = Path(__file__).parent / "fixtures" / "stories"


@pytest.fixture
def artifacts_tmpdir(tmp_path, monkeypatch):
    monkeypatch.setenv("ARTIFACTS_DIR", str(tmp_path / "artifacts"))
    monkeypatch.setenv("JIRA_PROVIDER", "mock")
    monkeypatch.setenv("LLM_PROVIDER", "mock")
    monkeypatch.setenv("CONFLUENCE_PROVIDER", "mock")
    monkeypatch.setenv("GIT_PROVIDER", "mock")
    monkeypatch.setenv("SALESFORCE_PROVIDER", "mock")
    monkeypatch.setenv("STATIC_ANALYSIS_PROVIDER", "mock")
    monkeypatch.setenv("APEX_TEST_PROVIDER", "mock")
    monkeypatch.setenv("MAX_REVIEW_CYCLES", "3")
    monkeypatch.setenv("JIRA_PROJECT_KEYS", "SALES")
    monkeypatch.setenv("JIRA_AGENT_LABEL", "agent-nova")
    monkeypatch.setenv("JIRA_AGENT_STATUS", "Ready for Agent")
    from packages.config import get_settings

    get_settings.cache_clear()
    return tmp_path / "artifacts"


@pytest_asyncio.fixture
async def db_session(artifacts_tmpdir):
    reset_engine()
    engine = create_async_engine("sqlite+aiosqlite:///:memory:")
    async with engine.begin() as conn:
        await conn.run_sync(Base.metadata.create_all)
    factory = async_sessionmaker(engine, expire_on_commit=False)
    async with factory() as session:
        yield session
    await engine.dispose()
    reset_engine()


@pytest.fixture
def mock_jira(artifacts_tmpdir):
    client = reset_mock_jira()
    reset_mock_git()
    reset_mock_confluence_publisher()
    return client


def load_story(key: str) -> JiraIssue:
    data = json.loads((FIXTURES / f"{key}.json").read_text(encoding="utf-8"))
    return JiraIssue(
        key=data["key"],
        summary=data["summary"],
        description=data["description"],
        status=data["status"],
        issue_type=data["issue_type"],
        labels=data.get("labels") or [],
        acceptance_criteria=data.get("acceptance_criteria") or [],
        comments=data.get("comments") or [],
        attachments=data.get("attachments") or [],
        project_key=data["key"].split("-")[0],
        assignee_account_id=data.get("assignee_account_id") or "",
        assignee_display_name=data.get("assignee_display_name") or "",
    )


@pytest_asyncio.fixture
async def api_client(db_session: AsyncSession, mock_jira, artifacts_tmpdir, monkeypatch):
    """ASGI client with DB dependency overridden; queue runs inline."""
    from apps.api.app import app
    from packages.db.session import get_db_session

    async def _override():
        yield db_session

    app.dependency_overrides[get_db_session] = _override

    async def _no_enqueue(*_a, **_k):
        raise RuntimeError("redis unavailable in tests")

    monkeypatch.setattr("apps.api.app.enqueue_process_run", _no_enqueue)
    app.router.on_startup.clear()

    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        yield client

    app.dependency_overrides.clear()
