"""CLI entry point — typer app wiring all commands together."""

from __future__ import annotations

from pathlib import Path
from typing import Optional

import typer

app = typer.Typer(
    name="atlasmemory",
    help="Persistent shared knowledge layer for AI coding agents.",
    no_args_is_help=True,
)
systems_app = typer.Typer(help="Manage system documentation.")
app.add_typer(systems_app, name="systems")


# ── init ──────────────────────────────────────────────────────────────

@app.command()
def init(
    project: Optional[str] = typer.Option(None, help="Project name (auto-detected if omitted)"),
    me: Optional[str] = typer.Option(None, help="Your name/id for .me identity"),
    platform: Optional[str] = typer.Option(None, help="Agent platform: claude-code, cursor, aider, none"),
    tracker: Optional[str] = typer.Option(None, help="Issue tracker: beads, linear, github, jira, none"),
    obsidian: bool = typer.Option(False, help="Generate Obsidian config"),
    auto_discover: bool = typer.Option(False, "--auto-discover", help="Auto-discover systems from codebase"),
) -> None:
    """Initialize .memory/ in the current project."""
    from supermemory.init import init_project

    # Interactive prompts for missing required values
    if me is None:
        me = typer.prompt("Your name/id", default="")
        if not me:
            me = None

    root = init_project(
        project=project,
        me=me,
        platform=platform,
        tracker=tracker,
        obsidian=obsidian,
        auto_discover=auto_discover,
    )
    typer.echo(f"Initialized .memory/ at {root}")

    if auto_discover:
        from supermemory.discover import discover_systems
        systems = [f.stem for f in (root / "systems").glob("*.md") if not f.name.startswith("_")]
        if systems:
            typer.echo(f"Discovered systems: {', '.join(systems)}")


# ── whoami ────────────────────────────────────────────────────────────

@app.command()
def whoami(
    name: Optional[str] = typer.Argument(None, help="Set identity (omit to show current)"),
) -> None:
    """Show or set the current .me identity."""
    from supermemory.config import get_current_user, memory_root

    root = memory_root()
    if name:
        (root / ".me").write_text(name + "\n")
        typer.echo(f"Identity set to: {name}")
    else:
        user = get_current_user(root)
        if user:
            typer.echo(user)
        else:
            typer.echo("No identity set. Run: atlasmemory whoami <name>")
            raise typer.Exit(1)


# ── systems ───────────────────────────────────────────────────────────

@systems_app.callback(invoke_without_command=True)
def systems_list(ctx: typer.Context) -> None:
    """List all system docs."""
    if ctx.invoked_subcommand is not None:
        return

    from supermemory.config import memory_root

    root = memory_root()
    systems_dir = root / "systems"
    if not systems_dir.is_dir():
        typer.echo("No systems/ directory. Run `atlasmemory init` first.")
        raise typer.Exit(1)

    docs = sorted(f for f in systems_dir.glob("*.md") if not f.name.startswith("_"))
    if not docs:
        typer.echo("No system docs found. Run `atlasmemory systems discover`.")
        return

    for doc in docs:
        typer.echo(f"  {doc.stem}")


@systems_app.command()
def discover() -> None:
    """Re-scan codebase and create new system docs."""
    from supermemory.config import memory_root
    from supermemory.discover import discover_systems

    root = memory_root()
    found = discover_systems(root, root.parent)
    if found:
        typer.echo(f"Discovered {len(found)} system(s): {', '.join(found)}")
    else:
        typer.echo("No new systems discovered.")


@systems_app.command()
def stale() -> None:
    """Show system docs past staleness threshold."""
    from supermemory.config import memory_root
    from supermemory.health import _check_stale_systems, load_config

    root = memory_root()
    config = load_config(root)
    issues = _check_stale_systems(root, config)

    if not issues:
        typer.echo("All system docs are up to date.")
        return

    for issue in issues:
        typer.echo(f"  {issue['message']}")


# ── query ─────────────────────────────────────────────────────────────

@app.command()
def query(
    system: Optional[str] = typer.Option(None, "--system", "-s", help="Filter by system tag"),
    concern: Optional[str] = typer.Option(None, "--concern", "-c", help="Filter by concern tag"),
) -> None:
    """Query memory files by system and/or concern tags."""
    from supermemory.query import query as run_query, format_results

    if system is None and concern is None:
        typer.echo("Specify at least --system or --concern")
        raise typer.Exit(1)

    results = run_query(system=system, concern=concern)
    typer.echo(format_results(results))


# ── summary ───────────────────────────────────────────────────────────

