"""Tests for initiative module: active initiative, specs, creation, paths."""

import textwrap
from pathlib import Path

import pytest

import initiative


def _initiative_with_spec(project_dir: Path, name: str, spec: str = "Spec body.") -> Path:
    init_dir = project_dir / ".autobuilder" / "initiatives" / name
    init_dir.mkdir(parents=True)
    (init_dir / "spec.md").write_text(spec + "\n", encoding="utf-8")
    (init_dir / "tasks").mkdir(exist_ok=True)
    return init_dir


# ═══════════════════════════════════════════════════════════════════════════
# read_active_initiative
# ═══════════════════════════════════════════════════════════════════════════


def test_read_active_initiative_none(tmp_path: Path):
    project_dir = tmp_path / "proj"
    (project_dir / ".autobuilder").mkdir(parents=True)
    assert initiative.read_active_initiative(project_dir) is None


def test_read_active_initiative_valid(tmp_path: Path):
    project_dir = tmp_path / "proj"
    _initiative_with_spec(project_dir, "0001-my-app", "# Title\n")
    active = project_dir / ".autobuilder" / "active-initiative"
    active.write_text("0001-my-app\n", encoding="utf-8")
    assert initiative.read_active_initiative(project_dir) == "0001-my-app"


def test_read_active_initiative_invalid_dir(tmp_path: Path):
    project_dir = tmp_path / "proj"
    (project_dir / ".autobuilder").mkdir(parents=True)
    active = project_dir / ".autobuilder" / "active-initiative"
    active.write_text("9999-missing\n", encoding="utf-8")
    assert initiative.read_active_initiative(project_dir) is None


# ═══════════════════════════════════════════════════════════════════════════
# resolve_active_initiative
# ═══════════════════════════════════════════════════════════════════════════


def test_resolve_active_initiative_fallback(tmp_path: Path):
    project_dir = tmp_path / "proj"
    _initiative_with_spec(project_dir, "0001-first", "A")
    assert initiative.read_active_initiative(project_dir) is None
    resolved = initiative.resolve_active_initiative(project_dir)
    assert resolved == "0001-first"
    assert initiative.read_active_initiative(project_dir) == "0001-first"


# ═══════════════════════════════════════════════════════════════════════════
# get_initiative_spec / constraints
# ═══════════════════════════════════════════════════════════════════════════


def test_get_initiative_spec(tmp_path: Path):
    project_dir = tmp_path / "proj"
    body = "# My product\n\nDetails here."
    _initiative_with_spec(project_dir, "0001-x", body)
    assert initiative.get_initiative_spec(project_dir, "0001-x").strip() == body.strip()


def test_get_initiative_constraints(tmp_path: Path):
    project_dir = tmp_path / "proj"
    init_dir = _initiative_with_spec(project_dir, "0001-x", "S")
    (init_dir / "constraints.md").write_text("Only REST.\n", encoding="utf-8")
    assert "REST" in initiative.get_initiative_constraints(project_dir, "0001-x")


# ═══════════════════════════════════════════════════════════════════════════
# has_tasks
# ═══════════════════════════════════════════════════════════════════════════


def test_has_tasks_empty(tmp_path: Path):
    project_dir = tmp_path / "proj"
    _initiative_with_spec(project_dir, "0001-x", "S")
    assert initiative.has_tasks(project_dir, "0001-x") is False


def test_has_tasks_with_files(tmp_path: Path):
    project_dir = tmp_path / "proj"
    init_dir = _initiative_with_spec(project_dir, "0001-x", "S")
    (init_dir / "tasks" / "0001-t.md").write_text("---\nid: t\n---\n", encoding="utf-8")
    assert initiative.has_tasks(project_dir, "0001-x") is True


# ═══════════════════════════════════════════════════════════════════════════
# create_root_task_from_spec
# ═══════════════════════════════════════════════════════════════════════════


def test_create_root_task_from_spec(tmp_path: Path):
    project_dir = tmp_path / "proj"
    spec = textwrap.dedent("""\
        # Dashboard MVP

        Build charts.
    """)
    _initiative_with_spec(project_dir, "0001-dashboard", spec)
    path = initiative.create_root_task_from_spec(
        project_dir, "0001-dashboard", root_id="myapp",
    )
    assert path is not None
    assert path.exists()
    text = path.read_text(encoding="utf-8")
    assert "id: dashboard-root" in text
    assert "parent: myapp" in text
    assert "Dashboard MVP" in text


def test_create_root_task_no_spec(tmp_path: Path):
    project_dir = tmp_path / "proj"
    init_dir = project_dir / ".autobuilder" / "initiatives" / "0001-empty"
    init_dir.mkdir(parents=True)
    (init_dir / "spec.md").write_text("", encoding="utf-8")
    (init_dir / "tasks").mkdir(exist_ok=True)
    assert initiative.create_root_task_from_spec(
        project_dir, "0001-empty", root_id="r",
    ) is None


# ═══════════════════════════════════════════════════════════════════════════
# set_active_initiative
# ═══════════════════════════════════════════════════════════════════════════


def test_set_active_initiative(tmp_path: Path):
    project_dir = tmp_path / "proj"
    (project_dir / ".autobuilder").mkdir(parents=True)
    initiative.set_active_initiative(project_dir, "0001-a")
    p = project_dir / ".autobuilder" / "active-initiative"
    assert p.read_text().strip() == "0001-a"
    initiative.set_active_initiative(project_dir, None)
    assert not p.exists()


# ═══════════════════════════════════════════════════════════════════════════
# list / create / numbering / slug
# ═══════════════════════════════════════════════════════════════════════════


def test_list_initiatives(tmp_path: Path):
    project_dir = tmp_path / "proj"
    _initiative_with_spec(project_dir, "0001-a", "A")
    _initiative_with_spec(project_dir, "0002-b", "B")
    listed = initiative.list_initiatives(project_dir)
    names = [x[0] for x in listed]
    assert "0001-a" in names
    assert "0002-b" in names


def test_create_initiative(tmp_path: Path):
    project_dir = tmp_path / "proj"
    (project_dir / ".autobuilder" / "initiatives").mkdir(parents=True)
    name = initiative.create_initiative(project_dir, "feature-x", "Spec here.")
    assert name.startswith("0001-")
    init_dir = project_dir / ".autobuilder" / "initiatives" / name
    assert (init_dir / "spec.md").exists()
    assert (init_dir / "tasks").is_dir()


def test_initiative_numbering(tmp_path: Path):
    project_dir = tmp_path / "proj"
    (project_dir / ".autobuilder" / "initiatives").mkdir(parents=True)
    n1 = initiative.create_initiative(project_dir, "a", "S1")
    n2 = initiative.create_initiative(project_dir, "b", "S2")
    assert int(n1.split("-")[0]) < int(n2.split("-")[0])


def test_initiative_slug():
    assert initiative.initiative_slug("0007-my-feature") == "my-feature"
    assert initiative.initiative_slug("no-prefix") == "no-prefix"


# ═══════════════════════════════════════════════════════════════════════════
# get_initiative_tasks_dir
# ═══════════════════════════════════════════════════════════════════════════


def test_get_initiative_tasks_dir(tmp_path: Path):
    project_dir = tmp_path / "proj"
    expected = (
        project_dir / ".autobuilder" / "initiatives" / "0001-app" / "tasks"
    )
    assert initiative.get_initiative_tasks_dir(project_dir, "0001-app") == expected
