#!/usr/bin/env bash

# Lacy Shell CLI
# https://github.com/lacymorrow/lacy
#
# Usage: lacy [command] [options]
#
# Set LACY_NO_NODE=1 to force bash-only mode (skip fancy Node UI)

set -e

VERSION_FALLBACK="1.8.11"
INSTALL_DIR="${HOME}/.lacy"
INSTALL_DIR_OLD="${HOME}/.lacy-shell"
CONFIG_FILE="${INSTALL_DIR}/config.yaml"
REPO_URL="https://github.com/lacymorrow/lacy.git"

# Colors (ANSI-C quoting so escape bytes are real, not literal)
RED=$'\033[0;31m'
GREEN=$'\033[0;32m'
YELLOW=$'\033[1;33m'
BLUE=$'\033[0;34m'
MAGENTA=$'\033[0;35m'
CYAN=$'\033[0;36m'
BOLD=$'\033[1m'
DIM=$'\033[2m'
NC=$'\033[0m'

# ============================================================================
# Version — single source of truth is package.json
# ============================================================================

get_version() {
    local pkg_file="${INSTALL_DIR}/package.json"
    if [[ -f "$pkg_file" ]]; then
        # Extract "version": "x.y.z" without jq (pure bash/grep/sed)
        grep '"version"' "$pkg_file" 2>/dev/null | head -1 | sed 's/.*"version"[[:space:]]*:[[:space:]]*"//' | sed 's/".*//'
    fi
}

VERSION="$(get_version)"
VERSION="${VERSION:-$VERSION_FALLBACK}"

# ============================================================================
# Helpers
# ============================================================================

die() { printf "${RED}Error: %s${NC}\n" "$1" >&2; exit 1; }

info() { printf "${BLUE}%s${NC}\n" "$1"; }

success() { printf "${GREEN}✓${NC} %s\n" "$1"; }

warn() { printf "${YELLOW}%s${NC}\n" "$1"; }

is_installed() {
    [[ -d "$INSTALL_DIR" ]] || [[ -L "$INSTALL_DIR" ]] || [[ -d "$INSTALL_DIR_OLD" ]]
}

command_exists() {
    command -v "$1" >/dev/null 2>&1
}

detect_shell() {
    local shell
    shell=$(basename "${SHELL:-}")
    case "$shell" in
        zsh|bash) echo "$shell" ;;
        *)
            # Detect from the running process if $SHELL is unhelpful
            if [[ -n "${BASH_VERSION:-}" ]]; then
                echo "bash"
            elif [[ -n "${ZSH_VERSION:-}" ]]; then
                echo "zsh"
            elif command_exists bash; then
                echo "bash"
            elif command_exists zsh; then
                echo "zsh"
            else
                echo "bash"
            fi
            ;;
    esac
}

update_via_tarball() {
    local dir="$1"
    local tarball_url="https://github.com/lacymorrow/lacy/archive/refs/heads/main.tar.gz"
    local tmp_file
    tmp_file=$(mktemp)
    curl -fsSL "$tarball_url" -o "$tmp_file" 2>/dev/null || { rm -f "$tmp_file"; return 1; }
    # Extract over existing directory
    tar xzf "$tmp_file" --strip-components=1 -C "$dir" 2>/dev/null || { rm -f "$tmp_file"; return 1; }
    rm -f "$tmp_file"
    return 0
}

get_rc_file() {
    case "$(detect_shell)" in
        bash)
            if [[ "$OSTYPE" == "darwin"* ]]; then
                echo "${HOME}/.bash_profile"
            else
                echo "${HOME}/.bashrc"
            fi
            ;;
        *)    echo "${HOME}/.zshrc" ;;
    esac
}

get_plugin_file() {
    case "$(detect_shell)" in
        bash) echo "lacy.plugin.bash" ;;
        *)    echo "lacy.plugin.zsh" ;;
    esac
}

# Parse a simple YAML value (strips inline comments and quotes)
yaml_value() {
    local file="$1" key="$2"
    grep "^[[:space:]]*${key}:" "$file" 2>/dev/null | head -1 | sed 's/^[^:]*:[[:space:]]*//' | sed 's/[[:space:]]*#.*//' | tr -d '"' | tr -d "'"
}