@app.command()
def summary() -> None:
    """Regenerate SUMMARY.md index of all memory."""
    from supermemory.config import load_config, memory_root
    from supermemory.query import parse_frontmatter

    root = memory_root()
    config = load_config(root)
    project_name = config.get("project", {}).get("name", "Project")

    lines = [f"# {project_name} — Memory Index\n"]
    lines.append("> Auto-generated by `atlasmemory summary`. Do not edit manually.\n")

    # Systems table
    lines.append("## Systems\n")
    lines.append("| System | Owner | Last Verified | Paths |")
    lines.append("|--------|-------|---------------|-------|")
    systems_dir = root / "systems"
    if systems_dir.is_dir():
        for f in sorted(systems_dir.glob("*.md")):
            if f.name.startswith("_"):
                continue
            fm = parse_frontmatter(f) or {}
            owner = fm.get("owner", "") or ""
            verified = fm.get("last_verified", "") or ""
            paths = ", ".join(fm.get("paths", []) or [])
            lines.append(f"| [[{f.stem}]] | {owner} | {verified} | {paths} |")

    # Decisions table
    lines.append("\n## Decisions\n")
    lines.append("| # | Title | Date | Status |")
    lines.append("|---|-------|------|--------|")
    decisions_dir = root / "decisions"
    if decisions_dir.is_dir():
        for f in sorted(decisions_dir.glob("*.md")):
            if f.name.startswith("_"):
                continue
            fm = parse_frontmatter(f) or {}
            num = fm.get("number", "") or ""
            d = fm.get("date", "") or ""
            status = fm.get("status", "") or ""
            lines.append(f"| {num} | [[{f.stem}]] | {d} | {status} |")

    # Gotchas table
    lines.append("\n## Gotchas\n")
    lines.append("| Gotcha | Severity | Systems |")
    lines.append("|--------|----------|---------|")
    gotchas_dir = root / "gotchas"
    if gotchas_dir.is_dir():
        for f in sorted(gotchas_dir.glob("*.md")):
            if f.name.startswith("_"):
                continue
            fm = parse_frontmatter(f) or {}
            sev = fm.get("severity", "") or ""
            systems = ", ".join(str(s) for s in (fm.get("systems", []) or []))
            lines.append(f"| [[{f.stem}]] | {sev} | {systems} |")

    # Research table
    lines.append("\n## Research\n")
    lines.append("| Topic | Date | Status |")
    lines.append("|-------|------|--------|")
    research_dir = root / "research"
    if research_dir.is_dir():
        for f in sorted(research_dir.glob("*.md")):
            if f.name.startswith("_"):
                continue
            fm = parse_frontmatter(f) or {}
            d = fm.get("date", "") or ""
            status = fm.get("status", "") or ""
            lines.append(f"| [[{f.stem}]] | {d} | {status} |")

    # People table
    lines.append("\n## Team\n")
    lines.append("| Person | Role | Areas |")
    lines.append("|--------|------|-------|")
    people_dir = root / "people"
    if people_dir.is_dir():
        for f in sorted(people_dir.glob("*.md")):
            if f.name.startswith("_"):
                continue
            fm = parse_frontmatter(f) or {}
            role = fm.get("role", "") or ""
            areas = ", ".join(fm.get("areas", []) or [])
            lines.append(f"| [[{f.stem}]] | {role} | {areas} |")

    # Add Dataview queries if Obsidian is enabled
    if config.get("integrations", {}).get("obsidian", False):
        lines.append("\n---\n")
        lines.append("## Dataview Queries\n")
        lines.append("*These render automatically in Obsidian with the Dataview plugin.*\n")
        lines.append("### Stale System Docs\n")
        lines.append("```dataview")
        lines.append("TABLE owner, last_verified, paths")
        lines.append('FROM "systems"')
        lines.append("WHERE date(now) - date(last_verified) > dur(7 days)")
        lines.append("SORT last_verified ASC")
        lines.append("```\n")
        lines.append("### High Severity Gotchas\n")
        lines.append("```dataview")
        lines.append("TABLE severity, systems, discovered")
        lines.append('FROM "gotchas"')
        lines.append('WHERE severity = "high"')
        lines.append("SORT discovered DESC")
        lines.append("```\n")
        lines.append("### Active Decisions\n")
        lines.append("```dataview")
        lines.append("TABLE date, author, status")
        lines.append('FROM "decisions"')
        lines.append('WHERE status = "active"')
        lines.append("SORT number DESC")
        lines.append("```\n")
        lines.append("### Team Activity (Last 7 Days)\n")
        lines.append("```dataview")
        lines.append("TABLE person, topic, systems_touched")
        lines.append('FROM "sessions"')
        lines.append("WHERE date(date) > date(now) - dur(7 days)")
        lines.append("SORT date DESC")
        lines.append("```")

    summary_text = "\n".join(lines) + "\n"
    (root / "SUMMARY.md").write_text(summary_text)
    typer.echo("SUMMARY.md regenerated.")


# ── health ────────────────────────────────────────────────────────────

@app.command()
def health() -> None:
    """Check memory health — staleness, orphans, missing templates."""
    from supermemory.health import check_health, format_health

    issues = check_health()
    typer.echo(format_health(issues))
    if any(i["level"] == "error" for i in issues):
        raise typer.Exit(1)


# ── check-conflict ────────────────────────────────────────────────────

@app.command("check-conflict")
def check_conflict_cmd(
    file_path: str = typer.Argument(..., help="File path to check for conflicts"),
) -> None:
    """Check if a file is claimed in someone's DO NOT TOUCH section."""
    from supermemory.hooks import check_conflict

    warning = check_conflict(file_path)
    if warning:
        typer.echo(warning, err=True)
        raise typer.Exit(1)


def main() -> None:
    app()


if __name__ == "__main__":
    main()
