#!/bin/bash
#
# OurDigital Skills Installer
# Portable installation tool for OurDigital Claude Skills package
#
# Usage:
#   ./install.sh              # Interactive install
#   ./install.sh --update     # Update existing installation
#   ./install.sh --uninstall  # Remove installation
#   ./install.sh --commands   # Only install/update global slash commands
#   ./install.sh --help       # Show help
#

set -e

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

# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SKILLS_DIR="$(dirname "$SCRIPT_DIR")"
REPO_DIR="$(dirname "$SKILLS_DIR")"
ENV_FILE="$HOME/.env.ourdigital"
CONFIG_DIR="$HOME/.ourdigital"
VENV_DIR="$SKILLS_DIR/.venv-ourdigital"
CLAUDE_COMMANDS_DIR="$HOME/.claude/commands"
REPO_COMMANDS_DIR="$REPO_DIR/.claude/commands"

# Print banner
print_banner() {
    echo -e "${CYAN}"
    echo "╔═══════════════════════════════════════════════════════════╗"
    echo "║                                                           ║"
    echo "║     OurDigital Skills Installer                          ║"
    echo "║     사람, 디지털, 그리고 문화                              ║"
    echo "║                                                           ║"
    echo "╚═══════════════════════════════════════════════════════════╝"
    echo -e "${NC}"
}

