"""Status command - show project status and verify configuration."""

import json
import sys
from pathlib import Path
from datetime import datetime
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 ui


def status(
    directory: Annotated[Path, typer.Argument(help="Path to the project directory.")] = Path("."),
    format: Annotated[Optional[str], typer.Option("--format", help="Output format: text or json.")] = None,
):
    """Show project status and verify configuration."""
    directory = directory.resolve()
    nogic_dir = directory / CONFIG_DIR
    current_dir_hash = get_directory_hash(str(directory))
    json_mode = format == "json"

    if not nogic_dir.exists():
        if json_mode:
            _emit_json_status(error="Not a Nogic project.")
        else:
            ui.error("Not a Nogic project.")
            ui.dim("Run `nogic init` to initialize your project.")
        raise typer.Exit(1)

    config = Config.load(directory)

    if json_mode:
        _status_json(directory, config, current_dir_hash)
        return

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

    ui.banner("nogic status")

    ui.section("Local Configuration")
    ui.kv("Directory", str(directory))
    ui.kv("Project ID", config.project_id or "(not set)")
    ui.kv("Project Name", config.project_name or "(not set)")
    ui.kv("Directory Hash", f"{current_dir_hash[:16]}...")
    ui.kv("Logged in", "Yes" if config.api_key else "[red]No[/]")

    if config.directory_hash and config.directory_hash != current_dir_hash:
        ui.console.print()
        ui.warn("Directory hash mismatch!")
        ui.kv("Config hash", f"{config.directory_hash[:16]}...", indent=4)
        ui.kv("Current hash", f"{current_dir_hash[:16]}...", indent=4)
        ui.dim("    Project may have been moved. Run 'nogic init --link' to update.")

    # Backend verification
    if config.api_key and config.project_id:
        client = NogicClient(config)
        try:
            with ui.status_spinner("Checking backend..."):
                backend_project = client.get_project_by_directory(current_dir_hash)

            ui.section("Backend Status")
            if backend_project:
                ui.kv("Project found", backend_project.name)
                ui.kv("Project ID", backend_project.id)
                if backend_project.created_at:
                    ui.kv("Created", _format_datetime(backend_project.created_at))
                if backend_project.updated_at:
                    ui.kv("Updated", _format_datetime(backend_project.updated_at))

                if backend_project.id != config.project_id:
                    ui.console.print()
                    ui.warn("Project ID mismatch!")
                    ui.kv("Local config", config.project_id, indent=4)
                    ui.kv("Backend", backend_project.id, indent=4)
                    ui.dim("    Run 'nogic init --link' to fix.")
            else:
                ui.dim("  No project found for this directory in backend")
                if config.project_id:
                    ui.dim(f"  Local config has project ID: {config.project_id}")
                    ui.dim("  Consider running 'nogic init --link' to link it.")

        except httpx.HTTPStatusError as e:
            ui.section("Backend Status")
            ui.error(f"Error ({e.response.status_code})")
            if e.response.status_code == 401:
                ui.dim("  Authentication failed. Run: nogic login")
        except httpx.RequestError:
            ui.section("Backend Status")
            ui.error("Connection failed")
        finally:
            client.close()
    elif not config.api_key:
        ui.section("Backend Status")
        ui.dim("  Not logged in. Run `nogic login` to authenticate.")
    else:
        ui.section("Backend Status")
        ui.dim("  No project configured. Run `nogic init` to set up.")

    ui.console.print()


def _status_json(directory: Path, config: Config, dir_hash: str):
    """Output status as a single JSON object to stdout."""
    result: dict = {
        "project_name": config.project_name or None,
        "project_id": config.project_id or None,
        "directory": str(directory),
        "logged_in": bool(config.api_key),
        "backend": None,
    }

    if config.api_key and config.project_id:
        client = NogicClient(config)
        try:
            backend_project = client.get_project_by_directory(dir_hash)
            if backend_project:
                result["backend"] = {
                    "status": "connected",
                    "project_name": backend_project.name,
                    "project_id": backend_project.id,
                    "created_at": backend_project.created_at,
                    "updated_at": backend_project.updated_at,
                }
            else:
                result["backend"] = {"status": "not_found"}
        except httpx.HTTPStatusError as e:
            result["backend"] = {
                "status": "error",
                "error": f"HTTP {e.response.status_code}",
            }
        except httpx.RequestError as e:
            result["backend"] = {
                "status": "error",
                "error": str(e),
            }
        finally:
            client.close()
    elif not config.api_key:
        result["backend"] = {"status": "not_logged_in"}
    else:
        result["backend"] = {"status": "not_configured"}

    sys.stdout.write(json.dumps(result) + "\n")
    sys.stdout.flush()


def _emit_json_status(**kwargs):
    """Emit a JSON status object with error info."""
    sys.stdout.write(json.dumps(kwargs) + "\n")
    sys.stdout.flush()


def _format_datetime(dt_string: str) -> str:
    try:
        dt = datetime.fromisoformat(dt_string.replace("Z", "+00:00"))
        return dt.strftime("%Y-%m-%d %H:%M:%S")
    except (ValueError, AttributeError):
        return dt_string