# Write a YAML value (replace in-place within a section)
yaml_write() {
    local file="$1" key="$2" value="$3"
    # Escape sed special chars in value (delimiter is |)
    local escaped_value="${value//\\/\\\\}"
    escaped_value="${escaped_value//|/\\|}"
    escaped_value="${escaped_value//&/\\&}"
    if grep -q "^[[:space:]]*${key}:" "$file" 2>/dev/null; then
        # Replace existing key — handles both "key: value" and "key:" (empty)
        sed -i.bak "s|^\\([[:space:]]*${key}:\\).*|\\1 ${escaped_value}|" "$file"
        rm -f "${file}.bak"
    fi
}

# Try Node CLI for rich interactive experience
# Falls back silently if Node unavailable or LACY_NO_NODE=1
# Respects LACY_CHANNEL (default: latest) for beta testing
try_node() {
    [[ "${LACY_NO_NODE:-}" == "1" ]] && return 1
    command_exists npx && [[ -t 0 ]] || return 1
    local pkg="lacy@${LACY_CHANNEL:-latest}"
    npx --yes "$pkg" "$@" && exit 0
    return 1
}

# Offer to restart the shell
offer_restart() {
    if [[ -t 0 ]]; then
        printf "\nRestart shell now to apply changes? [Y/n]: "
        read -r restart
        if [[ ! "$restart" =~ ^[Nn]$ ]]; then
            local shell_cmd
            shell_cmd=$(detect_shell)
            info "Restarting ${shell_cmd}..."
            exec "$shell_cmd" -l
        fi
    fi
}

# All RC files (for cleanup)
ALL_RC_FILES=(
    "${HOME}/.zshrc"
    "${HOME}/.bashrc"
    "${HOME}/.bash_profile"
    "${HOME}/.config/fish/conf.d/lacy.fish"
)

# ============================================================================
# Commands
# ============================================================================

