#!/usr/bin/env bash
# Point 53 Installer
# https://point53.com
#
# ---------------------------------------------------------------------------
# MIT License
#
# Copyright (c) 2026 Point 53 LLC
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# The tools this installer fetches are licensed separately under MPL-2.0.
# ---------------------------------------------------------------------------
#
# Usage:
#   Interactive:  ./install.sh
#   All tools:    ./install.sh --all
#   Specific:     ./install.sh --collector --intercept
#   Custom index: P53_INDEX=http://10.0.0.5:3553/simple/ ./install.sh --all
#   Skip uv:      ./install.sh --no-uv-check --all

set -euo pipefail

P53_INDEX="${P53_INDEX:-https://packages.point53.com/simple/}"
P53_UV_INSTALL="${P53_UV_INSTALL:-https://astral.sh/uv/install.sh}"

# --- Colors (disabled if not a terminal) ---

if [ -t 1 ]; then
    BOLD='\033[1m'
    DIM='\033[2m'
    GREEN='\033[32m'
    YELLOW='\033[33m'
    CYAN='\033[36m'
    RED='\033[31m'
    RESET='\033[0m'
else
    BOLD='' DIM='' GREEN='' YELLOW='' CYAN='' RED='' RESET=''
fi

info()  { printf "${CYAN}=>${RESET} %s\n" "$*"; }
warn()  { printf "${YELLOW}=>${RESET} %s\n" "$*"; }
err()   { printf "${RED}=>${RESET} %s\n" "$*" >&2; }
ok()    { printf "${GREEN}=>${RESET} %s\n" "$*"; }

# --- Parse arguments ---

WANT_COLLECTOR=0
WANT_COURIER=0
WANT_INTERCEPT=0
WANT_NIGHTDESK=0
WANT_ALL=0
INTERACTIVE=1
SKIP_UV_CHECK=0

while [ $# -gt 0 ]; do
    case "$1" in
        --all)        WANT_ALL=1; INTERACTIVE=0 ;;
        --collector)  WANT_COLLECTOR=1; INTERACTIVE=0 ;;
        --courier)    WANT_COURIER=1; INTERACTIVE=0 ;;
        --intercept)  WANT_INTERCEPT=1; INTERACTIVE=0 ;;
        --nightdesk)  WANT_NIGHTDESK=1; INTERACTIVE=0 ;;
        --no-uv-check) SKIP_UV_CHECK=1 ;;
        --index)
            shift
            P53_INDEX="$1"
            ;;
        --help|-h)
            printf "%s\n" \
                "Point 53 Installer" \
                "" \
                "Usage: ./install.sh [OPTIONS]" \
                "" \
                "Options:" \
                "  --all              Install all four tools" \
                "  --collector        Install Collector (RSS/web aggregation)" \
                "  --courier          Install Courier (AI web search)" \
                "  --intercept        Install Intercept (audio capture + transcription)" \
                "  --nightdesk        Install Nightdesk (iterative optimization)" \
                "  --index <url>      Package index URL" \
                "  --no-uv-check      Skip uv installation check" \
                "  -h, --help         Show this help" \
                "" \
                "Environment:" \
                "  P53_INDEX          Package index URL (default: https://packages.point53.com/simple/)" \
                "  P53_UV_INSTALL     URL for uv installer (default: astral.sh)"
            exit 0
            ;;
        *)
            err "Unknown option: $1"
            err "Run with --help for usage."
            exit 1
            ;;
    esac
    shift
done

if [ "$WANT_ALL" -eq 1 ]; then
    WANT_COLLECTOR=1
    WANT_COURIER=1
    WANT_INTERCEPT=1
    WANT_NIGHTDESK=1
fi

# --- Header ---

printf "\n"
printf "${BOLD}  Point 53 Suite Installer${RESET}\n"
printf "${DIM}  Making our thing your thing since 2026.${RESET}\n"
printf "\n"
printf "  Package index: ${DIM}%s${RESET}\n" "$P53_INDEX"
printf "\n"

# --- Check Python ---

