"""Tests for the project management router."""

from pathlib import Path
from unittest.mock import patch

import pytest
from fastapi.testclient import TestClient

from hangar.main import app

client = TestClient(app)


def test_get_current_project() -> None:
    """GET /api/project/current should return current project info."""
    with patch("hangar.routers.project.get_project_path") as mock_path:
        mock_path.return_value = Path("/home/user/my-project")
        resp = client.get("/api/project/current")

    assert resp.status_code == 200
    data = resp.json()
    assert data["name"] == "my-project"
    assert data["path"] == "/home/user/my-project"


def test_open_project_success(tmp_path: Path) -> None:
    """POST /api/project/open should switch to a fully initialized project."""
    (tmp_path / ".beads").mkdir()
    target = str(tmp_path)

    # Mock init status to report ready (avoids needing full init setup)
    ready_status = {"checks": [], "plan": [], "ready": True}
    with (
        patch("hangar.routers.project.set_project_path") as mock_set,
        patch("hangar.routers.project.detect_full_init_status", return_value=ready_status),
    ):
        resp = client.post("/api/project/open", json={"path": target})

    assert resp.status_code == 200
    data = resp.json()
    assert data["status"] == "ok"
    assert data["project"]["name"] == tmp_path.name
    assert data["project"]["path"] == str(tmp_path.resolve())
    mock_set.assert_called_once_with(tmp_path.resolve())


def test_open_project_with_openspec(tmp_path: Path) -> None:
    """POST /api/project/open should accept fully initialized projects."""
    (tmp_path / "openspec").mkdir()
    target = str(tmp_path)

    ready_status = {"checks": [], "plan": [], "ready": True}
    with (
        patch("hangar.routers.project.set_project_path"),
        patch("hangar.routers.project.detect_full_init_status", return_value=ready_status),
    ):
        resp = client.post("/api/project/open", json={"path": target})

    assert resp.status_code == 200
    assert resp.json()["status"] == "ok"


def test_open_project_not_found() -> None:
    """POST /api/project/open should return 404 for missing directory."""
    resp = client.post("/api/project/open", json={"path": "/nonexistent/path"})
    assert resp.status_code == 404
    assert "not found" in resp.json()["detail"].lower()


def test_open_project_not_initialized(tmp_path: Path) -> None:
    """POST /api/project/open should return 409 for uninitialized directories."""
    target = str(tmp_path)
    resp = client.post("/api/project/open", json={"path": target})
    assert resp.status_code == 409
    assert "not initialized" in resp.json()["detail"].lower()


def test_open_project_force(tmp_path: Path) -> None:
    """POST /api/project/open with force=true should bypass init check."""
    target = str(tmp_path)

    with patch("hangar.routers.project.set_project_path") as mock_set:
        resp = client.post("/api/project/open", json={"path": target, "force": True})

    assert resp.status_code == 200
    data = resp.json()
    assert data["status"] == "ok"
    assert data["project"]["name"] == tmp_path.name
    mock_set.assert_called_once_with(tmp_path.resolve())


def test_init_status(tmp_path: Path) -> None:
    """GET /api/project/init-status should return checklist for a directory."""
    resp = client.get("/api/project/init-status", params={"path": str(tmp_path)})
    assert resp.status_code == 200
    data = resp.json()
    assert data["path"] == str(tmp_path.resolve())
    assert isinstance(data["checks"], list)
    assert len(data["checks"]) == 5  # git, openspec, beads, skills, agents_md
    assert data["ready"] is False  # empty dir is not ready
    assert len(data["plan"]) > 0


def test_init_status_not_found() -> None:
    """GET /api/project/init-status should return 404 for missing directory."""
    resp = client.get("/api/project/init-status", params={"path": "/nonexistent/path"})
    assert resp.status_code == 404


def test_init_project(tmp_path: Path) -> None:
    """POST /api/project/init should initialize a project directory."""
    with patch("hangar.routers.project.set_project_path"):
        resp = client.post("/api/project/init", json={"path": str(tmp_path)})

    assert resp.status_code == 200
    data = resp.json()
    assert data["status"] == "ok"
    assert len(data["steps"]) > 0
    assert all(s["ok"] for s in data["steps"])
    assert data["project"]["name"] == tmp_path.name

    # Verify artifacts were created
    assert (tmp_path / ".git").is_dir()
    assert (tmp_path / "AGENTS.md").is_file()
    assert (tmp_path / ".claude" / "skills" / "openspec" / "SKILL.md").is_file()
    assert (tmp_path / ".claude" / "skills" / "beads" / "SKILL.md").is_file()


def test_init_project_not_found() -> None:
    """POST /api/project/init should return 404 for missing directory."""
    resp = client.post("/api/project/init", json={"path": "/nonexistent/path"})
    assert resp.status_code == 404