cmd_install() {
    # Try fancy Node installer first
    try_node "$@" || true

    # Fallback: run install.sh from repo or curl
    if [[ -f "${INSTALL_DIR}/install.sh" ]]; then
        exec bash "${INSTALL_DIR}/install.sh" "$@"
    fi

    info "Downloading installer..."
    exec bash <(curl -fsSL https://lacy.sh/install) "$@"
}

cmd_uninstall() {
    if ! is_installed; then
        warn "Lacy Shell is not installed"
        exit 0
    fi

    # Try fancy Node uninstaller first (suppress npx errors — bash fallback handles it)
    try_node --uninstall 2>/dev/null || true

    # Bash fallback
    if [[ -t 0 ]]; then
        printf "Are you sure you want to uninstall Lacy Shell? [y/N]: "
        read -r confirm
        if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
            echo "Cancelled."
            exit 0
        fi
    fi

    info "Uninstalling Lacy Shell..."

    # Remove from all RC files
    for rc in "${ALL_RC_FILES[@]}"; do
        if [[ -f "$rc" ]] && grep -q "lacy.plugin" "$rc" 2>/dev/null; then
            local tmp
            tmp=$(mktemp)
            grep -v "lacy.plugin" "$rc" | grep -v "# Lacy Shell" > "$tmp" || true
            grep -v '\.lacy/bin' "$tmp" > "${tmp}.2" || true
            mv "${tmp}.2" "$rc"
            rm -f "$tmp"
            success "Cleaned $(basename "$rc")"
        fi
    done

    # Detect Homebrew-managed install (symlink to Homebrew prefix)
    local is_brew=false
    if [[ -L "$INSTALL_DIR" ]]; then
        local link_target
        link_target=$(readlink "$INSTALL_DIR" 2>/dev/null || true)
        if [[ "$link_target" == *"/Cellar/"* || "$link_target" == *"/homebrew/"* ]]; then
            is_brew=true
        fi
    fi

    # Remove ~/.lacy symlink or directory
    if [[ -L "$INSTALL_DIR" ]]; then
        rm -f "$INSTALL_DIR"
        success "Removed $INSTALL_DIR symlink"
    elif [[ -d "$INSTALL_DIR" ]]; then
        rm -rf "$INSTALL_DIR"
        success "Removed $INSTALL_DIR"
    fi
    if [[ -d "$INSTALL_DIR_OLD" ]]; then
        rm -rf "$INSTALL_DIR_OLD"
        success "Removed $INSTALL_DIR_OLD"
    fi

    # If installed via Homebrew, uninstall the formula too
    if [[ "$is_brew" == true ]] && command_exists brew; then
        info "Removing Homebrew formula..."
        brew uninstall lacymorrow/tap/lacy 2>/dev/null && success "Homebrew formula removed" || true
    fi

    printf "\n${GREEN}Lacy Shell uninstalled.${NC}\n"

    offer_restart
    echo "Restart your terminal to apply changes."
}

cmd_update() {
    if ! is_installed; then
        die "Lacy Shell is not installed. Run: lacy install"
    fi

    local dir="$INSTALL_DIR"
    [[ -d "$dir" ]] || dir="$INSTALL_DIR_OLD"

    info "Updating Lacy Shell..."

    if [[ -d "${dir}/.git" ]] && command_exists git; then
        if git -C "$dir" pull origin main 2>/dev/null || git -C "$dir" pull 2>/dev/null; then
            VERSION="$(get_version)"
            VERSION="${VERSION:-$VERSION_FALLBACK}"
            success "Lacy Shell updated to v${VERSION}"
        else
            die "Update failed. Try: lacy reinstall"
        fi
    elif command_exists curl; then
        update_via_tarball "$dir" || die "Update failed. Try: lacy reinstall"
        VERSION="$(get_version)"
        VERSION="${VERSION:-$VERSION_FALLBACK}"
        success "Lacy Shell updated to v${VERSION}"
    else
        die "Neither git nor curl available. Cannot update."
    fi
}

cmd_reinstall() {
    info "Reinstalling Lacy Shell..."

    # Backup user config before removing
    local config_backup=""
    if [[ -f "$CONFIG_FILE" ]]; then
        config_backup=$(mktemp)
        cp "$CONFIG_FILE" "$config_backup"
    fi

    # Remove existing
    [[ -d "$INSTALL_DIR" ]] && rm -rf "$INSTALL_DIR"
    [[ -d "$INSTALL_DIR_OLD" ]] && rm -rf "$INSTALL_DIR_OLD"

    # Install fresh (git with tarball fallback)
    local installed=false
    if command_exists git; then
        git clone --depth 1 "$REPO_URL" "$INSTALL_DIR" 2>/dev/null && installed=true
    fi
    if [[ "$installed" == false ]] && command_exists curl; then
        local tarball_url="https://github.com/lacymorrow/lacy/archive/refs/heads/main.tar.gz"
        local tmp_file
        tmp_file=$(mktemp)
        curl -fsSL "$tarball_url" -o "$tmp_file" 2>/dev/null && \
            mkdir -p "$INSTALL_DIR" && \
            tar xzf "$tmp_file" --strip-components=1 -C "$INSTALL_DIR" 2>/dev/null && \
            installed=true
        rm -f "$tmp_file"
    fi
    [[ "$installed" == false ]] && die "Install failed. Need git or curl."

    # Restore user config
    if [[ -n "$config_backup" ]]; then
        mkdir -p "$(dirname "$CONFIG_FILE")"
        cp "$config_backup" "$CONFIG_FILE"
        rm -f "$config_backup"
        success "Configuration preserved"
    fi

    # Re-read version after reinstall
    VERSION="$(get_version)"
    VERSION="${VERSION:-$VERSION_FALLBACK}"
    success "Lacy Shell reinstalled (v${VERSION})"

    # Ensure shell is configured
    local rc_file plugin_file source_line
    rc_file=$(get_rc_file)
    plugin_file=$(get_plugin_file)
    source_line="source ${INSTALL_DIR}/${plugin_file}"

    if [[ -f "$rc_file" ]] && grep -q "lacy.plugin" "$rc_file" 2>/dev/null; then
        success "Shell already configured"
    else
        mkdir -p "$(dirname "$rc_file")"
        printf "\n# Lacy Shell\n%s\n" "$source_line" >> "$rc_file"
        success "Added to $(basename "$rc_file")"
    fi

    echo ""
    echo "Restart your terminal to apply changes."
}

cmd_status() {
    printf "\n${BOLD}Lacy Shell${NC}\n\n"

    # Installation
    if is_installed; then
        local dir="$INSTALL_DIR"
        [[ -d "$dir" ]] || dir="$INSTALL_DIR_OLD"
        success "Installed at ${dir}"

        # Version from git
        if [[ -d "${dir}/.git" ]]; then
            local sha
            sha=$(git -C "$dir" rev-parse --short HEAD 2>/dev/null || echo "unknown")
            printf "  Version: %s (git: %s)\n" "$VERSION" "$sha"
        fi
    else
        printf "  ${RED}✗${NC} Not installed\n"
        printf "\n  Run: ${CYAN}lacy install${NC}\n\n"
        return
    fi

    # Shell plugin
    local rc_file
    rc_file=$(get_rc_file)
    if [[ -f "$rc_file" ]] && grep -q "lacy.plugin" "$rc_file" 2>/dev/null; then
        success "Shell configured ($(basename "$rc_file"))"
    else
        printf "  ${YELLOW}○${NC} Shell not configured\n"
    fi

    # Config
    if [[ -f "$CONFIG_FILE" ]]; then
        success "Config exists"
        local active
        active=$(yaml_value "$CONFIG_FILE" "active")
        if [[ -n "$active" ]]; then
            printf "  Active tool: ${CYAN}%s${NC}\n" "$active"
        else
            printf "  Active tool: ${DIM}auto-detect${NC}\n"
        fi
    else
        printf "  ${YELLOW}○${NC} No config file\n"
    fi

    # AI tools
    printf "\n${BOLD}AI CLI Tools${NC}\n"
    for t in lash claude opencode gemini codex hermes copilot goose amp; do
        if command_exists "$t"; then
            success "$t"
        else
            printf "  ${DIM}○${NC} ${DIM}%s${NC}\n" "$t"
        fi
    done

    # PATH
    printf "\n${BOLD}PATH${NC}\n"
    if echo "$PATH" | grep -q "${INSTALL_DIR}/bin"; then
        success "~/.lacy/bin in PATH"
    else
        printf "  ${YELLOW}○${NC} ~/.lacy/bin not in PATH\n"
    fi

    echo ""
}

cmd_info() {
    if [[ -f "${INSTALL_DIR}/lib/commands/info.sh" ]]; then
        bash "${INSTALL_DIR}/lib/commands/info.sh"
    else
        printf '\033[38;5;75m%s\033[0m\n' "🔧 Lacy Shell v$VERSION"
        echo
        printf '%s\n' "Lacy Shell detects natural language and routes it to AI coding agents."
        echo
        printf '%s\n' "Quick tips:"
        printf '  • %s\n' "Type normally for shell commands"
        printf '  • %s\n' "Type natural language for AI assistance"
        printf '  • %s\n' "Press Ctrl+Space to toggle modes"
        echo
        printf '%b\n' "Run '\033[38;5;200mlacy setup\033[0m' to configure your AI tool and settings."
        printf '%b\n' "Run '\033[38;5;200mlacy mode\033[0m' to see current mode and legend."
    fi
}

cmd_doctor() {
    printf "\n${BOLD}Lacy Shell Doctor${NC} ${DIM}v${VERSION}${NC}\n\n"

    local issues=0

    # Check installation
    if is_installed; then
        success "Installation found"
    else
        printf "  ${RED}✗${NC} Not installed\n"
        printf "    Fix: ${CYAN}lacy install${NC}\n"
        issues=$((issues + 1))
    fi

    # Check shell plugin
    local shell rc_file
    shell=$(detect_shell)
    rc_file=$(get_rc_file)

    if [[ -f "$rc_file" ]] && grep -q "lacy.plugin" "$rc_file" 2>/dev/null; then
        success "Shell plugin sourced in $(basename "$rc_file")"
    else
        printf "  ${RED}✗${NC} Shell plugin not in $(basename "$rc_file")\n"
        printf "    Fix: Add ${CYAN}source ~/.lacy/lacy.plugin.%s${NC} to %s\n" "$shell" "$(basename "$rc_file")"
        issues=$((issues + 1))
    fi

    # Check plugin file exists
    local plugin_file
    plugin_file=$(get_plugin_file)
    if [[ -f "${INSTALL_DIR}/${plugin_file}" ]]; then
        success "Plugin file exists (${plugin_file})"
    else
        printf "  ${RED}✗${NC} Plugin file missing: ${INSTALL_DIR}/${plugin_file}\n"
        printf "    Fix: ${CYAN}lacy reinstall${NC}\n"
        issues=$((issues + 1))
    fi

    # Check AI tool
    local found_tool=0
    for t in lash claude opencode gemini codex hermes copilot goose amp; do
        if command_exists "$t"; then
            found_tool=1
            break
        fi
    done
    if [[ $found_tool -eq 1 ]]; then
        success "AI CLI tool available"
    else
        printf "  ${YELLOW}!${NC} No AI CLI tool installed\n"
        printf "    Fix: ${CYAN}npm install -g lashcode${NC} (recommended) — lash.lacy.sh\n"
        issues=$((issues + 1))
    fi

    # Check PATH
    if echo "$PATH" | grep -q "${INSTALL_DIR}/bin"; then
        success "~/.lacy/bin in PATH"
    else
        printf "  ${YELLOW}!${NC} ~/.lacy/bin not in PATH\n"
        printf "    The ${CYAN}lacy${NC} command may not be available in new shells\n"
        issues=$((issues + 1))
    fi

    # Check config
    if [[ -f "$CONFIG_FILE" ]]; then
        success "Config file exists"
    else
        printf "  ${YELLOW}!${NC} No config file\n"
        printf "    Fix: ${CYAN}lacy install${NC} to generate one\n"
        issues=$((issues + 1))
    fi

    # Check git (optional — tarball fallback available)
    if command_exists git; then
        success "git available"
    else
        printf "  ${YELLOW}○${NC} git not found (optional, updates use curl fallback)\n"
    fi

    # Check curl
    if command_exists curl; then
        success "curl available"
    else
        printf "  ${YELLOW}!${NC} curl not found\n"
        issues=$((issues + 1))
    fi

    echo ""
    if [[ $issues -eq 0 ]]; then
        printf "${GREEN}All checks passed!${NC}\n"
    else
        printf "${YELLOW}%d issue(s) found${NC}\n" "$issues"
    fi
    echo ""
}

cmd_config() {
    if [[ ! -f "$CONFIG_FILE" ]]; then
        die "No config file. Run: lacy install"
    fi

    case "$1" in
        edit)
            local editor="${EDITOR:-${VISUAL:-vi}}"
            exec "$editor" "$CONFIG_FILE"
            ;;
        path)
            echo "$CONFIG_FILE"
            ;;
        show|"")
            cat "$CONFIG_FILE"
            ;;
        *)
            echo "Usage: lacy config [show|edit|path]"
            ;;
    esac
}