# Print colored messages
info() { echo -e "${BLUE}[INFO]${NC} $1"; }
success() { echo -e "${GREEN}[OK]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; }

# Check prerequisites
check_prerequisites() {
    info "Checking prerequisites..."

    local missing=()

    # Check Python 3.11+
    if command -v python3 &> /dev/null; then
        PYTHON_VERSION=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
        if [[ $(echo "$PYTHON_VERSION >= 3.11" | bc -l) -eq 1 ]]; then
            success "Python $PYTHON_VERSION"
        else
            warn "Python $PYTHON_VERSION (3.11+ recommended)"
        fi
    else
        missing+=("python3")
    fi

    # Check git
    if command -v git &> /dev/null; then
        success "Git $(git --version | cut -d' ' -f3)"
    else
        missing+=("git")
    fi

    # Check Claude Code CLI
    if command -v claude &> /dev/null; then
        success "Claude Code CLI available"
    else
        warn "Claude Code CLI not found (slash commands require it)"
    fi

    # Check 1Password CLI (optional)
    if command -v op &> /dev/null; then
        success "1Password CLI available"
        HAS_1PASSWORD=true
    else
        warn "1Password CLI not found (credentials will need manual entry)"
        HAS_1PASSWORD=false
    fi

    if [[ ${#missing[@]} -gt 0 ]]; then
        error "Missing required tools: ${missing[*]}"
        exit 1
    fi

    echo ""
}

# Create directory structure
setup_directories() {
    info "Setting up directories..."

    # Create config directory
    mkdir -p "$CONFIG_DIR/credentials"
    chmod 700 "$CONFIG_DIR"
    chmod 700 "$CONFIG_DIR/credentials"
    success "Created $CONFIG_DIR/"

    # Create logs directory
    mkdir -p "$CONFIG_DIR/logs"
    success "Created $CONFIG_DIR/logs/"

    # Create Claude commands directory
    mkdir -p "$CLAUDE_COMMANDS_DIR"
    success "Created $CLAUDE_COMMANDS_DIR/"

    echo ""
}

# Install global slash commands via symlinks
setup_global_commands() {
    info "Setting up global slash commands..."

    if [[ ! -d "$REPO_COMMANDS_DIR" ]]; then
        error "Commands directory not found: $REPO_COMMANDS_DIR"
        echo "  Make sure you're running from the our-claude-skills repository."
        return 1
    fi

    mkdir -p "$CLAUDE_COMMANDS_DIR"

    local linked=0
    local skipped=0
    local updated=0

    for cmd_file in "$REPO_COMMANDS_DIR"/*.md; do
        [[ -f "$cmd_file" ]] || continue
        local filename
        filename=$(basename "$cmd_file")
        local target="$CLAUDE_COMMANDS_DIR/$filename"

        if [[ -L "$target" ]]; then
            local current_link
            current_link=$(readlink "$target")
            if [[ "$current_link" == "$cmd_file" ]]; then
                ((skipped++)) || true
            else
                rm "$target"
                ln -s "$cmd_file" "$target"
                ((updated++)) || true
            fi
        elif [[ -f "$target" ]]; then
            warn "Skipping $filename (non-symlink file exists at $target)"
            ((skipped++)) || true
        else
            ln -s "$cmd_file" "$target"
            ((linked++)) || true
        fi
    done

    [[ $linked -gt 0 ]] && success "Linked $linked new commands"
    [[ $updated -gt 0 ]] && success "Updated $updated existing symlinks"
    [[ $skipped -gt 0 ]] && info "Skipped $skipped (already current)"

    # Count total symlinks pointing to our repo
    local total
    total=$(find "$CLAUDE_COMMANDS_DIR" -maxdepth 1 -type l -lname "$REPO_COMMANDS_DIR/*" 2>/dev/null | wc -l | tr -d ' ')
    success "Total global commands from this repo: $total"

    echo ""
}

# Remove global slash command symlinks
remove_global_commands() {
    info "Removing global slash command symlinks..."

    if [[ ! -d "$CLAUDE_COMMANDS_DIR" ]]; then
        info "No commands directory found, nothing to remove"
        return
    fi

    local removed=0
    for link in "$CLAUDE_COMMANDS_DIR"/*.md; do
        [[ -L "$link" ]] || continue
        local link_target
        link_target=$(readlink "$link")
        if [[ "$link_target" == "$REPO_COMMANDS_DIR/"* ]]; then
            rm "$link"
            ((removed++)) || true
        fi
    done

    if [[ $removed -gt 0 ]]; then
        success "Removed $removed command symlinks"
    else
        info "No symlinks from this repo found"
    fi

    echo ""
}

# Setup environment file
setup_environment() {
    info "Setting up environment file..."

    if [[ -f "$ENV_FILE" ]]; then
        warn "$ENV_FILE already exists"
        read -p "Overwrite? (y/N): " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            info "Keeping existing environment file"
            return
        fi
        cp "$ENV_FILE" "$ENV_FILE.backup.$(date +%Y%m%d%H%M%S)"
        success "Backed up existing file"
    fi

    cp "$SCRIPT_DIR/.env.ourdigital.template" "$ENV_FILE"
    chmod 600 "$ENV_FILE"
    success "Created $ENV_FILE"

    echo ""
}

# Setup credentials from 1Password or manual
setup_credentials() {
    info "Setting up credentials..."

    if [[ "$HAS_1PASSWORD" == true ]]; then
        read -p "Fetch credentials from 1Password? (Y/n): " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[Nn]$ ]]; then
            fetch_from_1password
            return
        fi
    fi

    echo -e "${YELLOW}Manual credential setup required.${NC}"
    echo "Edit $ENV_FILE with your API keys:"
    echo "  - NOTION_API_TOKEN"
    echo "  - GHOST_BLOG_ADMIN_KEY"
    echo "  - GHOST_JOURNAL_ADMIN_KEY"
    echo "  - FIGMA_ACCESS_TOKEN"
    echo ""
}

# Fetch credentials from 1Password
fetch_from_1password() {
    info "Fetching credentials from 1Password..."

    # Check if signed in
    if ! op account list &> /dev/null; then
        warn "Please sign in to 1Password CLI first"
        echo "Run: eval \$(op signin)"
        return
    fi

    # Fetch each credential
    local credentials=(
        "NOTION_API_TOKEN:OurDigital Notion:api_token"
        "GHOST_BLOG_ADMIN_KEY:OurDigital Ghost Blog:api_key"
        "GHOST_JOURNAL_ADMIN_KEY:OurDigital Ghost Journal:api_key"
        "FIGMA_ACCESS_TOKEN:OurDigital Figma:api_token"
    )

    for cred in "${credentials[@]}"; do
        IFS=':' read -r env_var item_name field <<< "$cred"

        if value=$(op item get "$item_name" --fields "$field" 2>/dev/null); then
            sed -i '' "s|^$env_var=.*|$env_var=$value|" "$ENV_FILE" 2>/dev/null || \
            sed -i "s|^$env_var=.*|$env_var=$value|" "$ENV_FILE"
            success "Fetched $env_var"
        else
            warn "Could not fetch $env_var from 1Password"
        fi
    done

    echo ""
}

# Setup Python virtual environment
setup_python_env() {
    info "Setting up Python virtual environment..."

    if [[ -d "$VENV_DIR" ]]; then
        warn "Virtual environment already exists"
        read -p "Recreate? (y/N): " -n 1 -r
        echo
        if [[ $REPLY =~ ^[Yy]$ ]]; then
            rm -rf "$VENV_DIR"
        else
            info "Using existing virtual environment"
            return
        fi
    fi

    python3 -m venv "$VENV_DIR"
    success "Created virtual environment"

    # Activate and install dependencies
    source "$VENV_DIR/bin/activate"
    pip install --upgrade pip -q
    pip install -r "$SCRIPT_DIR/requirements/base.txt" -q
    success "Installed base dependencies"

    # Install code-specific if requested
    read -p "Install Claude Code dependencies? (Y/n): " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Nn]$ ]]; then
        pip install -r "$SCRIPT_DIR/requirements/code.txt" -q
        success "Installed Code dependencies"
    fi

    deactivate
    echo ""
}

# Copy config file
setup_config() {
    info "Setting up configuration..."

    if [[ ! -f "$CONFIG_DIR/config.yaml" ]]; then
        cp "$SCRIPT_DIR/config/ourdigital.yaml" "$CONFIG_DIR/config.yaml"
        success "Created $CONFIG_DIR/config.yaml"
    else
        info "Config file already exists, skipping"
    fi

    echo ""
}

# Validate installation
validate_installation() {
    info "Validating installation..."

    local checks_passed=0
    local checks_total=7

    # Check directories
    [[ -d "$CONFIG_DIR" ]] && { ((checks_passed++)) || true; success "Config directory exists"; } || warn "Config directory missing"
    [[ -d "$CONFIG_DIR/credentials" ]] && { ((checks_passed++)) || true; success "Credentials directory exists"; } || warn "Credentials directory missing"

    # Check files
    [[ -f "$ENV_FILE" ]] && { ((checks_passed++)) || true; success "Environment file exists"; } || warn "Environment file missing"
    [[ -f "$CONFIG_DIR/config.yaml" ]] && { ((checks_passed++)) || true; success "Config file exists"; } || warn "Config file missing"

    # Check virtual environment
    [[ -d "$VENV_DIR" ]] && { ((checks_passed++)) || true; success "Virtual environment exists"; } || warn "Virtual environment missing"

    # Check skills directory
    [[ -d "$SKILLS_DIR/01-ourdigital-brand-guide" ]] && { ((checks_passed++)) || true; success "Skills directory valid"; } || warn "Skills not found"

    # Check global commands
    local cmd_count
    cmd_count=$(find "$CLAUDE_COMMANDS_DIR" -maxdepth 1 -type l -lname "$REPO_COMMANDS_DIR/*" 2>/dev/null | wc -l | tr -d ' ')
    if [[ $cmd_count -gt 0 ]]; then
        ((checks_passed++)) || true
        success "Global slash commands installed ($cmd_count commands)"
    else
        warn "No global slash commands found (run with --commands to install)"
    fi

    echo ""
    echo -e "${CYAN}Validation: $checks_passed/$checks_total checks passed${NC}"
    echo ""
}

# Show installed skills
show_skills() {
    info "Installed Skills:"
    echo ""

    local categories=(
        "OurDigital Core:0{1,2,3,4,5,6,7,8,9}-ourdigital-*,10-ourdigital-*"
        "SEO Tools:1{1,2,3,4,5,6,7,8,9}-seo-*,2{0,1,2,3,4,5,6,7,8,9}-seo-*,3{0,1,2,3,4}-seo-*"
        "Jamie Clinic:4{0,1,2,3,4,5}-jamie-*"
        "NotebookLM:5{0,1,2,3}-notebooklm-*"
        "GTM/GA:6{0,1,2}-gtm-*"
        "Notion:3{1,2}-notion-*"
        "Reference & Multi-Agent:9{0,1}-*"
    )

    for category in "${categories[@]}"; do
        IFS=':' read -r label patterns <<< "$category"
        local count=0
        local names=()

        IFS=',' read -ra pattern_arr <<< "$patterns"
        for pattern in "${pattern_arr[@]}"; do
            for dir in "$SKILLS_DIR"/$pattern; do
                if [[ -d "$dir" ]]; then
                    ((count++)) || true
                    names+=("$(basename "$dir")")
                fi
            done
        done

        if [[ $count -gt 0 ]]; then
            echo -e "  ${CYAN}$label${NC} ($count skills)"
            for name in "${names[@]}"; do
                echo -e "    ${GREEN}✓${NC} $name"
            done
            echo ""
        fi
    done
}

# Show global command summary
show_global_commands() {
    info "Global Slash Commands (available from any project):"
    echo ""

    if [[ ! -d "$CLAUDE_COMMANDS_DIR" ]]; then
        warn "No commands directory found"
        return
    fi

    local cmd_count=0
    local categories=()

    for link in "$CLAUDE_COMMANDS_DIR"/*.md; do
        [[ -L "$link" ]] || continue
        local link_target
        link_target=$(readlink "$link")
        if [[ "$link_target" == "$REPO_COMMANDS_DIR/"* ]]; then
            ((cmd_count++)) || true
            local name
            name=$(basename "$link" .md)
            categories+=("$name")
        fi
    done

    if [[ $cmd_count -eq 0 ]]; then
        warn "No commands symlinked from this repo"
        return
    fi

    # Group by prefix
    local seo=0 gtm=0 jamie=0 notebooklm=0 notion=0 ourdigital=0 other=0
    for name in "${categories[@]}"; do
        case "$name" in
            seo-*) ((seo++)) || true ;;
            gtm-*) ((gtm++)) || true ;;
            jamie-*) ((jamie++)) || true ;;
            notebooklm-*) ((notebooklm++)) || true ;;
            notion-*) ((notion++)) || true ;;
            ourdigital-*) ((ourdigital++)) || true ;;
            *) ((other++)) || true ;;
        esac
    done

    [[ $seo -gt 0 ]] && echo -e "  ${GREEN}SEO${NC}: $seo commands (/seo-technical, /seo-keyword-strategy, ...)"
    [[ $gtm -gt 0 ]] && echo -e "  ${GREEN}GTM${NC}: $gtm commands (/gtm-audit, /gtm-manager)"
    [[ $jamie -gt 0 ]] && echo -e "  ${GREEN}Jamie${NC}: $jamie commands (/jamie-editor, /jamie-audit)"
    [[ $notebooklm -gt 0 ]] && echo -e "  ${GREEN}NotebookLM${NC}: $notebooklm commands (/notebooklm-agent, ...)"
    [[ $notion -gt 0 ]] && echo -e "  ${GREEN}Notion${NC}: $notion commands (/notion-writer, /notion-organizer)"
    [[ $ourdigital -gt 0 ]] && echo -e "  ${GREEN}OurDigital${NC}: $ourdigital commands (/ourdigital-research, ...)"
    [[ $other -gt 0 ]] && echo -e "  ${GREEN}Other${NC}: $other commands"
    echo ""
    echo -e "  ${CYAN}Total: $cmd_count global commands${NC}"
    echo ""
}

# Print usage instructions
print_usage() {
    echo -e "${CYAN}Usage Instructions:${NC}"
    echo ""
    echo "1. Activate the virtual environment:"
    echo "   source $VENV_DIR/bin/activate"
    echo ""
    echo "2. Edit credentials if needed:"
    echo "   nano $ENV_FILE"
    echo ""
    echo "3. Use slash commands from any project (globally installed):"
    echo "   /seo-technical https://example.com"
    echo "   /reference-curator \"Claude Code best practices\""
    echo "   /ourdigital-research \"topic\""
    echo "   /notebooklm-agent"
    echo ""
    echo "4. Update commands after pulling repo changes:"
    echo "   ./install.sh --commands"
    echo ""
}

# Uninstall
uninstall() {
    warn "This will remove OurDigital configuration and global commands (not skill source files)."
    read -p "Continue? (y/N): " -n 1 -r
    echo

    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        info "Cancelled"
        exit 0
    fi

    # Remove global command symlinks
    remove_global_commands

    # Backup before removing
    if [[ -f "$ENV_FILE" ]]; then
        cp "$ENV_FILE" "$ENV_FILE.uninstall.backup"
        rm "$ENV_FILE"
        success "Removed $ENV_FILE (backup saved)"
    fi

    if [[ -d "$VENV_DIR" ]]; then
        rm -rf "$VENV_DIR"
        success "Removed virtual environment"
    fi

    info "Config directory preserved at $CONFIG_DIR"
    info "To fully remove: rm -rf $CONFIG_DIR"

    success "Uninstall complete"
}

# Show help
show_help() {
    echo "OurDigital Skills Installer"
    echo ""
    echo "Usage: ./install.sh [OPTIONS]"
    echo ""
    echo "Options:"
    echo "  --help, -h       Show this help message"
    echo "  --update, -u     Update existing installation"
    echo "  --uninstall      Remove installation (preserves skill source files)"
    echo "  --validate       Only run validation checks"
    echo "  --commands       Only install/update global slash commands"
    echo "  --skip-creds     Skip credentials setup"
    echo "  --skip-venv      Skip virtual environment setup"
    echo ""
    echo "Examples:"
    echo "  ./install.sh                    # Full interactive install"
    echo "  ./install.sh --update           # Update existing setup"
    echo "  ./install.sh --commands         # Just install/refresh global commands"
    echo "  ./install.sh --skip-creds       # Install without credentials"
    echo ""
    echo "Global Commands:"
    echo "  Slash commands are symlinked to ~/.claude/commands/ so they"
    echo "  work from any project directory in Claude Code."
    echo ""
}

# Main installation flow
main_install() {
    print_banner
    check_prerequisites
    setup_directories
    setup_global_commands
    setup_environment

    if [[ "$SKIP_CREDS" != true ]]; then
        setup_credentials
    fi

    if [[ "$SKIP_VENV" != true ]]; then
        setup_python_env
    fi

    setup_config
    validate_installation
    show_skills
    show_global_commands
    print_usage

    echo -e "${GREEN}╔═══════════════════════════════════════════════════════════╗${NC}"
    echo -e "${GREEN}║           Installation Complete!                         ║${NC}"
    echo -e "${GREEN}╚═══════════════════════════════════════════════════════════╝${NC}"
}

# Parse arguments
SKIP_CREDS=false
SKIP_VENV=false

while [[ $# -gt 0 ]]; do
    case $1 in
        --help|-h)
            show_help
            exit 0
            ;;
        --uninstall)
            uninstall
            exit 0
            ;;
        --validate)
            validate_installation
            show_global_commands
            exit 0
            ;;
        --commands)
            info "Installing/updating global slash commands..."
            setup_global_commands
            show_global_commands
            exit 0
            ;;
        --update|-u)
            info "Updating installation..."
            setup_global_commands
            setup_python_env
            validate_installation
            show_global_commands
            exit 0
            ;;
        --skip-creds)
            SKIP_CREDS=true
            shift
            ;;
        --skip-venv)
            SKIP_VENV=true
            shift
            ;;
        *)
            error "Unknown option: $1"
            show_help
            exit 1
            ;;
    esac
done

# Run main install
main_install
