#!/usr/bin/env bash
#
# initech installer
#
# One-liner:
#   curl -fsSL https://initech.sh/install.sh | bash
#
# Options:
#   --version vX.Y.Z   Install specific version (default: latest)
#   --dest DIR         Install to DIR on Linux (default: ~/.local/bin)
#
# macOS: installs via Homebrew (brew tap nmelo/tap && brew install initech)
# Linux: downloads binary from GitHub Releases to ~/.local/bin
#
set -euo pipefail

# ═══════════════════════════════════════════════════════════════════════════════
# Configuration
# ═══════════════════════════════════════════════════════════════════════════════

OWNER="nmelo"
REPO="initech"
GITHUB_RELEASE_URL="https://github.com/${OWNER}/${REPO}/releases"
DEFAULT_INSTALL_DIR="$HOME/.local/bin"
VERSION="${INITECH_VERSION:-latest}"
DEST="${INITECH_INSTALL_DIR:-$DEFAULT_INSTALL_DIR}"

# ═══════════════════════════════════════════════════════════════════════════════
# Argument Parsing
# ═══════════════════════════════════════════════════════════════════════════════

while [[ $# -gt 0 ]]; do
    case "$1" in
        --version) VERSION="$2"; shift 2 ;;
        --dest)    DEST="$2"; shift 2 ;;
        *)         shift ;;
    esac
done

# ═══════════════════════════════════════════════════════════════════════════════
# Colors & Output
# ═══════════════════════════════════════════════════════════════════════════════

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
DIM='\033[2m'
BOLD='\033[1m'
RESET='\033[0m'

if [ ! -t 1 ]; then
    RED='' GREEN='' YELLOW='' BLUE='' CYAN='' DIM='' BOLD='' RESET=''
fi

info()  { echo -e "  ${BLUE}->${RESET} $1"; }
ok()    { echo -e "  ${GREEN}ok${RESET} $1"; }
warn()  { echo -e "  ${YELLOW}!!${RESET} $1"; }
fail()  { echo -e "  ${RED}xx${RESET} $1" >&2; exit 1; }

# ═══════════════════════════════════════════════════════════════════════════════
# Box Drawing
# ═══════════════════════════════════════════════════════════════════════════════

ESC=$(printf '\033')
STRIP_ANSI="s/${ESC}\\[[0-9;]*m//g"

draw_box() {
    local color="$1"; shift
    local lines=("$@")
    local max_w=0

    for line in "${lines[@]}"; do
        local stripped
        stripped=$(printf '%b' "$line" | LC_ALL=C sed "$STRIP_ANSI")
        local len=${#stripped}
        (( len > max_w )) && max_w=$len
    done

    local inner=$((max_w + 4))
    local border=""
    for ((i=0; i<inner; i++)); do border+="\u2550"; done

    printf "\033[%sm\u2554%b\u2557\033[0m\n" "$color" "$border"
    for line in "${lines[@]}"; do
        local stripped
        stripped=$(printf '%b' "$line" | LC_ALL=C sed "$STRIP_ANSI")
        local pad=$((max_w - ${#stripped}))
        local pad_str=""
        for ((i=0; i<pad; i++)); do pad_str+=" "; done
        printf "\033[%sm\u2551\033[0m  %b%s  \033[%sm\u2551\033[0m\n" "$color" "$line" "$pad_str" "$color"
    done
    printf "\033[%sm\u255a%b\u255d\033[0m\n" "$color" "$border"
}

# ═══════════════════════════════════════════════════════════════════════════════
# Banner
# ═══════════════════════════════════════════════════════════════════════════════

echo ""
draw_box "0;36" \
    "${BOLD}initech${RESET}  multi-agent terminal multiplexer" \
    "${DIM}https://github.com/nmelo/initech${RESET}"
echo ""

# ═══════════════════════════════════════════════════════════════════════════════
# Platform Detection
# ═══════════════════════════════════════════════════════════════════════════════

OS="$(uname -s)"
ARCH="$(uname -m)"

case "$OS" in
    Darwin) PLATFORM="macOS"; INSTALL_METHOD="homebrew" ;;
    Linux)  PLATFORM="Linux"; INSTALL_METHOD="direct" ;;
    *)      fail "Unsupported OS: $OS. initech supports macOS and Linux." ;;
esac

case "$ARCH" in
    x86_64|amd64)  ARCH_NAME="amd64" ;;
    arm64|aarch64) ARCH_NAME="arm64" ;;
    *)             fail "Unsupported architecture: $ARCH" ;;