cmd_setup() {
    if ! is_installed; then
        die "Lacy Shell is not installed. Run: lacy install"
    fi

    # Try fancy Node setup first
    try_node setup || true

    # Bash fallback: simple numbered menu
    cmd_setup_bash
}

cmd_setup_bash() {
    if [[ ! -f "$CONFIG_FILE" ]]; then
        die "No config file. Run: lacy install"
    fi

    while true; do
        local active mode
        active=$(yaml_value "$CONFIG_FILE" "active")
        mode=$(yaml_value "$CONFIG_FILE" "default")

        printf "\n${BOLD}Lacy Shell${NC} ${DIM}v${VERSION}${NC}\n\n"
        printf "  1) Change AI tool     ${DIM}(current: ${active:-auto-detect})${NC}\n"
        printf "  2) Change mode        ${DIM}(current: ${mode:-auto})${NC}\n"
        printf "  3) Edit config        ${DIM}(open in \$EDITOR)${NC}\n"
        printf "  4) Back\n"
        printf "\n"

        read -p "Select [1-4]: " choice

        case "$choice" in
            1) setup_tool ;;
            2) setup_mode ;;
            3)
                local editor="${EDITOR:-${VISUAL:-vi}}"
                "$editor" "$CONFIG_FILE"
                ;;
            4|"") break ;;
            *) warn "Invalid choice" ;;
        esac
    done
}