PYTHON=""
for cmd in python3 python; do
    if command -v "$cmd" &>/dev/null; then
        ver=$("$cmd" -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')" 2>/dev/null || echo "0.0")
        major=$(echo "$ver" | cut -d. -f1)
        minor=$(echo "$ver" | cut -d. -f2)
        if [ "$major" -ge 3 ] && [ "$minor" -ge 10 ]; then
            PYTHON="$cmd"
            break
        fi
    fi
done

if [ -z "$PYTHON" ]; then
    err "Python 3.10+ is required but not found in PATH."
    err "Install Python from your system package manager or https://python.org"
    exit 1
fi

ok "Python found: $($PYTHON --version)"

# --- Check uv ---

if [ "$SKIP_UV_CHECK" -eq 0 ]; then
    if ! command -v uv &>/dev/null; then
        warn "uv is not installed. It is required to install Point 53 tools."
        printf "\n"
        printf "  uv is a fast Python package manager from Astral.\n"
        printf "  Install it from: https://docs.astral.sh/uv/getting-started/installation/\n"
        printf "\n"

        if [ "$INTERACTIVE" -eq 1 ]; then
            printf "  Install uv now? [Y/n] "
            read -r answer < /dev/tty
            case "$answer" in
                [nN]*) err "Cannot proceed without uv."; exit 1 ;;
            esac
        else
            info "Installing uv..."
        fi

        curl -LsSf "$P53_UV_INSTALL" | sh
        export PATH="$HOME/.local/bin:$HOME/.cargo/bin:$PATH"

        if ! command -v uv &>/dev/null; then
            err "uv installation failed. Install manually: https://docs.astral.sh/uv/"
            exit 1
        fi
    fi
    ok "uv found: $(uv self version 2>/dev/null || uv --version 2>/dev/null || echo 'unknown version')"
fi

# --- Interactive selection ---

if [ "$INTERACTIVE" -eq 1 ]; then
    printf "\n"
    printf "${BOLD}  Available tools:${RESET}\n"
    printf "\n"
    printf "    ${CYAN}1${RESET}  Collector    RSS/web aggregation + AI-summarized briefings\n"
    printf "    ${CYAN}2${RESET}  Courier      AI-assisted web search with configurable depth\n"
    printf "    ${CYAN}3${RESET}  Intercept    Audio capture + offline transcription + analysis\n"
    printf "    ${CYAN}4${RESET}  Nightdesk    Iterative metric optimization engine\n"
    printf "    ${CYAN}a${RESET}  All          Install everything\n"
    printf "\n"
    printf "  Select tools (space/comma separated, e.g. '1 3' or '1,2,4'): "
    read -r selection < /dev/tty

    selection=$(echo "$selection" | tr ',' ' ')

    for s in $selection; do
        case "$s" in
            1|collector)  WANT_COLLECTOR=1 ;;
            2|courier)    WANT_COURIER=1 ;;
            3|intercept)  WANT_INTERCEPT=1 ;;
            4|nightdesk)  WANT_NIGHTDESK=1 ;;
            a|all)        WANT_COLLECTOR=1; WANT_COURIER=1; WANT_INTERCEPT=1; WANT_NIGHTDESK=1 ;;
            *)            warn "Unknown selection: $s (skipping)" ;;
        esac
    done
fi

# --- Validate selection ---

if [ "$WANT_COLLECTOR" -eq 0 ] && [ "$WANT_COURIER" -eq 0 ] && \
   [ "$WANT_INTERCEPT" -eq 0 ] && [ "$WANT_NIGHTDESK" -eq 0 ]; then
    err "No tools selected."
    exit 1
fi

# Courier requires Collector
if [ "$WANT_COURIER" -eq 1 ] && [ "$WANT_COLLECTOR" -eq 0 ]; then
    info "Courier requires Collector — adding Collector to install list."
    WANT_COLLECTOR=1
fi

# --- Prerequisite hints ---

printf "\n"
printf "${BOLD}  Before we install — what you will need:${RESET}\n"
printf "\n"

if [ "$WANT_COLLECTOR" -eq 1 ]; then
    printf "    ${CYAN}Collector${RESET}  Chrome or Firefox for web scraping; a local LLM\n"
    printf "               server (Ollama) or cloud API key for summarization.\n"
    printf "\n"
fi
if [ "$WANT_COURIER" -eq 1 ]; then
    printf "    ${CYAN}Courier${RESET}    Chrome or Firefox for web navigation; a local LLM\n"
    printf "               server (Ollama) or cloud API key for analysis.\n"
    printf "\n"
fi
if [ "$WANT_INTERCEPT" -eq 1 ]; then
    printf "    ${CYAN}Intercept${RESET}  ffmpeg for audio recording; a Vosk model for offline\n"
    printf "               transcription. Download models from:\n"
    printf "               ${DIM}https://alphacephei.com/vosk/models${RESET}\n"
    printf "\n"
fi
if [ "$WANT_NIGHTDESK" -eq 1 ]; then
    printf "    ${CYAN}Nightdesk${RESET}  git for project tracking; a local LLM server (Ollama)\n"
    printf "               or cloud API key. Courier recommended for web-context\n"
    printf "               research.\n"
    printf "\n"
fi

printf "  ${DIM}Point 53 does not install these for you. Doctor will verify after install.${RESET}\n"
printf "\n"

if [ "$INTERACTIVE" -eq 1 ]; then
    printf "  Do you have the above dependencies installed? [Y/n] "
    read -r answer < /dev/tty
    case "$answer" in
        [nN]*) info "No problem. Install the dependencies above and re-run when ready."; exit 0 ;;
    esac
fi

# --- Install ---

printf "\n"
info "Installing from $P53_INDEX"
printf "\n"