esac

info "Detected ${BOLD}${PLATFORM} ${ARCH_NAME}${RESET}"
info "Install method: ${BOLD}${INSTALL_METHOD}${RESET}"

# ═══════════════════════════════════════════════════════════════════════════════
# Prerequisites
# ═══════════════════════════════════════════════════════════════════════════════

echo ""
info "Checking prerequisites..."

PREREQ_OK=1

if command -v git &>/dev/null; then
    ok "git $(git --version 2>/dev/null | awk '{print $3}')"
else
    warn "git not found (required)"
    PREREQ_OK=0
fi

if command -v claude &>/dev/null; then
    ok "claude $(claude --version 2>/dev/null | head -1)"
else
    warn "claude not found (install Claude Code first)"
    warn "  See: https://docs.anthropic.com/en/docs/claude-code"
    PREREQ_OK=0
fi

if [ "$PREREQ_OK" -eq 0 ]; then
    echo ""
    warn "Install missing prerequisites, then re-run this script."
    exit 1
fi

# ═══════════════════════════════════════════════════════════════════════════════
# Version Resolution
# ═══════════════════════════════════════════════════════════════════════════════

resolve_latest_version() {
    local url="${GITHUB_RELEASE_URL}/latest"
    # GitHub redirects /latest to /tag/vX.Y.Z. Follow the redirect and extract.
    local redirect
    redirect=$(curl -fsSI -o /dev/null -w '%{url_effective}' -L "$url" 2>/dev/null || true)
    if [[ -n "$redirect" ]]; then
        echo "${redirect##*/}"
        return
    fi
    # Fallback: parse the releases page.
    curl -fsSL "${GITHUB_RELEASE_URL}" 2>/dev/null | grep -oP 'tag/v[\d.]+' | head -1 | sed 's|tag/||'
}

if [[ "$VERSION" == "latest" ]]; then
    info "Resolving latest version..."
    VERSION=$(resolve_latest_version)
    if [[ -z "$VERSION" ]]; then
        fail "Could not resolve latest version from GitHub Releases."
    fi
fi

# Strip leading 'v' for comparison but keep for display.
VERSION_BARE="${VERSION#v}"
VERSION_TAG="v${VERSION_BARE}"

ok "Target version: ${BOLD}${VERSION_TAG}${RESET}"

# ═══════════════════════════════════════════════════════════════════════════════
# macOS: Homebrew Install
# ═══════════════════════════════════════════════════════════════════════════════

install_homebrew() {
    echo ""
    info "Installing via Homebrew..."

    if ! command -v brew &>/dev/null; then
        fail "Homebrew not found. Install it first: https://brew.sh"
    fi
    ok "Homebrew found"

    if command -v initech &>/dev/null; then
        local current
        current="$(initech version 2>/dev/null | awk '{print $2}')"
        info "Upgrading from ${current}..."
        brew upgrade nmelo/tap/initech 2>/dev/null || brew reinstall nmelo/tap/initech
    else
        info "Tapping nmelo/tap..."
        brew tap nmelo/tap 2>/dev/null || true
        info "Installing initech..."
        brew install nmelo/tap/initech
    fi
}

# ═══════════════════════════════════════════════════════════════════════════════
# Linux: Direct Binary Install
# ═══════════════════════════════════════════════════════════════════════════════