setup_tool() {
    printf "\n${BOLD}Select AI tool${NC}\n\n"

    local i=1
    local tools=("lash" "claude" "opencode" "gemini" "codex" "hermes" "copilot" "goose" "amp" "custom" "auto")
    local hints=("AI coding agent (recommended)" "Claude Code CLI" "OpenCode CLI" "Google Gemini CLI" "OpenAI Codex CLI" "Hermes Agent CLI" "GitHub Copilot CLI" "Goose CLI" "Sourcegraph Amp CLI" "enter your own command" "use first available")

    for t in "${tools[@]}"; do
        local hint="${hints[$((i-1))]}"
        if [[ "$t" != "custom" && "$t" != "auto" ]] && command_exists "$t"; then
            printf "  ${GREEN}%d)${NC} %-12s ${GREEN}installed${NC}\n" "$i" "$t"
        else
            printf "  %d) %-12s ${DIM}%s${NC}\n" "$i" "$t" "$hint"
        fi
        i=$((i + 1))
    done
    printf "\n"

    read -p "Select [1-${#tools[@]}]: " choice

    if [[ -z "$choice" ]] || ! [[ "$choice" =~ ^[0-9]+$ ]] || [[ "$choice" -lt 1 ]] || [[ "$choice" -gt ${#tools[@]} ]]; then
        warn "Cancelled"
        return
    fi

    local selected="${tools[$((choice-1))]}"

    if [[ "$selected" == "custom" ]]; then
        read -p "Enter custom command: " custom_cmd
        if [[ -z "$custom_cmd" ]]; then
            warn "No command entered. Cancelled."
            return
        fi
        yaml_write "$CONFIG_FILE" "active" "custom"
        yaml_write "$CONFIG_FILE" "custom_command" "\"$custom_cmd\""
        success "Tool set to: custom ($custom_cmd)"
    elif [[ "$selected" == "auto" ]]; then
        yaml_write "$CONFIG_FILE" "active" ""
        success "Tool set to: auto-detect"
    else
        yaml_write "$CONFIG_FILE" "active" "$selected"
        success "Tool set to: $selected"
    fi

    offer_restart
}

setup_mode() {
    printf "\n${BOLD}Select default mode${NC}\n\n"
    printf "  1) auto     ${DIM}smart detection (recommended)${NC}\n"
    printf "  2) shell    ${DIM}all commands execute directly${NC}\n"
    printf "  3) agent    ${DIM}all input goes to AI${NC}\n"
    printf "\n"

    read -p "Select [1-3]: " choice

    case "$choice" in
        1) yaml_write "$CONFIG_FILE" "default" "auto"; success "Mode set to: auto" ;;
        2) yaml_write "$CONFIG_FILE" "default" "shell"; success "Mode set to: shell" ;;
        3) yaml_write "$CONFIG_FILE" "default" "agent"; success "Mode set to: agent" ;;
        *) warn "Cancelled"; return ;;
    esac

    offer_restart
}

