"""chlo-mcp init — set up Claude Code hooks for automatic activity reporting."""

import json
import os
import stat
import sys

import httpx

DEFAULT_API_URL = "https://orchestrate.patadev.lv"

HOOK_SCRIPT = r'''#!/bin/bash
# Claude Code PostToolUse hook — forwards activity events to Chlo's API
# for real-time graph highlighting and activity feed.
#
# Env loaded from .claude/hooks/.chlo-env:
#   CHLO_PROJECT_ID — Target project UUID
#   CHLO_API_KEY    — Bearer token (API key starting with chlo_)
#   CHLO_API_URL    — API base URL (default: https://orchestrate.patadev.lv)

# Source project config
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
if [ -f "$SCRIPT_DIR/.chlo-env" ]; then
  source "$SCRIPT_DIR/.chlo-env"
fi

if [ -z "$CHLO_API_KEY" ] || [ -z "$CHLO_PROJECT_ID" ]; then
  exit 0
fi

INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // ""')

# For Grep/Glob: extract matched file paths from tool_response
if [ "$TOOL_NAME" = "Grep" ] || [ "$TOOL_NAME" = "Glob" ]; then
  # tool_response contains matched file paths, one per line
  FILE_PATHS_JSON=$(echo "$INPUT" | jq -rc '
    (.tool_response // "") | split("\n") | map(select(length > 0 and test("^/")))
    | if length > 20 then .[0:20] else . end
  ')

  EVENT=$(echo "$INPUT" | jq -rc --argjson fps "$FILE_PATHS_JSON" '{
    event_type: "search",
    file_paths: $fps,
    file_path: (.tool_input.file_path // .tool_input.path // .tool_input.pattern // ""),
    tool_name: .tool_name,
    summary: (
      if .tool_name == "Grep" then "Searching: " + (.tool_input.pattern // "")
      else "Finding: " + (.tool_input.pattern // "")
      end
    ),
    session_id: .session_id
  }')
else
  # Build tool_input payload for Edit/Write/Bash events
  TOOL_INPUT_JSON=$(echo "$INPUT" | jq -rc '
    if .tool_name == "Edit" then
      {
        old_string: (.tool_input.old_string // "" | .[0:500]),
        new_string: (.tool_input.new_string // "" | .[0:500])
      }
    elif .tool_name == "Write" then
      {
        content: (.tool_input.content // "" | .[0:500])
      }
    elif .tool_name == "Bash" then
      {
        command: (.tool_input.command // "" | .[0:500])
      }
    else null
    end
  ')

  EVENT=$(echo "$INPUT" | jq -rc --argjson ti "$TOOL_INPUT_JSON" '{
    event_type: (
      if .tool_name == "Read" then "file_read"
      elif .tool_name == "Edit" or .tool_name == "Write" then "file_edit"
      elif .tool_name == "Bash" then "bash_command"
      else "other"
      end
    ),
    file_path: (.tool_input.file_path // .tool_input.path // .tool_input.pattern // ""),
    tool_name: .tool_name,
    tool_input: $ti,
    summary: (
      if .tool_name == "Read" then "Reading " + (.tool_input.file_path // "" | split("/") | last)
      elif .tool_name == "Edit" then "Editing " + (.tool_input.file_path // "" | split("/") | last)
      elif .tool_name == "Write" then "Creating " + (.tool_input.file_path // "" | split("/") | last)
      elif .tool_name == "Bash" then "Running command"
      else .tool_name
      end
    ),
    session_id: .session_id
  }')
fi

# Fire and forget — don't block Claude
curl -s -X POST \
  "${CHLO_API_URL:-https://orchestrate.patadev.lv}/api/v2/projects/${CHLO_PROJECT_ID}/activity" \
  -H "Authorization: Bearer $CHLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d "$EVENT" &>/dev/null &
'''

HOOK_CONFIG = {
    "hooks": {
        "PostToolUse": [
            {
                "matcher": "Read|Edit|Write|Bash|Grep|Glob",
                "hooks": [
                    {
                        "type": "command",
                        "command": "bash .claude/hooks/chlo-activity.sh",
                    }
                ],
            }
        ]
    }
}


