"""Init command - initialize a Nogic project."""

from pathlib import Path
from typing import Annotated, Optional

import httpx
import typer

from nogic.config import Config, CONFIG_DIR, is_dev_mode, get_api_url
from nogic.api import NogicClient
from nogic.api.client import get_directory_hash
from nogic import telemetry, ui


def init(
    directory: Annotated[Path, typer.Argument(help="Path to the project directory.")] = Path("."),
    project_id: Annotated[Optional[str], typer.Option("--project-id", "-p", help="Use existing project ID.")] = None,
    name: Annotated[Optional[str], typer.Option("--name", "-n", help="Project name.")] = None,
    link: Annotated[bool, typer.Option("--link", help="Re-link an existing project.")] = False,
    yes: Annotated[bool, typer.Option("--yes", "-y", help="Accept defaults, skip prompts.")] = False,
):
    """Initialize a Nogic project in a directory."""
    directory = directory.resolve()
    nogic_dir = directory / CONFIG_DIR
    dir_hash = get_directory_hash(str(directory))

    config = Config.load(directory)

    if not config.api_key:
        ui.error("Not logged in.")
        ui.dim("Run `nogic login` to authenticate.")
        raise typer.Exit(1)

    if is_dev_mode():
        ui.dev_banner(get_api_url())

    client = NogicClient(config)

    try:
        if nogic_dir.exists() and not link and config.project_id:
            ui.warn(f"Already initialized: {nogic_dir}")
            ui.kv("Project ID", config.project_id)
            ui.kv("Project Name", config.project_name or "unknown")
            ui.dim("\nUse --link to re-link to a different project.")
            return

        if project_id:
            config.project_id = project_id
            config.project_name = name or directory.name
            config.directory_hash = dir_hash
            _finalize_init(directory, nogic_dir, config)
            return

        with ui.status_spinner("Checking for existing project..."):
            existing_project = client.get_project_by_directory(dir_hash)

        if existing_project:
            ui.info(f"Found existing project '{existing_project.name}'")
            ui.kv("Project ID", existing_project.id)

            if yes or typer.confirm("Use this project?", default=True):
                config.project_id = existing_project.id
                config.project_name = existing_project.name
                config.directory_hash = dir_hash
                _finalize_init(directory, nogic_dir, config)
            else:
                ui.console.print("\nOptions:")
                ui.console.print("  1. Wipe graph data and reuse this project")
                ui.console.print("  2. Abort")

                choice = "1" if yes else typer.prompt("Choose option", default="1")

                if choice == "1":
                    with ui.status_spinner("Wiping graph data..."):
                        result = client.wipe_project_graph(existing_project.id)
                    ui.info(f"Deleted {result.nodes_deleted} nodes")
                    config.project_id = existing_project.id
                    config.project_name = existing_project.name
                    config.directory_hash = dir_hash
                    _finalize_init(directory, nogic_dir, config)
                else:
                    ui.dim("Aborted.")
                    raise typer.Exit(0)
        else:
            project_name = name or (directory.name if yes else typer.prompt("Project name", default=directory.name))

            try:
                with ui.status_spinner("Creating project..."):
                    project = client.create_project(project_name, dir_hash)
                config.project_id = project.id
                config.project_name = project.name
                config.directory_hash = dir_hash
                ui.success(f"Created project '{project.name}'")
                _finalize_init(directory, nogic_dir, config)
            except httpx.HTTPStatusError as e:
                if e.response.status_code == 409:
                    data = e.response.json()
                    ui.warn(f"Project already exists: {data.get('project_name')}")
                    if yes or typer.confirm("Use this project?", default=True):
                        config.project_id = data.get("project_id")
                        config.project_name = data.get("project_name")
                        config.directory_hash = dir_hash
                        _finalize_init(directory, nogic_dir, config)
                    else:
                        raise typer.Exit(1)
                else:
                    ui.error(f"Error creating project ({e.response.status_code})")
                    raise typer.Exit(1)
    finally:
        client.close()


def _finalize_init(directory: Path, nogic_dir: Path, config: Config):
    nogic_dir.mkdir(mode=0o700, exist_ok=True)
    config.save_local(directory)

    ui.console.print()
    ui.banner("nogic init")
    ui.kv("Directory", str(directory))
    ui.kv("Project", config.project_name or "")
    ui.kv("Project ID", config.project_id or "")
    ui.console.print()
    ui.dim("Ready to sync: nogic watch")

    telemetry.capture("cli_init", {"project_name": config.project_name})