cmd_enter() {
    # Already inside a lacy shell session — show info instead of nesting
    if [[ "${LACY_SHELL_ACTIVE:-}" == "1" ]]; then
        cmd_info
        return
    fi

    if ! is_installed; then
        die "Lacy Shell is not installed. Run: lacy install"
    fi

    # Launch an interactive shell — the plugin loads from .zshrc/.bashrc
    local shell
    shell=$(detect_shell)
    exec "$shell" -li
}

cmd_new() {
    local shell_home="${LACY_SHELL_HOME:-${HOME}/.lacy}"
    local last_session_file="${shell_home}/.last_session"
    if [[ -f "$last_session_file" ]]; then
        rm -f "$last_session_file"
        success "Last session cleared"
    else
        info "No saved session to clear"
    fi
    printf '\n%b\n' "Next query will start a fresh context."
}

cmd_resume() {
    local shell_home="${LACY_SHELL_HOME:-${HOME}/.lacy}"
    local last_session_file="${shell_home}/.last_session"
    if [[ ! -f "$last_session_file" ]]; then
        warn "No previous session found"
        printf '\n%b\n' "Start chatting to create a session, then use ${CYAN}resume${NC} to pick it up in another shell."
        return 1
    fi

    local saved_tool saved_id
    { read -r saved_tool; read -r saved_id; } < "$last_session_file"

    if [[ -z "$saved_tool" || -z "$saved_id" ]]; then
        warn "Saved session file is empty"
        return 1
    fi

    printf '\n%b\n' "${BOLD}Last session${NC}"
    printf '  Tool:    %s\n' "$saved_tool"
    printf '  Session: %s\n' "$saved_id"
    printf '\n%b\n' "Type ${CYAN}resume${NC} inside Lacy Shell to load this session."
}

cmd_logs() {
    local log_file="${INSTALL_DIR}/logs/queries.log"

    case "${1:-}" in
        --clear|-c)
            if [[ -f "$log_file" ]]; then
                rm -f "$log_file"
                success "Query log cleared"
            else
                info "No log file found"
            fi
            return
            ;;
        --count)
            if [[ -f "$log_file" ]]; then
                local count
                count=$(wc -l < "$log_file" 2>/dev/null || echo 0)
                printf "Entries: %s\n" "$count"
            else
                echo "0"
            fi
            return
            ;;
    esac

    if [[ ! -f "$log_file" ]]; then
        info "No queries logged yet."
        printf '\nStart using Lacy Shell and queries will appear here.\n\n'
        return
    fi

    local limit="${1:-50}"
    if [[ "$limit" =~ ^[0-9]+$ ]]; then
        printf "\n${BOLD}Recent queries${NC} ${DIM}(last %s)${NC}\n\n" "$limit"
        tail -n "$limit" "$log_file" | while IFS=$'\t' read -r ts tool query; do
            printf "  ${DIM}%s${NC}  ${CYAN}%-12s${NC}  %s\n" "$ts" "$tool" "$query"
        done
    else
        printf "\n${BOLD}All queries${NC}\n\n"
        while IFS=$'\t' read -r ts tool query; do
            printf "  ${DIM}%s${NC}  ${CYAN}%-12s${NC}  %s\n" "$ts" "$tool" "$query"
        done < "$log_file"
    fi
    echo ""
    printf "${DIM}Log: %s${NC}\n\n" "$log_file"
}

