from datetime import date

from click.testing import CliRunner

from fx_alfred.cli import cli


def test_index_handles_multiple_prefixes(tmp_path, monkeypatch):
    rules_dir = tmp_path / "rules"
    rules_dir.mkdir()
    (rules_dir / "ALF-2100-SOP-Something.md").write_text("# ALF doc")
    (rules_dir / "NRV-2200-SOP-Other.md").write_text("# NRV doc")
    monkeypatch.chdir(tmp_path)
    runner = CliRunner()
    result = runner.invoke(cli, ["index"], catch_exceptions=False)
    assert result.exit_code == 0
    alf_index = rules_dir / "ALF-0000-REF-Document-Index.md"
    nrv_index = rules_dir / "NRV-0000-REF-Document-Index.md"
    assert alf_index.exists()
    assert nrv_index.exists()
    assert "2100" in alf_index.read_text()
    assert "2200" in nrv_index.read_text()


def test_index_only_indexes_prj_layer(sample_project, monkeypatch):
    """Index command only indexes PRJ layer documents."""
    monkeypatch.chdir(sample_project)
    runner = CliRunner()
    result = runner.invoke(cli, ["index"], catch_exceptions=False)
    assert result.exit_code == 0
    # Check that index was created in rules/ for ALF prefix
    doc_indexes = list((sample_project / "rules").glob("*-0000-REF-*.md"))
    assert len(doc_indexes) == 1
    content = doc_indexes[0].read_text()
    assert "2201" in content
    assert "2202" in content


def test_index_empty_project(tmp_path, monkeypatch):
    """Index command handles empty project."""
    monkeypatch.chdir(tmp_path)
    runner = CliRunner()
    result = runner.invoke(cli, ["index"], catch_exceptions=False)
    assert result.exit_code == 0
    assert "No PRJ documents" in result.output


def test_index_with_root_option(tmp_path):
    rules_dir = tmp_path / "rules"
    rules_dir.mkdir()
    (rules_dir / "TST-2100-SOP-Something.md").write_text("# test")
    runner = CliRunner()
    result = runner.invoke(
        cli, ["--root", str(tmp_path), "index"], catch_exceptions=False
    )
    assert result.exit_code == 0
    assert (rules_dir / "TST-0000-REF-Document-Index.md").exists()


def test_index_with_root_after_subcommand(tmp_path):
    rules_dir = tmp_path / "rules"
    rules_dir.mkdir()
    (rules_dir / "TST-2100-SOP-Something.md").write_text("# test")
    runner = CliRunner()
    result = runner.invoke(
        cli, ["index", "--root", str(tmp_path)], catch_exceptions=False
    )
    assert result.exit_code == 0
    assert (rules_dir / "TST-0000-REF-Document-Index.md").exists()


# --- Part A: Document Format Contract compliance tests ---


def _get_index_content(tmp_path) -> str:
    """Helper: create a project with one doc, run index, return index content."""
    rules_dir = tmp_path / "rules"
    rules_dir.mkdir(exist_ok=True)
    (rules_dir / "TST-2100-SOP-Something.md").write_text("# test")
    runner = CliRunner()
    runner.invoke(cli, ["index", "--root", str(tmp_path)], catch_exceptions=False)
    return (rules_dir / "TST-0000-REF-Document-Index.md").read_text()


def test_index_h1_format(tmp_path):
    """Generated index has compliant H1: # REF-0000: Document Index."""
    content = _get_index_content(tmp_path)
    assert content.startswith("# REF-0000: Document Index\n")


def test_index_has_applies_to(tmp_path):
    """Generated index has **Applies to:** field with correct prefix."""
    content = _get_index_content(tmp_path)
    assert "**Applies to:** TST project" in content


def test_index_has_last_updated(tmp_path):
    """Generated index has **Last updated:** field with today's date."""
    content = _get_index_content(tmp_path)
    today = date.today().isoformat()
    assert f"**Last updated:** {today}" in content


def test_index_has_last_reviewed(tmp_path):
    """Generated index has **Last reviewed:** field with today's date."""
    content = _get_index_content(tmp_path)
    today = date.today().isoformat()
    assert f"**Last reviewed:** {today}" in content


def test_index_has_status_active(tmp_path):
    """Generated index has **Status:** Active."""
    content = _get_index_content(tmp_path)
    assert "**Status:** Active" in content


def test_index_has_change_history(tmp_path):
    """Generated index has ## Change History section with table."""
    content = _get_index_content(tmp_path)
    assert "## Change History" in content
    assert "| Date | Change | By |" in content
    assert "Auto-generated by af index" in content


def test_index_has_separator_before_table(tmp_path):
    """Generated index has --- separator between metadata and body."""
    content = _get_index_content(tmp_path)
    lines = content.split("\n")
    # There should be a --- after metadata, before the table
    sep_indices = [i for i, line in enumerate(lines) if line.strip() == "---"]
    assert len(sep_indices) >= 1, "Expected at least one --- separator"


def test_index_passes_validate(tmp_path):
    """Generated index passes af validate (no issues for the index doc)."""
    _get_index_content(tmp_path)
    runner = CliRunner()
    result = runner.invoke(
        cli, ["validate", "--root", str(tmp_path)], catch_exceptions=False
    )
    # Index docs (ACID=0000) should not produce any issues
    assert "TST-0000" not in result.output or "0 issues" in result.output


def test_index_multiple_prefixes_compliant(tmp_path):
    """Generated indexes for multiple prefixes are all compliant."""
    rules_dir = tmp_path / "rules"
    rules_dir.mkdir()
    (rules_dir / "ALF-2100-SOP-Something.md").write_text("# ALF doc")
    (rules_dir / "NRV-2200-SOP-Other.md").write_text("# NRV doc")
    runner = CliRunner()
    runner.invoke(cli, ["index", "--root", str(tmp_path)], catch_exceptions=False)
    alf_content = (rules_dir / "ALF-0000-REF-Document-Index.md").read_text()
    nrv_content = (rules_dir / "NRV-0000-REF-Document-Index.md").read_text()
    assert "**Applies to:** ALF project" in alf_content
    assert "**Applies to:** NRV project" in nrv_content
    assert alf_content.startswith("# REF-0000: Document Index\n")
    assert nrv_content.startswith("# REF-0000: Document Index\n")
