"""Projects command - list and manage projects."""

from pathlib import Path
from typing import Annotated

import httpx
import typer

from nogic.config import Config
from nogic.api import NogicClient
from nogic.api.client import get_directory_hash
from nogic import ui

projects_app = typer.Typer(no_args_is_help=True, rich_markup_mode="rich")


def _require_auth() -> Config:
    config = Config.load()
    if not config.api_key:
        ui.error("Not logged in.")
        ui.dim("Run `nogic login` to authenticate.")
        raise typer.Exit(1)
    return config


@projects_app.command("list")
def list_projects(
    verbose: Annotated[bool, typer.Option("--verbose", "-v", help="Show detailed info.")] = False,
):
    """List your projects."""
    config = _require_auth()

    client = NogicClient(config)
    try:
        with ui.status_spinner("Fetching projects..."):
            projects_list = client.list_projects()

        if not projects_list:
            ui.info("No projects found.")
            ui.dim("Create one with: nogic init")
            return

        ui.banner("nogic projects", f"{len(projects_list)} project(s)")
        for p in projects_list:
            marker = " [green]*[/]" if p.id == config.project_id else ""
            ui.console.print(f"  [bold]{p.name}[/] [dim]({p.id[:8]}...)[/]{marker}")
            if verbose:
                if p.directory_hash:
                    ui.dim(f"    Hash: {p.directory_hash[:16]}...")
                if p.created_at:
                    ui.dim(f"    Created: {p.created_at}")

        if config.project_id:
            ui.console.print()
            ui.dim("  * = current project")

    except httpx.HTTPStatusError as e:
        ui.error(f"Error ({e.response.status_code})")
        raise typer.Exit(1)
    finally:
        client.close()


@projects_app.command("use")
def use_project(
    project_id: Annotated[str, typer.Argument(help="Project ID (prefix match).")],
):
    """Set the current project by ID."""
    cwd = Path.cwd()
    config = _require_auth()

    client = NogicClient(config)
    try:
        with ui.status_spinner("Fetching projects..."):
            projects_list = client.list_projects()
        matched = [p for p in projects_list if p.id.startswith(project_id)]

        if not matched:
            ui.error(f"No project found matching: {project_id}")
            raise typer.Exit(1)
        if len(matched) > 1:
            ui.error(f"Multiple projects match '{project_id}':")
            for p in matched:
                ui.console.print(f"  {p.name} ({p.id})")
            raise typer.Exit(1)

        config.project_id = matched[0].id
        config.save_local(cwd)
        ui.success(f"Now using project: {matched[0].name}")

    except httpx.HTTPStatusError as e:
        ui.error(f"Error ({e.response.status_code})")
        raise typer.Exit(1)
    finally:
        client.close()


@projects_app.command("create")
def create_project(
    name: Annotated[str, typer.Argument(help="Project name.")],
    use: Annotated[bool, typer.Option("--use", help="Set as current project.")] = False,
    link: Annotated[bool, typer.Option("--link", help="Link to current directory.")] = False,
):
    """Create a new project."""
    cwd = Path.cwd()
    config = _require_auth()

    dir_hash = get_directory_hash(str(cwd)) if link else None

    client = NogicClient(config)
    try:
        with ui.status_spinner("Creating project..."):
            project = client.create_project(name, dir_hash)

        ui.success(f"Created project: {project.name}")
        ui.kv("Project ID", project.id)
        if link:
            ui.kv("Linked to", str(cwd))

        if use or link:
            config.project_id = project.id
            config.project_name = project.name
            if link:
                config.directory_hash = dir_hash
            config.save_local(cwd)
            ui.dim("Set as current project.")

    except httpx.HTTPStatusError as e:
        if e.response.status_code == 409:
            data = e.response.json()
            ui.error("A project already exists for this directory.")
            ui.kv("Project", f"{data.get('project_name')} ({data.get('project_id')[:8]}...)", indent=4)
            ui.dim("  Use 'nogic init' to reuse the existing project.")
        else:
            ui.error(f"Error ({e.response.status_code})")
        raise typer.Exit(1)
    finally:
        client.close()