cmd_changelog() {
    printf "\n${BOLD}Lacy Shell Changelog${NC}\n\n"

    # Try fetching from GitHub releases API
    if command_exists curl; then
        local json
        json=$(curl -sf --max-time 5 \
            -H "Accept: application/vnd.github+json" \
            "https://api.github.com/repos/lacymorrow/lacy/releases/latest" 2>/dev/null || true)

        if [[ -n "$json" ]]; then
            local tag body
            tag=$(printf '%s\n' "$json" | grep '"tag_name"' | head -1 | sed 's/.*"tag_name"[[:space:]]*:[[:space:]]*"//' | sed 's/".*//')
            body=$(printf '%s\n' "$json" | python3 -c "
import json, sys
try:
    d = json.loads(sys.stdin.read())
    print(d.get('body', ''))
except: pass" 2>/dev/null || true)

            if [[ -n "$tag" ]]; then
                printf "${CYAN}Latest release: %s${NC}\n\n" "$tag"
                if [[ -n "$body" ]]; then
                    printf '%s\n' "$body"
                else
                    printf "${DIM}No release notes.${NC}\n"
                fi
                echo ""
                return
            fi
        fi
    fi

    # Fallback: show local CHANGELOG.md if present
    local changelog_file="${INSTALL_DIR}/CHANGELOG.md"
    if [[ -f "$changelog_file" ]]; then
        head -n 80 "$changelog_file"
        echo ""
        return
    fi

    # Last resort: recent git log
    if [[ -d "${INSTALL_DIR}/.git" ]]; then
        warn "Could not fetch release notes (offline?). Showing recent commits:"
        echo ""
        git -C "$INSTALL_DIR" log --oneline -20 2>/dev/null || true
    else
        warn "Could not fetch changelog. Run \`lacy update\` to get the latest version."
    fi
    echo ""
}

cmd_completions() {
    local shell_type="${1:-}"

    # Auto-detect if not specified
    if [[ -z "$shell_type" ]]; then
        shell_type=$(detect_shell)
    fi

    case "$shell_type" in
        zsh)  _completions_zsh ;;
        bash) _completions_bash ;;
        *)
            warn "Unknown shell: $shell_type. Use 'zsh' or 'bash'."
            exit 1
            ;;
    esac
}

_completions_zsh() {
    cat <<'ZSHCOMP'
#compdef lacy

_lacy() {
    local -a commands
    commands=(
        'setup:Interactive settings (tool, mode, config)'
        'install:Install Lacy Shell'
        'uninstall:Remove Lacy Shell'
        'update:Pull latest changes'
        'reinstall:Fresh installation'
        'status:Show installation status'
        'info:Show basic information'
        'doctor:Diagnose common issues'
        'config:Show or edit configuration'
        'new:Clear saved session'
        'resume:Show saved session info'
        'logs:Show recent agent query log'
        'changelog:Show latest release notes'
        'version:Show version'
        'help:Show help'
    )

    local -a tool_names
    tool_names=(lash claude opencode gemini codex custom auto)

    case "$words[2]" in
        config)
            local -a config_sub
            config_sub=('show:Print config file' 'edit:Open in $EDITOR' 'path:Print config path')
            _describe 'config subcommand' config_sub
            ;;
        logs)
            local -a logs_sub
            logs_sub=('--clear:Clear the log file' '--count:Print entry count')
            _describe 'logs option' logs_sub
            ;;
        tool)
            case "$words[3]" in
                set) _describe 'tool name' tool_names ;;
                *)   local -a tool_sub; tool_sub=('set:Set the active tool' 'list:List available tools')
                     _describe 'tool subcommand' tool_sub ;;
            esac
            ;;
        completions)
            _describe 'shell' '(zsh bash)'
            ;;
        *)
            _describe 'lacy command' commands
            ;;
    esac
}

_lacy "$@"
ZSHCOMP
}