install_direct() {
    echo ""
    info "Downloading from GitHub Releases..."

    local os_name="linux"
    local tarball="initech_${os_name}_${ARCH_NAME}.tar.gz"
    local url="${GITHUB_RELEASE_URL}/download/${VERSION_TAG}/${tarball}"
    local checksum_url="${GITHUB_RELEASE_URL}/download/${VERSION_TAG}/checksums.txt"

    local tmpdir
    tmpdir=$(mktemp -d)
    trap "rm -rf '$tmpdir'" EXIT

    info "Downloading ${BOLD}${tarball}${RESET}..."
    if ! curl -fsSL -o "${tmpdir}/${tarball}" "$url"; then
        fail "Download failed: $url"
    fi
    ok "Downloaded $(du -h "${tmpdir}/${tarball}" | awk '{print $1}')"

    # Verify checksum if available.
    info "Verifying checksum..."
    if curl -fsSL -o "${tmpdir}/checksums.txt" "$checksum_url" 2>/dev/null; then
        local expected
        expected=$(grep "${tarball}" "${tmpdir}/checksums.txt" | awk '{print $1}')
        if [[ -n "$expected" ]]; then
            local actual
            actual=$(sha256sum "${tmpdir}/${tarball}" 2>/dev/null | awk '{print $1}' \
                  || shasum -a 256 "${tmpdir}/${tarball}" | awk '{print $1}')
            if [[ "$actual" == "$expected" ]]; then
                ok "Checksum verified (sha256)"
            else
                fail "Checksum mismatch! Expected: ${expected}, got: ${actual}"
            fi
        else
            warn "Tarball not found in checksums.txt, skipping verification"
        fi
    else
        warn "checksums.txt not available, skipping verification"
    fi

    # Extract.
    info "Extracting to ${BOLD}${DEST}${RESET}..."
    mkdir -p "$DEST"
    tar -xzf "${tmpdir}/${tarball}" -C "${tmpdir}"
    if [[ -f "${tmpdir}/initech" ]]; then
        mv "${tmpdir}/initech" "${DEST}/initech"
        chmod +x "${DEST}/initech"
    else
        fail "Binary not found in tarball"
    fi
    ok "Installed to ${DEST}/initech"

    # PATH check.
    if ! echo "$PATH" | tr ':' '\n' | grep -qx "$DEST"; then
        echo ""
        warn "${DEST} is not in your PATH"
        info "Add it to your shell profile:"
        echo ""
        echo -e "    ${BOLD}export PATH=\"${DEST}:\$PATH\"${RESET}"
        echo ""
        local shell_rc=""
        case "${SHELL:-}" in
            */zsh)  shell_rc="$HOME/.zshrc" ;;
            */bash) shell_rc="$HOME/.bashrc" ;;
            */fish) shell_rc="$HOME/.config/fish/config.fish" ;;
        esac
        if [[ -n "$shell_rc" ]]; then
            info "Or run: ${DIM}echo 'export PATH=\"${DEST}:\$PATH\"' >> ${shell_rc}${RESET}"
        fi
        # Temporarily add to PATH for verification below.
        export PATH="${DEST}:${PATH}"
    fi
}

# ═══════════════════════════════════════════════════════════════════════════════
# Install
# ═══════════════════════════════════════════════════════════════════════════════

case "$INSTALL_METHOD" in
    homebrew) install_homebrew ;;
    direct)   install_direct ;;
esac

# ═══════════════════════════════════════════════════════════════════════════════
# Verify
# ═══════════════════════════════════════════════════════════════════════════════

echo ""
info "Verifying installation..."

if ! command -v initech &>/dev/null; then
    fail "initech not found in PATH after install"
fi

INSTALLED_VERSION="$(initech version 2>/dev/null | awk '{print $NF}')"
INSTALLED_PATH="$(command -v initech)"
ok "initech ${BOLD}${INSTALLED_VERSION}${RESET} verified"

# Check for bd (beads).
BD_STATUS="${DIM}not installed${RESET}"
if command -v bd &>/dev/null; then
    BD_STATUS="${GREEN}installed${RESET}"
fi

# ═══════════════════════════════════════════════════════════════════════════════
# Summary
# ═══════════════════════════════════════════════════════════════════════════════

echo ""
draw_box "0;32" \
    "${BOLD}${GREEN}Installation complete${RESET}" \
    "" \
    "  Binary:    ${BOLD}${INSTALLED_PATH}${RESET}" \
    "  Version:   ${BOLD}${INSTALLED_VERSION}${RESET}" \
    "  Platform:  ${PLATFORM} ${ARCH_NAME}" \
    "  Beads:     ${BD_STATUS}"
echo ""

echo -e "  ${BOLD}Quick start:${RESET}"
echo -e "    mkdir myproject && cd myproject"
echo -e "    initech init       ${DIM}# bootstrap project${RESET}"
echo -e "    initech            ${DIM}# launch TUI${RESET}"
echo ""
echo -e "  ${BOLD}Useful commands:${RESET}"
echo -e "    initech doctor     ${DIM}# check prerequisites${RESET}"
echo -e "    initech status     ${DIM}# agent status table${RESET}"
echo -e "    initech --help     ${DIM}# all commands${RESET}"
echo ""
echo -e "  ${BOLD}Uninstall:${RESET}"
if [[ "$INSTALL_METHOD" == "homebrew" ]]; then
    echo -e "    brew uninstall initech && brew untap nmelo/tap"
else
    echo -e "    rm ${DEST}/initech"
fi
echo ""
echo -e "  ${DIM}Docs:   https://initech.sh${RESET}"
echo -e "  ${DIM}Source: https://github.com/nmelo/initech${RESET}"
echo ""
