"""Initialize gjalla in a repository."""

import json
import os
from pathlib import Path

import click
from rich.prompt import Prompt, Confirm

from gjalla_precommit.display.output import console, success, error, warning, info, panel
from gjalla_precommit.tools.git_tools import is_git_repo, get_remote_url

from ._api import (
    verify_api_key,
    list_projects,
    discover_project,
    select_project_interactively,
    _make_api_headers,
)


# Global config paths
GJALLA_DIR = Path.home() / ".gjalla"
CONFIG_PATH = GJALLA_DIR / "config.yaml"

# API timeout in seconds
API_TIMEOUT = 30.0


def load_global_config() -> dict:
    """Load global gjalla config from ~/.gjalla/config.yaml."""
    import yaml

    if not CONFIG_PATH.exists():
        return {
            "api_key": None,
            "api_url": "https://gjalla.io",
            "projects": {},
        }

    with open(CONFIG_PATH) as f:
        return yaml.safe_load(f) or {}


def save_global_config(config: dict) -> None:
    """Save global gjalla config to ~/.gjalla/config.yaml."""
    import yaml

    GJALLA_DIR.mkdir(parents=True, exist_ok=True)
    with open(CONFIG_PATH, "w") as f:
        yaml.dump(config, f, default_flow_style=False)