_completions_bash() {
    cat <<'BASHCOMP'
_lacy_completions() {
    local cur prev
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    local commands="setup install uninstall update reinstall status info doctor config new resume logs changelog version help completions"
    local tool_names="lash claude opencode gemini codex custom auto"

    case "$prev" in
        config)
            COMPREPLY=( $(compgen -W "show edit path" -- "$cur") )
            return
            ;;
        logs)
            COMPREPLY=( $(compgen -W "--clear --count" -- "$cur") )
            return
            ;;
        set)
            COMPREPLY=( $(compgen -W "$tool_names" -- "$cur") )
            return
            ;;
        tool)
            COMPREPLY=( $(compgen -W "set list" -- "$cur") )
            return
            ;;
        completions)
            COMPREPLY=( $(compgen -W "zsh bash" -- "$cur") )
            return
            ;;
    esac

    COMPREPLY=( $(compgen -W "$commands" -- "$cur") )
}

complete -F _lacy_completions lacy
BASHCOMP
}

cmd_version() {
    echo "lacy $VERSION"
    if [[ -d "${INSTALL_DIR}/.git" ]]; then
        local sha
        sha=$(git -C "$INSTALL_DIR" rev-parse --short HEAD 2>/dev/null || echo "")
        [[ -n "$sha" ]] && echo "git: $sha"
    fi
}

cmd_help() {
    local has_node=false
    if command_exists npx && [[ "${LACY_NO_NODE:-}" != "1" ]]; then
        has_node=true
    fi

    cat <<EOF
${BOLD}Lacy Shell${NC} ${DIM}v${VERSION}${NC} — Talk directly to your shell

${BOLD}Usage:${NC}
  lacy                Enter Lacy Shell (or re-enter after quit)
  lacy [command]      Run a command

${BOLD}Commands:${NC}
  setup          Interactive settings (tool, mode, config)
  install        Install Lacy Shell (interactive)
  uninstall      Remove Lacy Shell completely
  update         Pull latest changes
  reinstall      Fresh installation
  status         Show installation status
  info           Show basic information and help
  doctor         Diagnose common issues
  config         Show/edit configuration
  new            Clear saved session (start fresh next time)
  resume         Show saved session info
  logs [N]       Show last N agent queries (default: 50)
  logs --clear   Clear query log
  changelog      Show latest release notes
  completions    Print shell completion script (pipe to source)
  version        Show version
  help           Show this help

${BOLD}In-shell commands${NC} (available when Lacy is active):
  mode           Show/switch mode (shell/agent/auto)
  tool           Show/switch AI tool
  ask "query"    Direct query to AI
  new            Start fresh context (aliases: reset, clear, /new)
  resume         Resume previous session (/resume)
  Ctrl+Space     Toggle between modes

${BOLD}Environment:${NC}
  LACY_NO_NODE=1            Force bash-only mode (skip Node UI)

${DIM}https://github.com/lacymorrow/lacy${NC}
EOF

    # Show banner again at the bottom
    if [[ "$has_node" == true ]]; then
        print_setup_banner
    fi
}

print_setup_banner() {
    printf "\n"
    printf "  ${MAGENTA}${BOLD}╔════════════════════════════════════════════════╗${NC}\n"
    printf "  ${MAGENTA}${BOLD}║                                                ║${NC}\n"
    printf "  ${MAGENTA}${BOLD}║   Run ${NC}${BOLD}lacy setup${MAGENTA}${BOLD} for interactive settings      ║${NC}\n"
    printf "  ${MAGENTA}${BOLD}║                                                ║${NC}\n"
    printf "  ${MAGENTA}${BOLD}╚════════════════════════════════════════════════╝${NC}\n"
    printf "\n"
}

# ============================================================================
# Main
# ============================================================================

main() {
    local cmd="${1:-}"
    shift 2>/dev/null || true

    case "$cmd" in
        setup)      cmd_setup "$@" ;;
        install)    cmd_install "$@" ;;
        uninstall)  cmd_uninstall "$@" ;;
        update)     cmd_update "$@" ;;
        reinstall)  cmd_reinstall "$@" ;;
        status|s)   cmd_status "$@" ;;
        info)       cmd_info ;;
        doctor)     cmd_doctor "$@" ;;
        config|c)   cmd_config "$@" ;;
        new|/new|reset|/reset|clear|/clear) cmd_new "$@" ;;
        resume|/resume)                     cmd_resume "$@" ;;
        logs)         cmd_logs "$@" ;;
        changelog)    cmd_changelog "$@" ;;
        completions)  cmd_completions "$@" ;;
        version|-v|--version) cmd_version ;;
        help|-h|--help)       cmd_help ;;
        "")                   cmd_enter ;;
        *)
            printf "${RED}Unknown command: %s${NC}\n\n" "$cmd"
            cmd_help
            exit 1
            ;;
    esac
}

main "$@"
