"""Install Hooks command for TripWire CLI."""

import subprocess
import sys
from pathlib import Path

import click

from tripwire.cli.utils.console import console


@click.command(name="install-hooks")
@click.option(
    "--framework",
    type=click.Choice(["git", "pre-commit"]),
    default="git",
    help="Hook framework to use",
)
@click.option(
    "--force",
    is_flag=True,
    help="Overwrite existing hooks",
)
@click.option(
    "--uninstall",
    is_flag=True,
    help="Remove TripWire hooks",
)
def install_hooks(framework: str, force: bool, uninstall: bool) -> None:
    """Install pre-commit hooks for TripWire.

    Prevents commits with validation errors or secrets by automatically
    running checks before each commit.

    Examples:

        tripwire install-hooks

        tripwire install-hooks --framework pre-commit

        tripwire install-hooks --uninstall
    """
    import shutil
    import stat
    from datetime import datetime

    git_dir = Path(".git")

    if not git_dir.exists():
        console.print("[red]Error:[/red] Not a git repository")
        console.print("Initialize git first: [cyan]git init[/cyan]")
        sys.exit(1)

    hooks_dir = git_dir / "hooks"
    pre_commit_hook = hooks_dir / "pre-commit"
    config_file = Path(".tripwire-hooks.toml")

    # Uninstall mode
    if uninstall:
        console.print("[yellow]Uninstalling TripWire hooks...[/yellow]\n")

        removed_files = []

        if pre_commit_hook.exists():
            # Check if it's our hook
            content = pre_commit_hook.read_text()
            if "Generated by TripWire" in content:
                pre_commit_hook.unlink()
                removed_files.append(str(pre_commit_hook))
                console.print(f"[green][OK][/green] Removed {pre_commit_hook}")
            else:
                console.print(f"[yellow][!][/yellow] {pre_commit_hook} not managed by TripWire, skipping")

        if config_file.exists():
            config_file.unlink()
            removed_files.append(str(config_file))
            console.print(f"[green][OK][/green] Removed {config_file}")

        if removed_files:
            console.print(f"\n[green]Successfully removed {len(removed_files)} file(s)[/green]")
        else:
            console.print("[yellow]No TripWire hooks found to remove[/yellow]")

        return

    # Install mode
    if framework == "pre-commit":
        # Generate .pre-commit-config.yaml
        pre_commit_config = Path(".pre-commit-config.yaml")

        if pre_commit_config.exists() and not force:
            console.print(f"[red]Error:[/red] {pre_commit_config} already exists")
            console.print("Use --force to overwrite or manually add TripWire hooks to the file")
            sys.exit(1)

        # Check if pre-commit is installed
        if not shutil.which("pre-commit"):
            console.print("[red]Error:[/red] pre-commit framework not installed")
            console.print("Install it with: [cyan]pip install pre-commit[/cyan]")
            sys.exit(1)

        config_content = """# TripWire Pre-Commit Hooks
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks

repos:
  - repo: local
    hooks:
      - id: tripwire-schema-validate
        name: TripWire Schema Validation
        entry: tripwire schema validate --strict
        language: system
        pass_filenames: false
        always_run: true

      - id: tripwire-secret-scan
        name: TripWire Secret Scan
        entry: tripwire scan --strict
        language: system
        pass_filenames: false
        always_run: true
"""

        pre_commit_config.write_text(config_content)
        console.print(f"[green][OK][/green] Created {pre_commit_config}")

        console.print("\n[bold cyan]Next steps:[/bold cyan]")
        console.print("  1. Run: [cyan]pre-commit install[/cyan]")
        console.print("  2. Test hooks: [cyan]pre-commit run --all-files[/cyan]")
        console.print("  3. Commit as usual - hooks run automatically")

        return

    # Git hooks mode
    console.print("[bold cyan]Installing TripWire git hooks...[/bold cyan]\n")

    # Create hooks directory if it doesn't exist
    hooks_dir.mkdir(parents=True, exist_ok=True)

    # Check for existing hook
    if pre_commit_hook.exists() and not force:
        content = pre_commit_hook.read_text()
        if "Generated by TripWire" not in content:
            console.print(f"[red]Error:[/red] {pre_commit_hook} already exists (not managed by TripWire)")
            console.print("Use --force to overwrite, or manually integrate TripWire commands")
            console.print("\nManual integration:")
            console.print("  Add to your existing hook:")
            console.print("  [cyan]tripwire schema validate --strict[/cyan]")
            console.print("  [cyan]tripwire scan --strict[/cyan]")
            sys.exit(1)
        else:
            console.print(f"[yellow][!][/yellow] TripWire hook already installed, updating...")

    # Create config file if it doesn't exist
    if not config_file.exists():
        config_content = """# TripWire Pre-Commit Hook Configuration
# Generated by: tripwire install-hooks

[pre-commit]
enabled = true
strict = true

[checks]
schema_validate = true
secret_scan = true
drift_check = false

[schema_validate]
environment = "development"
strict = true

[secret_scan]
fail_on_critical = true
fail_on_high = false

[drift_check]
# Variables allowed to differ from .env.example
allowed_drift = ["DEBUG", "LOG_LEVEL"]
"""

        config_file.write_text(config_content)
        console.print(f"[green][OK][/green] Created {config_file}")

    # Create pre-commit hook script
    hook_content = f"""#!/bin/bash
# Generated by TripWire - DO NOT EDIT MANUALLY
# Created: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
# To disable: git commit --no-verify

CONFIG_FILE=".tripwire-hooks.toml"

# Check if TripWire hooks are enabled
if [ ! -f "$CONFIG_FILE" ]; then
    echo "Warning: TripWire hook configuration not found"
    exit 0
fi

# Colors for output
RED='\\033[0;31m'
GREEN='\\033[0;32m'
YELLOW='\\033[1;33m'
NC='\\033[0m' # No Color

echo "Running TripWire pre-commit checks..."
echo ""

FAILED=0

# Check if schema validation is enabled
if grep -q "schema_validate = true" "$CONFIG_FILE"; then
    if [ -f ".tripwire.toml" ]; then
        echo "Validating .env against schema..."
        if ! tripwire schema validate --strict --environment development; then
            echo "${{RED}}Schema validation failed${{NC}}"
            echo "Fix errors or skip with: git commit --no-verify"
            FAILED=1
        else
            echo "${{GREEN}}Schema validation passed${{NC}}"
        fi
        echo ""
    fi
fi

# Check if secret scan is enabled
if grep -q "secret_scan = true" "$CONFIG_FILE"; then
    echo "Scanning for secrets..."
    if ! tripwire scan --strict --depth 10; then
        echo "${{RED}}Secret scan failed${{NC}}"
        echo "Fix secrets or skip with: git commit --no-verify"
        FAILED=1
    else
        echo "${{GREEN}}No secrets detected${{NC}}"
    fi
    echo ""
fi

# Check if drift check is enabled
if grep -q "drift_check = true" "$CONFIG_FILE"; then
    if [ -f ".env" ] && [ -f ".env.example" ]; then
        echo "Checking for .env drift..."
        if ! tripwire check --strict; then
            echo "${{RED}}Drift check failed${{NC}}"
            echo "Sync with: tripwire sync"
            # Don't fail on drift, just warn
            echo "${{YELLOW}}Warning: .env differs from .env.example${{NC}}"
        else
            echo "${{GREEN}}No drift detected${{NC}}"
        fi
        echo ""
    fi
fi

if [ $FAILED -eq 1 ]; then
    echo "${{RED}}TripWire pre-commit checks failed${{NC}}"
    echo "To skip these checks: git commit --no-verify"
    exit 1
fi

echo "${{GREEN}}All TripWire checks passed${{NC}}"
exit 0
"""

    pre_commit_hook.write_text(hook_content)

    # Make hook executable
    current_perms = pre_commit_hook.stat().st_mode
    pre_commit_hook.chmod(current_perms | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)

    console.print(f"[green][OK][/green] Created {pre_commit_hook}")
    console.print(f"[green][OK][/green] Made hook executable")

    console.print("\n[bold green]Hooks installed successfully![/bold green]\n")
    console.print("[bold cyan]What happens now:[/bold cyan]")
    console.print("  - Every commit will automatically:")
    console.print("    1. Validate .env against schema (if .tripwire.toml exists)")
    console.print("    2. Scan for secrets in staged files")
    console.print("    3. Optionally check for .env drift\n")

    console.print("[bold cyan]Configuration:[/bold cyan]")
    console.print(f"  - Edit {config_file} to customize checks")
    console.print("  - Enable/disable individual checks")
    console.print("  - Configure strictness levels\n")

    console.print("[bold cyan]To bypass hooks:[/bold cyan]")
    console.print("  git commit --no-verify")


__all__ = ["install_hooks"]