install_tool() {
    local pkg="$1"
    local name="$2"
    info "Installing $name..."
    if uv tool install "$pkg" --index "$P53_INDEX" 2>&1; then
        ok "$name installed."
    else
        err "Failed to install $name."
        return 1
    fi
}

FAILED=0

# Collector first (Courier depends on it)
if [ "$WANT_COLLECTOR" -eq 1 ]; then
    install_tool p53-collector Collector || FAILED=1
fi

if [ "$WANT_COURIER" -eq 1 ]; then
    install_tool p53-courier Courier || FAILED=1
fi

if [ "$WANT_INTERCEPT" -eq 1 ]; then
    install_tool p53-intercept Intercept || FAILED=1
fi

if [ "$WANT_NIGHTDESK" -eq 1 ]; then
    install_tool p53-nightdesk Nightdesk || FAILED=1
fi

# --- Post-install ---

printf "\n"

if [ "$FAILED" -eq 0 ]; then
    ok "All selected tools installed successfully."
else
    warn "Some tools failed to install. Check errors above."
fi

# --- PATH check + fix for this session ---

UV_BIN_DIR="$(uv tool dir 2>/dev/null || echo "$HOME/.local/bin")"
# uv tool dir returns the tool environments dir; executables go in the bin sibling
UV_BIN_DIR="${UV_BIN_DIR%/tools}/bin"
# Fallback: check common locations
if [ ! -d "$UV_BIN_DIR" ]; then
    UV_BIN_DIR="$HOME/.local/bin"
fi

NEED_PATH_FIX=0
if ! echo "$PATH" | tr ':' '\n' | grep -qx "$UV_BIN_DIR"; then
    NEED_PATH_FIX=1
fi

if [ "$NEED_PATH_FIX" -eq 1 ]; then
    # Add to PATH for this session so doctor commands work
    export PATH="$UV_BIN_DIR:$PATH"

    printf "\n"
    warn "Tool executables are in ${BOLD}$UV_BIN_DIR${RESET} which was not in your PATH."
    info "Added to PATH for this session."
    printf "\n"
    printf "${BOLD}  To make it permanent, add to your shell profile:${RESET}\n"
    printf "\n"

    SHELL_NAME="$(basename "$SHELL" 2>/dev/null || echo "sh")"
    case "$SHELL_NAME" in
        zsh)
            printf "    echo 'export PATH=\"%s:\$PATH\"' >> ~/.zshrc\n" "$UV_BIN_DIR"
            ;;
        bash)
            printf "    echo 'export PATH=\"%s:\$PATH\"' >> ~/.bashrc\n" "$UV_BIN_DIR"
            ;;
        fish)
            printf "    fish_add_path %s\n" "$UV_BIN_DIR"
            ;;
        *)
            printf "    export PATH=\"%s:\$PATH\"\n" "$UV_BIN_DIR"
            ;;
    esac

    printf "\n"
fi

# --- Run doctor for each installed tool ---

printf "\n"
printf "${BOLD}  Running health checks...${RESET}\n"
printf "\n"

if [ "$WANT_COLLECTOR" -eq 1 ]; then
    if command -v collector &>/dev/null; then
        collector doctor || true
        printf "\n"
    else
        warn "collector not found in PATH — skipping doctor."
    fi
fi

if [ "$WANT_COURIER" -eq 1 ]; then
    if command -v courier &>/dev/null; then
        courier doctor || true
        printf "\n"
    else
        warn "courier not found in PATH — skipping doctor."
    fi
fi

if [ "$WANT_INTERCEPT" -eq 1 ]; then
    if command -v intercept &>/dev/null; then
        intercept doctor || true
        printf "\n"
    else
        warn "intercept not found in PATH — skipping doctor."
    fi
fi

if [ "$WANT_NIGHTDESK" -eq 1 ]; then
    if command -v nightdesk &>/dev/null; then
        nightdesk doctor || true
        printf "\n"
    else
        warn "nightdesk not found in PATH — skipping doctor."
    fi
fi

# --- Summary ---

printf "\n"
case "$(uname -s)" in
    Darwin)
        printf "  Config lives in:  ${DIM}~/Library/Application Support/point53/${RESET}\n"
        printf "  Data lives in:    ${DIM}~/Library/Application Support/point53/${RESET}\n"
        printf "  Cache lives in:   ${DIM}~/Library/Caches/point53/${RESET}\n"
        ;;
    *)
        printf "  Config lives in:  ${DIM}~/.config/point53/${RESET}\n"
        printf "  Data lives in:    ${DIM}~/.local/share/point53/${RESET}\n"
        printf "  Cache lives in:   ${DIM}~/.cache/point53/${RESET}\n"
        ;;
esac
printf "\n"
printf "${DIM}  Point 53 — Making our thing your thing since 2026.${RESET}\n"
printf "  ${DIM}Source: https://point53.com${RESET}\n"
printf "  ${DIM}Tools: MPL-2.0   Installer: MIT${RESET}\n"
printf "\n"
