"""Tests for the /export slash command."""

from __future__ import annotations

from pathlib import Path

import pytest

from clients.terminal.tui.tui_app import NaviCodeTui


@pytest.fixture(autouse=True)
def tmp_state_dir(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Path:
    """Override the state dir so tests never touch ~/.navi_code."""
    from clients.terminal import config

    original = config.settings.state_dir
    config.settings.state_dir = tmp_path
    import clients.terminal.tui.settings as settings_module

    settings_module._tui_settings = None
    yield tmp_path
    config.settings.state_dir = original
    settings_module._tui_settings = None


@pytest.fixture
def fake_session(monkeypatch: pytest.MonkeyPatch) -> dict:
    """Return a fake session payload used to test export."""
    session_id = "sess-export-1234"

    def fake_get_session(sid: str) -> dict:
        if sid != session_id:
            raise Exception("not found")
        return {
            "session_id": session_id,
            "profile_id": "navi_code",
            "created_at": "2026-06-23T12:00:00",
            "messages": [
                {"role": "user", "content": "Hello Navi"},
                {"role": "assistant", "content": "Hello!"},
            ],
        }

    def fake_create_session(profile_id: str | None = None) -> dict:
        return {
            "session_id": session_id,
            "profile_id": profile_id or "navi_code",
        }

    def fake_list_sessions() -> list[dict]:
        return [fake_get_session(session_id)]

    monkeypatch.setattr("clients.terminal.api.get_session", fake_get_session)
    monkeypatch.setattr("clients.terminal.api.create_session", fake_create_session)
    monkeypatch.setattr("clients.terminal.api.list_sessions", fake_list_sessions)

    return fake_get_session(session_id)


@pytest.mark.anyio
async def test_export_command_writes_markdown(
    tmp_state_dir: Path, fake_session: dict, monkeypatch: pytest.MonkeyPatch
) -> None:
    """Running /export writes a markdown file and opens the editor."""
    opened_files: list[str] = []

    def fake_open_in_editor(path: str) -> None:
        opened_files.append(path)

    monkeypatch.setattr(
        "clients.terminal.tui.commands.builtin._open_in_editor", fake_open_in_editor
    )

    async with NaviCodeTui(new_session=True).run_test() as pilot:
        await pilot.pause()
        input_box = pilot.app.query_one("InputBox")
        input_box._input.text = "/export"
        await pilot.press("enter")
        await pilot.pause()

    export_dir = tmp_state_dir / "exports"
    assert export_dir.exists()
    files = list(export_dir.glob("*.md"))
    assert len(files) == 1
    content = files[0].read_text(encoding="utf-8")
    assert "# Navi Code Export" in content
    assert "Hello Navi" in content
    assert "Hello!" in content
    assert "navi_code" in content
    assert opened_files == [str(files[0])]


@pytest.mark.anyio
async def test_export_without_session_shows_error(
    tmp_state_dir: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
    """Running /export when there is no active session shows an error."""

    def fake_create_session(profile_id: str | None = None) -> dict:
        return {"session_id": "", "profile_id": profile_id or "navi_code"}

    def fake_get_session(sid: str) -> dict:
        raise Exception("not found")

    monkeypatch.setattr("clients.terminal.api.create_session", fake_create_session)
    monkeypatch.setattr("clients.terminal.api.get_session", fake_get_session)

    async with NaviCodeTui(new_session=True).run_test() as pilot:
        await pilot.pause()
        pilot.app._ctx.session_id = None
        input_box = pilot.app.query_one("InputBox")
        input_box._input.text = "/export"
        await pilot.press("enter")
        await pilot.pause()
        chat = pilot.app.query_one("ChatPanel")
        assert any(item.kind == "error" for item in chat._model.items)


@pytest.mark.anyio
async def test_export_editor_failure_shows_error(
    tmp_state_dir: Path, fake_session: dict, monkeypatch: pytest.MonkeyPatch
) -> None:
    """If the editor cannot be launched, /export reports the error."""

    def fake_open_in_editor(path: str) -> None:
        raise OSError("no such editor")

    monkeypatch.setattr(
        "clients.terminal.tui.commands.builtin._open_in_editor", fake_open_in_editor
    )

    async with NaviCodeTui(new_session=True).run_test() as pilot:
        await pilot.pause()
        input_box = pilot.app.query_one("InputBox")
        input_box._input.text = "/export"
        await pilot.press("enter")
        await pilot.pause()
        chat = pilot.app.query_one("ChatPanel")
        assert any(
            item.kind == "error" and "no such editor" in item.content for item in chat._model.items
        )
