"""
CLI commands for prompt dependency resolution.

Provides Click commands for tracing provenance, visualizing graphs,
querying run history, and inspecting impact debt.
"""

import json
import os

import click

from markitect.prompts.dependencies.graph import GraphBuilder
from markitect.prompts.dependencies.repository import SQLiteDependencyRepository
from markitect.prompts.queries.operations import PromptQueryService
from markitect.prompts.repositories.sqlite import SQLiteArtifactRepository
from markitect.prompts.traceability.service import TraceabilityService
from markitect.prompts.visualization.graph import GraphExporter


def _default_db_path():
    """Return the default database path."""
    return os.path.expanduser("~/.markitect/markitect.db")


def _get_repos(database):
    """Create artifact and dependency repos from database path."""
    db = database or _default_db_path()
    artifact_repo = SQLiteArtifactRepository(db)
    dep_repo = SQLiteDependencyRepository(db)
    return artifact_repo, dep_repo, db


@click.group(name="prompt")
def prompt_commands():
    """Prompt dependency resolution commands."""
    pass


@prompt_commands.command("trace")
@click.argument("artifact_id")
@click.option("--database", type=click.Path(), help="Database file path")
def trace_artifact(artifact_id, database):
    """Trace provenance of an artifact."""
    artifact_repo, dep_repo, db = _get_repos(database)
    service = TraceabilityService(artifact_repo, dep_repo, db_path=db)

    artifact = artifact_repo.get_by_id(artifact_id)
    if not artifact:
        click.echo(f"Artifact '{artifact_id}' not found.", err=True)
        raise SystemExit(1)

    trace = service.trace_artifact(artifact_id)
    click.echo(json.dumps(trace.to_dict(), indent=2, default=str))


@prompt_commands.command("graph")
@click.argument("artifact_id")
@click.option(
    "--format",
    "fmt",
    type=click.Choice(["dot", "mermaid"]),
    default="mermaid",
    help="Output format",
)
@click.option("--database", type=click.Path(), help="Database file path")
def show_graph(artifact_id, fmt, database):
    """Visualize dependency graph for an artifact."""
    artifact_repo, dep_repo, db = _get_repos(database)
    builder = GraphBuilder(dep_repo)

    # Build graph from all edges involving this artifact
    from markitect.prompts.dependencies.queries import DependencyQueryService

    query_svc = DependencyQueryService(dep_repo)
    deps = query_svc.find_transitive_dependencies(artifact_id)
    dependents = query_svc.find_transitive_dependents(artifact_id)
    all_ids = deps | dependents | {artifact_id}

    graph = builder.build_graph(all_ids)

    if fmt == "dot":
        click.echo(GraphExporter.to_dot(graph, title=f"Dependencies: {artifact_id}"))
    else:
        click.echo(
            GraphExporter.to_mermaid(graph, title=f"Dependencies: {artifact_id}")
        )


@prompt_commands.command("runs")
@click.option("--template", help="Filter by template ID")
@click.option(
    "--status",
    type=click.Choice(["pending", "running", "success", "failed", "skipped"]),
    help="Filter by status",
)
@click.option("--limit", default=20, type=int, help="Maximum results")
@click.option("--database", type=click.Path(), help="Database file path")
def list_runs(template, status, limit, database):
    """List prompt execution runs."""
    artifact_repo, dep_repo, db = _get_repos(database)
    query_svc = PromptQueryService(artifact_repo, dep_repo, db_path=db)

    runs = query_svc.get_run_history(
        template_id=template, status=status, limit=limit
    )

    if not runs:
        click.echo("No runs found.")
        return

    click.echo(json.dumps(runs, indent=2, default=str))


@prompt_commands.command("debt")
@click.option("--artifact", help="Filter by artifact ID")
@click.option("--database", type=click.Path(), help="Database file path")
def show_debt(artifact, database):
    """Show impact debt (suppressed recomputations)."""
    artifact_repo, dep_repo, db = _get_repos(database)
    query_svc = PromptQueryService(artifact_repo, dep_repo, db_path=db)

    if artifact:
        # Get debt for specific artifact via traceability service
        trace_svc = TraceabilityService(artifact_repo, dep_repo, db_path=db)
        debts = trace_svc.get_impact_debt(artifact)
        if not debts:
            click.echo(f"No impact debt for artifact '{artifact}'.")
            return
        click.echo(json.dumps(debts, indent=2, default=str))
    else:
        stale = query_svc.get_stale_artifacts()
        if not stale:
            click.echo("No stale artifacts found.")
            return
        click.echo(json.dumps(stale, indent=2, default=str))


@prompt_commands.command("stats")
@click.option("--database", type=click.Path(), help="Database file path")
def show_stats(database):
    """Show dependency graph statistics."""
    artifact_repo, dep_repo, db = _get_repos(database)
    query_svc = PromptQueryService(artifact_repo, dep_repo, db_path=db)

    stats = query_svc.get_dependency_stats()
    click.echo(json.dumps(stats, indent=2))