def _fetch_projects(api_url: str, api_key: str) -> list[dict]:
    """Fetch projects from the Chlo API (sync)."""
    url = f"{api_url.rstrip('/')}/api/v2/projects/"
    resp = httpx.get(
        url,
        headers={"Authorization": f"Bearer {api_key}"},
        timeout=15.0,
        follow_redirects=True,
    )
    resp.raise_for_status()
    return resp.json()


def _pick_project(projects: list[dict]) -> str | None:
    """Interactive project picker — returns a project_id or None."""
    print("\nAvailable projects:\n")
    for i, p in enumerate(projects, 1):
        name = p.get("name", "Untitled")
        pid = p.get("project_id", "")
        print(f"  {i}. {name}  ({pid})")

    print()
    while True:
        choice = input(f"Select a project [1-{len(projects)}]: ").strip()
        if not choice:
            return None
        try:
            idx = int(choice) - 1
            if 0 <= idx < len(projects):
                return projects[idx]["project_id"]
        except ValueError:
            pass
        print(f"  Please enter a number between 1 and {len(projects)}")


def run_init(project_id: str | None = None) -> None:
    """Set up Claude Code hooks for Chlo activity reporting."""
    print("chlo-mcp init — setting up Claude Code activity hooks\n")

    # 1. Validate API key
    api_key = os.environ.get("CHLO_API_KEY", "")
    if not api_key:
        print("Error: CHLO_API_KEY environment variable is not set.")
        print("Generate an API key at https://chlo.dev and export it:")
        print("  export CHLO_API_KEY=chlo_...")
        sys.exit(1)

    api_url = os.environ.get("CHLO_API_URL", DEFAULT_API_URL)

    # 2. Resolve project ID
    if not project_id:
        print("Fetching your projects...")
        try:
            projects = _fetch_projects(api_url, api_key)
        except httpx.HTTPStatusError as e:
            if e.response.status_code == 401:
                print("Error: Invalid or expired API key.")
            else:
                print(f"Error fetching projects: {e}")
            sys.exit(1)
        except httpx.HTTPError as e:
            print(f"Error connecting to Chlo API: {e}")
            sys.exit(1)

        if not projects:
            print("No projects found. Index a repository at https://chlo.dev first.")
            sys.exit(1)

        project_id = _pick_project(projects)
        if not project_id:
            print("No project selected. Aborting.")
            sys.exit(1)

    print(f"\nProject ID: {project_id}")

    # 3. Create hooks directory
    hooks_dir = os.path.join(".claude", "hooks")
    os.makedirs(hooks_dir, exist_ok=True)

    # 4. Write hook script
    hook_path = os.path.join(hooks_dir, "chlo-activity.sh")
    with open(hook_path, "w") as f:
        f.write(HOOK_SCRIPT)
    os.chmod(hook_path, os.stat(hook_path).st_mode | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH)
    print(f"  Wrote {hook_path}")

    # 5. Write .chlo-env with project ID and API key
    env_path = os.path.join(hooks_dir, ".chlo-env")
    with open(env_path, "w") as f:
        f.write(f'CHLO_PROJECT_ID="{project_id}"\n')
        f.write(f'CHLO_API_KEY="{api_key}"\n')
        if api_url != DEFAULT_API_URL:
            f.write(f'CHLO_API_URL="{api_url}"\n')
    print(f"  Wrote {env_path}")

    # 6. Update .claude/settings.json
    settings_path = os.path.join(".claude", "settings.json")
    settings: dict = {}
    if os.path.exists(settings_path):
        with open(settings_path) as f:
            try:
                settings = json.load(f)
            except json.JSONDecodeError:
                settings = {}

    # Merge hook config — don't clobber existing hooks
    existing_hooks = settings.get("hooks", {})
    existing_post = existing_hooks.get("PostToolUse", [])

    # Check if our hook is already registered
    already_registered = any(
        any(
            h.get("command", "").endswith("chlo-activity.sh")
            for h in entry.get("hooks", [])
        )
        for entry in existing_post
    )

    if not already_registered:
        existing_post.extend(HOOK_CONFIG["hooks"]["PostToolUse"])
        existing_hooks["PostToolUse"] = existing_post
        settings["hooks"] = existing_hooks

        with open(settings_path, "w") as f:
            json.dump(settings, f, indent=2)
            f.write("\n")
        print(f"  Updated {settings_path}")
    else:
        print(f"  Hook already registered in {settings_path}")

    print("\nDone! Claude Code will now report activity to Chlo.")