@click.command()
@click.option(
    "--api-key",
    envvar="GJALLA_API_KEY",
    help="API key for gjalla cloud. Can also be set via GJALLA_API_KEY env var.",
)
@click.option(
    "--project-id",
    type=int,
    help="Project ID. If not provided, will be auto-discovered from git remote.",
)
def init(
    api_key: str | None,
    project_id: int | None,
) -> None:
    """Initialize gjalla in the current repository.

    This command sets up gjalla for your repository by:

    \b
    1. Checking git repository
    2. Configuring your API key (optional — skip for local-only usage)
    3. Verifying API key
    4. Selecting your project from Gjalla
    5. Creating .gjalla project config
    6. Updating .gitignore
    7. Offering guardrails setup

    Run without --api-key for local-only mode. Use 'gjalla connect' later to link a project.
    """
    repo_path = Path.cwd()

    panel("gjalla Initialization", title="gjalla init")
    console.print()

    # Step 1: Verify we're in a git repo
    info("Step 1/7: Checking git repository...")
    if not is_git_repo(repo_path):
        error("Not a git repository. Please run 'gjalla init' from a git repository.")
        raise SystemExit(1)
    success("Git repository detected")
    console.print()

    # Load existing config
    config = load_global_config()
    api_url = os.environ.get("GJALLA_API_URL") or config.get("api_url", "https://gjalla.io")

    # Determine if we have an API key available
    has_api_key = False
    if api_key:
        has_api_key = True
        info("Step 2/7: Using API key from command line or environment")
    elif config.get("api_key"):
        api_key = config["api_key"]
        has_api_key = True
        info("Step 2/7: Using existing API key from config")
    else:
        info("Step 2/7: No API key provided — setting up local-only mode")
        info("  Run 'gjalla connect' later to link to a Gjalla project")

    project_info = None

    if has_api_key:
        success("API key configured")
        console.print()

        # Step 3: Verify API key
        info("Step 3/7: Verifying API key...")
        if not verify_api_key(api_key, api_url):
            error("Invalid API key. Please check your key and try again.")
            raise SystemExit(1)
        success("API key verified")
        console.print()

        # Step 4: Discover/select project
        info("Step 4/7: Selecting project...")
        if project_id:
            info(f"Using provided project ID: {project_id}")
            project_info = {"id": project_id, "name": "unknown"}
        else:
            remote_url = get_remote_url(repo_path)
            if remote_url and not remote_url.startswith("Error:"):
                info(f"Found git remote: {remote_url}")
                discovered = discover_project(remote_url, api_key, api_url)

                if discovered:
                    info(f"Discovered project: {discovered['name']}")
                    if Confirm.ask("Is this the correct project?", default=True):
                        project_info = {"id": discovered["id"], "name": discovered["name"]}

            if not project_info:
                info("Select your project from the available options:")
                project_info = select_project_interactively(api_key, api_url)
                if not project_info:
                    raise SystemExit(1)

        success(f"Selected project: {project_info.get('name', project_info['id'])}")
        console.print()

        # Save config with API key
        config["api_key"] = api_key
        config["api_url"] = api_url
        if "projects" not in config:
            config["projects"] = {}
        config["projects"][str(repo_path)] = str(project_info["id"])
        save_global_config(config)
    else:
        info("  Skipping steps 3-4 (API verification and project selection)")
        console.print()

    # Step 5: Create .gjalla project config
    info("Step 5/7: Creating .gjalla project config...")
    gjalla_dir = repo_path / ".gjalla"

    # Migrate: if .gjalla is an old-format file, move it into the directory
    if gjalla_dir.is_file():
        old_content = gjalla_dir.read_text()
        gjalla_dir.unlink()
        gjalla_dir.mkdir(parents=True, exist_ok=True)
        (gjalla_dir / "config.json").write_text(old_content)
        info("Migrated .gjalla file → .gjalla/config.json")
    else:
        gjalla_dir.mkdir(parents=True, exist_ok=True)

    gjalla_config_data = {
        "project_id": project_info["id"] if project_info else None,
        "api_url": api_url,
        "api_key_env": "GJALLA_API_KEY",
    }
    (gjalla_dir / "config.json").write_text(json.dumps(gjalla_config_data, indent=2) + "\n")

    if project_info:
        success(f"Created .gjalla/config.json (project {project_info['id']})")
    else:
        success("Created .gjalla/config.json (local-only, no project linked)")
    console.print()

    # Step 6: Update .gitignore
    info("Step 6/7: Updating .gitignore...")
    gitignore_path = repo_path / ".gitignore"
    gitignore_content = gitignore_path.read_text() if gitignore_path.exists() else ""
    gitignore_lines = gitignore_content.splitlines()
    entries_to_add = [".commit-attestation.md", ".gjallalog", ".gjalla/attestations/"]
    added = []
    for entry in entries_to_add:
        if entry not in gitignore_lines:
            gitignore_lines.append(entry)
            added.append(entry)
    if added:
        gitignore_path.write_text("\n".join(gitignore_lines) + "\n")
        success(f"Added to .gitignore: {', '.join(added)}")
    else:
        success(".gitignore already up to date")
    console.print()

    # Step 7: Offer guardrails setup
    info("Step 7/7: Commit attestation guardrails...")
    info("This will add precommit hooks to your repository so agents must attest that their changes are compliant with your rules and architecture before committing.")
    if Confirm.ask("Enable?", default=True):
        from .setup import _ensure_gitignore
        from ..hooks.scripts import attestation_pre_commit_script, post_commit_upload_script, example_attestation
        from ..hooks.installer import install_hooks
        import stat

        # Write example attestation
        example_path = gjalla_dir / "example-attestation.md"
        example_path.write_text(example_attestation())
        success("Created .gjalla/example-attestation.md")

        scripts_dir = repo_path / "scripts"
        scripts_dir.mkdir(exist_ok=True)

        pre_path = scripts_dir / "gjalla-attestation-check.sh"
        pre_path.write_text(attestation_pre_commit_script())
        pre_path.chmod(pre_path.stat().st_mode | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH)

        post_path = scripts_dir / "gjalla-post-commit-upload.sh"
        post_path.write_text(post_commit_upload_script())
        post_path.chmod(post_path.stat().st_mode | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH)

        result = install_hooks(
            repo_path,
            pre_commit_command="bash scripts/gjalla-attestation-check.sh",
            post_commit_command="bash scripts/gjalla-post-commit-upload.sh",
        )
        success(f"Pre-commit: {result.pre_commit.message}")
        success(f"Post-commit: {result.post_commit.message}")
    else:
        info("Skipped. Run 'gjalla setup' later to enable guardrails.")
    console.print()

    # Build completion message
    if has_api_key:
        completion_msg = "[green]Success! Agents will now have to attest that their changes are compliant with your rules and architecture before committing[/green]\n\n"
        completion_msg += "Run 'gjalla sync' to refresh project context.\n"
        completion_msg += "Run 'gjalla setup' to reconfigure guardrails.\n"
        panel(completion_msg, title="gjalla initialized successfully!")
    else:
        completion_msg = "[green]Success! Local guardrails are active — agents must attest before committing.[/green]\n\n"
        completion_msg += "Connect a Gjalla account to navigate architecture changes,\n"
        completion_msg += "control what agents can do, and track compliance across your team.\n\n"
        completion_msg += "  [bold]gjalla connect[/bold] — link your API key and project\n"
        panel(completion_msg, title="gjalla initialized (local-only)")
