#!/bin/bash
# ═══════════════════════════════════════════════════════════════════════════════
# pyMC Console - Dashboard Overlay Manager
# ═══════════════════════════════════════════════════════════════════════════════
#
# ARCHITECTURE: Thin wrapper around pyMC_Repeater's native installer.
# We don't duplicate upstream's functionality - we extend it with our dashboard.
#
# WHAT WE DO:
#   • Clone/update pyMC_Repeater (to access their manage.sh)
#   • Call upstream's manage.sh for install/upgrade/uninstall
#   • Overlay our React dashboard after upstream completes
#   • Respect user's UI preference (don't force our dashboard on upgrades)
#
# WHAT UPSTREAM DOES:
#   • User creation, directories, dependencies
#   • pip install (pymc_repeater, pymc_core)
#   • Service file, systemd management
#   • Radio/GPIO configuration
#   • Config file management
#
# DASHBOARD OVERLAY RULES:
#   • Fresh install → Set web.web_path to our dashboard
#   • Upgrade → Update files only, preserve user's web_path choice
#
# ═══════════════════════════════════════════════════════════════════════════════

set -e

# ─────────────────────────────────────────────────────────────────────────────
# Configuration
# ─────────────────────────────────────────────────────────────────────────────

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CLONE_DIR="$(dirname "$SCRIPT_DIR")/pyMC_Repeater"

INSTALL_DIR="/opt/pymc_repeater"
CONSOLE_DIR="/opt/pymc_console"
UI_DIR="$CONSOLE_DIR/web/html"
CONFIG_DIR="/etc/pymc_repeater"

SERVICE_NAME="pymc-repeater"
DEFAULT_BRANCH="dev"

UI_REPO="dmduran12/pymc_console-dist"
UI_RELEASE_URL="https://github.com/${UI_REPO}/releases"

# ─────────────────────────────────────────────────────────────────────────────
# Terminal Output
# ─────────────────────────────────────────────────────────────────────────────

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

print_step()    { echo -e "\n${BOLD}${CYAN}[$1/$2]${NC} ${BOLD}$3${NC}"; }
print_success() { echo -e "    ${GREEN}✓${NC} $1"; }
print_error()   { echo -e "    ${RED}✗${NC} ${RED}$1${NC}"; }
print_info()    { echo -e "    ${CYAN}➜${NC} $1"; }
print_warning() { echo -e "    ${YELLOW}⚠${NC} $1"; }

print_banner() {
    clear
    echo ""
    echo -e "${BOLD}${CYAN}pyMC Console${NC}"
    echo -e "${DIM}React Dashboard for pyMC_Repeater${NC}"
    echo ""
}

# ─────────────────────────────────────────────────────────────────────────────
# TUI Setup (whiptail/dialog)
# ─────────────────────────────────────────────────────────────────────────────

setup_dialog() {
    if command -v whiptail &>/dev/null; then
        DIALOG="whiptail"
    elif command -v dialog &>/dev/null; then
        DIALOG="dialog"
    else
        echo "Installing whiptail..."
        apt-get update -qq && apt-get install -y whiptail
        DIALOG="whiptail"
    fi
}

show_info()   { $DIALOG --backtitle "pyMC Console" --title "$1" --msgbox "$2" 12 60; }
show_error()  { $DIALOG --backtitle "pyMC Console" --title "Error" --msgbox "$1" 10 60; }
ask_yes_no()  { $DIALOG --backtitle "pyMC Console" --title "$1" --yesno "$2" 12 60; }

# ─────────────────────────────────────────────────────────────────────────────
# Status Helpers
# ─────────────────────────────────────────────────────────────────────────────

is_installed()    { [[ -d "$INSTALL_DIR" ]] && [[ -f "$INSTALL_DIR/pyproject.toml" ]]; }
service_running() { systemctl is-active "$SERVICE_NAME" &>/dev/null; }

get_version() {
    pip3 show pymc-repeater 2>/dev/null | grep "^Version:" | awk '{print $2}' || echo "unknown"
}

get_console_version() {
    [[ -f "$UI_DIR/VERSION" ]] && cat "$UI_DIR/VERSION" 2>/dev/null | tr -d '[:space:]' && return
    echo "unknown"
}

get_core_version() {
    pip3 show pymc-core 2>/dev/null | grep "^Version:" | awk '{print $2}' || echo "unknown"
}

get_repeater_version() {
    pip3 show pymc-repeater 2>/dev/null | grep "^Version:" | awk '{print $2}' || echo "unknown"
}

print_version_summary() {
    local core_ver=$(get_core_version)
    local rep_ver=$(get_repeater_version)
    local ui_ver=$(get_console_version)
    
    echo ""
    echo -e "  ${DIM}Versions:${NC}"
    echo -e "    pyMC Core:     ${CYAN}$core_ver${NC}"
    echo -e "    pyMC Repeater: ${CYAN}$rep_ver${NC}"
    echo -e "    pyMC Console:  ${CYAN}v$ui_ver${NC}"
}

# ─────────────────────────────────────────────────────────────────────────────
# Git Operations
# ─────────────────────────────────────────────────────────────────────────────

clone_upstream() {
    local branch="$1"
    
    git config --global --add safe.directory "$CLONE_DIR" 2>/dev/null || true
    
    if [[ -d "$CLONE_DIR/.git" ]]; then
        print_info "Updating existing clone..."
        cd "$CLONE_DIR"
        git fetch origin --prune
        git reset --hard HEAD
        git checkout "$branch" 2>/dev/null || git checkout -b "$branch" "origin/$branch"
        git reset --hard "origin/$branch"
    else
        print_info "Cloning pyMC_Repeater@$branch..."
        rm -rf "$CLONE_DIR"
        git clone -b "$branch" "https://github.com/rightup/pyMC_Repeater.git" "$CLONE_DIR"
    fi
    
    # Show what we got
    cd "$CLONE_DIR"
    local commit=$(git rev-parse --short HEAD)
    local date=$(git log -1 --format=%cd --date=short)
    print_success "Source: $branch @ $commit ($date)"
}

# ─────────────────────────────────────────────────────────────────────────────
# Upstream Installer Wrapper
# ─────────────────────────────────────────────────────────────────────────────

run_upstream() {
    local action="$1"
    local upstream_script="$CLONE_DIR/manage.sh"
    
    if [[ ! -f "$upstream_script" ]]; then
        print_error "Upstream manage.sh not found"
        return 1
    fi
    
    echo ""
    echo -e "${DIM}─────────────────────────────────────────────────────────${NC}"
    echo -e "${BOLD}Running pyMC_Repeater $action...${NC}"
    echo -e "${DIM}─────────────────────────────────────────────────────────${NC}"
    echo ""
    
    (cd "$CLONE_DIR" && bash "$upstream_script" "$action")
    local exit_code=$?
    
    echo ""
    echo -e "${DIM}─────────────────────────────────────────────────────────${NC}"
    
    if [[ $exit_code -eq 0 ]]; then
        print_success "pyMC_Repeater $action completed"
        return 0
    else
        print_error "pyMC_Repeater $action failed"
        return 1
    fi
}

# ─────────────────────────────────────────────────────────────────────────────
# Dashboard Installation
# ─────────────────────────────────────────────────────────────────────────────

install_dashboard() {
    local config_file="$CONFIG_DIR/config.yaml"
    local temp_file="/tmp/pymc-ui-$$.tar.gz"
    local is_fresh_install=true
    
    # Detect fresh install vs upgrade
    if [[ -d "$CONSOLE_DIR" ]]; then
        is_fresh_install=false
    fi
    
    # Download dashboard
    print_info "Downloading dashboard..."
    if ! curl -fsSL -o "$temp_file" "${UI_RELEASE_URL}/latest/download/pymc-ui-latest.tar.gz"; then
        print_error "Download failed"
        rm -f "$temp_file"
        return 1
    fi
    
    # Clean and extract
    rm -rf "$UI_DIR"
    mkdir -p "$UI_DIR"
    tar -xzf "$temp_file" -C "$UI_DIR"
    rm -f "$temp_file"
    
    # Set permissions
    chown -R repeater:repeater "$CONSOLE_DIR" 2>/dev/null || true
    
    # Configure web_path (fresh install only)
    if [[ -f "$config_file" ]] && command -v yq &>/dev/null; then
        # Ensure web section exists
        yq -i '.web //= {}' "$config_file" 2>/dev/null || true
        
        if [[ "$is_fresh_install" == true ]]; then
            yq -i ".web.web_path = \"$UI_DIR\"" "$config_file"
            print_success "Dashboard installed (web_path configured)"
        else
            print_success "Dashboard updated (web_path preserved)"
        fi
    else
        print_warning "Could not configure web_path - set manually in $config_file"
    fi
    
    local size=$(du -sh "$UI_DIR" 2>/dev/null | cut -f1)
    print_info "Size: $size"
}

# ─────────────────────────────────────────────────────────────────────────────
# Install
# ─────────────────────────────────────────────────────────────────────────────

do_install() {
    if [[ "$EUID" -ne 0 ]]; then
        show_error "Installation requires root.\n\nRun: sudo $0 install"
        return 1
    fi
    
    # Check if pyMC_Repeater already installed
    local repeater_exists=false
    is_installed && repeater_exists=true
    
    # Installation type selection (interactive only)
    local install_type="${1:-}"
    if [[ -z "$install_type" ]]; then
        if [[ "$repeater_exists" == true ]]; then
            # Repeater exists - only offer console
            install_type="console"
            show_info "Existing Installation" "pyMC_Repeater detected.\n\nInstalling Console dashboard only."
        else
            # Fresh system - offer choice
            install_type=$($DIALOG --backtitle "pyMC Console" --title "Installation Type" --menu \
                "\nSelect what to install:" 14 55 2 \
                "full"    "Full Stack (pyMC_Repeater + Console)" \
                "console" "Console Only (dashboard for existing install)" \
                3>&1 1>&2 2>&3) || return 0
        fi
    fi
    
    case "$install_type" in
        full)    do_install_full ;;
        console) do_install_console ;;
        *)       show_error "Unknown install type: $install_type"; return 1 ;;
    esac
}

do_install_full() {
    if is_installed; then
        show_error "pyMC_Repeater already installed.\n\nUse 'upgrade' or choose Console-only install."
        return 1
    fi
    
    # Branch selection
    local branch
    branch=$($DIALOG --backtitle "pyMC Console" --title "Select Branch" --menu \
        "\nSelect pyMC_Repeater branch:" 14 50 3 \
        "dev"  "Development (recommended)" \
        "main" "Stable release" \
        "custom" "Enter custom branch" 3>&1 1>&2 2>&3) || return 0
    
    if [[ "$branch" == "custom" ]]; then
        branch=$($DIALOG --backtitle "pyMC Console" --inputbox "Branch name:" 8 40 "dev" 3>&1 1>&2 2>&3) || return 0
    fi
    
    print_banner
    echo -e "  ${DIM}Mode: Full Stack${NC}"
    echo -e "  ${DIM}Branch: $branch${NC}"
    
    # Step 1: Clone upstream
    print_step 1 3 "Preparing pyMC_Repeater"
    clone_upstream "$branch"
    
    # Step 2: Run upstream installer
    print_step 2 3 "Installing pyMC_Repeater"
    run_upstream "install" || return 1
    
    # Step 3: Overlay dashboard
    print_step 3 3 "Installing dashboard"
    install_dashboard
    
    # Done
    local ip=$(hostname -I 2>/dev/null | awk '{print $1}')
    echo ""
    echo -e "${GREEN}${BOLD}Installation Complete!${NC}"
    print_version_summary
    echo ""
    echo -e "  Dashboard: ${CYAN}http://$ip:8000/${NC}"
    echo ""
    echo -e "  ${DIM}Configure radio: cd $CLONE_DIR && sudo ./manage.sh${NC}"
    echo ""
}

do_install_console() {
    if ! is_installed; then
        show_error "pyMC_Repeater not found.\n\nUse Full Stack install or install pyMC_Repeater first."
        return 1
    fi
    
    if [[ -d "$UI_DIR" ]]; then
        if ! ask_yes_no "Console Exists" "Console dashboard already installed.\n\nReinstall?"; then
            return 0
        fi
    fi
    
    print_banner
    echo -e "  ${DIM}Mode: Console Only${NC}"
    
    # Single step: Install dashboard
    print_step 1 1 "Installing dashboard"
    install_dashboard
    
    # Done
    local ip=$(hostname -I 2>/dev/null | awk '{print $1}')
    echo ""
    echo -e "${GREEN}${BOLD}Console Installed!${NC}"
    echo ""
    echo -e "  ${DIM}Versions:${NC}"
    echo -e "    pyMC Console:  ${CYAN}v$(get_console_version)${NC}"
    echo ""
    echo -e "  Dashboard: ${CYAN}http://$ip:8000/${NC}"
    echo ""
}

# ─────────────────────────────────────────────────────────────────────────────
# Upgrade
# ─────────────────────────────────────────────────────────────────────────────

do_upgrade() {
    if ! is_installed; then
        show_error "Not installed. Use 'install' first."
        return 1
    fi
    
    if [[ "$EUID" -ne 0 ]]; then
        show_error "Upgrade requires root.\n\nRun: sudo $0 upgrade"
        return 1
    fi
    
    # Self-update pymc_console repo
    if [[ -d "$SCRIPT_DIR/.git" ]]; then
        print_info "Checking for pymc_console updates..."
        cd "$SCRIPT_DIR"
        git config --global --add safe.directory "$SCRIPT_DIR" 2>/dev/null || true
        git fetch origin 2>/dev/null || true
        
        local local_hash=$(git rev-parse HEAD 2>/dev/null)
        local remote_hash=$(git rev-parse origin/main 2>/dev/null)
        
        if [[ -n "$remote_hash" && "$local_hash" != "$remote_hash" ]]; then
            if git pull --ff-only 2>/dev/null || git reset --hard origin/main 2>/dev/null; then
                print_success "pymc_console updated - restarting..."
                exec "$SCRIPT_DIR/manage.sh" upgrade
            fi
        fi
    fi
    
    # Capture current versions before upgrade
    local core_before=$(get_core_version)
    local rep_before=$(get_repeater_version)
    local ui_before=$(get_console_version)
    
    # Get current branch
    local branch="$DEFAULT_BRANCH"
    if [[ -d "$CLONE_DIR/.git" ]]; then
        branch=$(cd "$CLONE_DIR" && git rev-parse --abbrev-ref HEAD 2>/dev/null) || branch="$DEFAULT_BRANCH"
    fi
    
    # Upgrade type selection
    local upgrade_type
    upgrade_type=$($DIALOG --backtitle "pyMC Console" --title "Upgrade" --menu \
        "\nWhat would you like to upgrade?" 12 55 2 \
        "console" "Console only" \
        "full"    "Full Stack (Repeater + Console)" \
        3>&1 1>&2 2>&3) || return 0
    
    print_banner
    echo -e "  ${DIM}Mode: $([[ "$upgrade_type" == "full" ]] && echo "Full Stack" || echo "Console Only")${NC}"
    
    if [[ "$upgrade_type" == "full" ]]; then
        # Full stack: 3 steps
        print_step 1 3 "Updating pyMC_Repeater source"
        clone_upstream "$branch"
        
        print_step 2 3 "Upgrading pyMC_Repeater"
        run_upstream "upgrade" || return 1
        
        print_step 3 3 "Updating dashboard"
        install_dashboard
    else
        # Console only: 1 step
        print_step 1 1 "Updating dashboard"
        install_dashboard
    fi
    
    # Done
    local ip=$(hostname -I 2>/dev/null | awk '{print $1}')
    local core_after=$(get_core_version)
    local rep_after=$(get_repeater_version)
    local ui_after=$(get_console_version)
    
    echo ""
    echo -e "${GREEN}${BOLD}Upgrade Complete!${NC}"
    echo ""
    echo -e "  ${DIM}Versions:${NC}"
    [[ "$core_before" != "$core_after" ]] \
        && echo -e "    pyMC Core:     ${DIM}$core_before${NC} → ${CYAN}$core_after${NC}" \
        || echo -e "    pyMC Core:     ${CYAN}$core_after${NC}"
    [[ "$rep_before" != "$rep_after" ]] \
        && echo -e "    pyMC Repeater: ${DIM}$rep_before${NC} → ${CYAN}$rep_after${NC}" \
        || echo -e "    pyMC Repeater: ${CYAN}$rep_after${NC}"
    [[ "$ui_before" != "$ui_after" ]] \
        && echo -e "    pyMC Console:  ${DIM}v$ui_before${NC} → ${CYAN}v$ui_after${NC}" \
        || echo -e "    pyMC Console:  ${CYAN}v$ui_after${NC}"
    echo ""
    echo -e "  Dashboard: ${CYAN}http://$ip:8000/${NC}"
    echo ""
}

# ─────────────────────────────────────────────────────────────────────────────
# Uninstall
# ─────────────────────────────────────────────────────────────────────────────

do_uninstall() {
    # Check if there's anything to uninstall
    local has_repeater=false
    local has_console=false
    local has_clone=false
    local has_self=true  # Script is always running from somewhere
    
    is_installed && has_repeater=true
    [[ -d "$CONSOLE_DIR" ]] && has_console=true
    [[ -d "$CLONE_DIR" ]] && has_clone=true
    
    # Debug: show what we found
    print_banner
    echo -e "  ${DIM}Detected components:${NC}"
    echo -e "    Repeater:  $([[ "$has_repeater" == true ]] && echo "${GREEN}found${NC}" || echo "${DIM}not found${NC}")"
    echo -e "    Console:   $([[ "$has_console" == true ]] && echo "${GREEN}found${NC} ($CONSOLE_DIR)" || echo "${DIM}not found${NC}")"
    echo -e "    Clone:     $([[ "$has_clone" == true ]] && echo "${GREEN}found${NC} ($CLONE_DIR)" || echo "${DIM}not found${NC}")"
    echo -e "    This repo: ${GREEN}$SCRIPT_DIR${NC}"
    echo ""
    
    if [[ "$EUID" -ne 0 ]]; then
        show_error "Uninstall requires root.\n\nRun: sudo $0 uninstall"
        return 1
    fi
    
    # Build description of what will be removed
    local will_remove=""
    [[ "$has_repeater" == true ]] && will_remove+="• pyMC_Repeater\n"
    [[ "$has_console" == true ]] && will_remove+="• Console dashboard ($CONSOLE_DIR)\n"
    [[ "$has_clone" == true ]] && will_remove+="• pyMC_Repeater clone ($CLONE_DIR)\n"
    will_remove+="• pymc_console repo ($SCRIPT_DIR)"
    
    if ! ask_yes_no "Confirm Uninstall" "\nThis will remove:\n${will_remove}\n\nContinue?"; then
        return 0
    fi
    
    print_banner
    
    # Calculate steps: repeater(optional) + console + clone(optional) + self
    local step=1
    local total=1  # self is always counted
    [[ "$has_repeater" == true ]] && ((total++))
    [[ "$has_console" == true ]] && ((total++))
    [[ "$has_clone" == true ]] && ((total++))
    
    # Step: Run upstream uninstall (if Repeater installed)
    if [[ "$has_repeater" == true ]]; then
        print_step $step $total "Removing pyMC_Repeater"
        if [[ -f "$CLONE_DIR/manage.sh" ]]; then
            # Run upstream in completely separate bash process
            # Use script -q to capture and isolate the entire session
            bash -c 'cd "'"$CLONE_DIR"'" && bash manage.sh uninstall' </dev/tty || true
        else
            # Manual cleanup if upstream not available
            systemctl stop "$SERVICE_NAME" 2>/dev/null || true
            systemctl disable "$SERVICE_NAME" 2>/dev/null || true
            rm -f /etc/systemd/system/pymc-repeater.service
            systemctl daemon-reload
            rm -rf "$INSTALL_DIR" "$CONFIG_DIR" /var/log/pymc_repeater
            pip3 uninstall -y pymc_repeater pymc_core 2>/dev/null || true
            userdel repeater 2>/dev/null || true
        fi
        print_success "pyMC_Repeater removed"
        ((step++))
    fi
    
    # Step: Remove dashboard overlay (if exists)
    if [[ "$has_console" == true ]]; then
        print_step $step $total "Removing dashboard"
        rm -rf "$CONSOLE_DIR"
        print_success "Dashboard removed ($CONSOLE_DIR)"
        ((step++))
    fi
    
    # Step: Remove clone
    if [[ "$has_clone" == true ]]; then
        print_step $step $total "Removing pyMC_Repeater clone"
        rm -rf "$CLONE_DIR"
        print_success "Clone removed ($CLONE_DIR)"
        ((step++))
    fi
    
    # Step: Remove pymc_console repo itself (scheduled for after script exits)
    print_step $step $total "Removing pymc_console repo"
    echo -e "    ${YELLOW}Will remove $SCRIPT_DIR after script exits${NC}"
    trap "rm -rf '$SCRIPT_DIR'" EXIT
    print_success "Scheduled for removal"
    
    echo ""
    echo -e "${GREEN}${BOLD}Uninstall Complete${NC}"
    echo ""
}

# ─────────────────────────────────────────────────────────────────────────────
# Service Control (simple wrappers)
# ─────────────────────────────────────────────────────────────────────────────

do_start() {
    [[ "$EUID" -ne 0 ]] && { echo "Run as root: sudo $0 start"; return 1; }
    systemctl start "$SERVICE_NAME"
    sleep 1
    service_running && echo "✓ Service started" || echo "✗ Service failed to start"
}

do_stop() {
    [[ "$EUID" -ne 0 ]] && { echo "Run as root: sudo $0 stop"; return 1; }
    systemctl stop "$SERVICE_NAME"
    echo "✓ Service stopped"
}

do_restart() {
    [[ "$EUID" -ne 0 ]] && { echo "Run as root: sudo $0 restart"; return 1; }
    systemctl restart "$SERVICE_NAME"
    sleep 1
    service_running && echo "✓ Service restarted" || echo "✗ Service failed to start"
}

do_status() {
    if is_installed; then
        echo "pyMC_Repeater: $(get_version)"
        echo "Console:       v$(get_console_version)"
        echo "Service:       $(service_running && echo "running" || echo "stopped")"
    else
        echo "Not installed"
    fi
}

# ─────────────────────────────────────────────────────────────────────────────
# Main Menu
# ─────────────────────────────────────────────────────────────────────────────

show_menu() {
    local status="Not installed"
    is_installed && status=$(service_running && echo "Running" || echo "Stopped")
    
    local choice=$($DIALOG --backtitle "pyMC Console" --title "Main Menu" --menu \
        "\nStatus: $status\n\nSelect action:" 16 50 6 \
        "install"   "Fresh installation" \
        "upgrade"   "Upgrade existing" \
        "uninstall" "Remove everything" \
        "status"    "Show versions" \
        "logs"      "View live logs" \
        "exit"      "Exit" 3>&1 1>&2 2>&3) || return 1
    
    case "$choice" in
        install)   do_install ;;
        upgrade)   do_upgrade ;;
        uninstall) do_uninstall ;;
        status)    clear; do_status; read -p "Press Enter..." ;;
        logs)      clear; journalctl -u "$SERVICE_NAME" -f ;;
        exit)      exit 0 ;;
    esac
}

# ─────────────────────────────────────────────────────────────────────────────
# CLI Entry Point
# ─────────────────────────────────────────────────────────────────────────────

show_help() {
    cat << EOF
pyMC Console - Dashboard Overlay Manager

Usage: $0 [command]

Commands:
  install [full|console]  Fresh installation (default: interactive)
                          full    - pyMC_Repeater + Console dashboard
                          console - Dashboard only (existing Repeater)
  upgrade                 Upgrade existing installation
  uninstall               Remove everything
  start                   Start service
  stop                    Stop service  
  restart                 Restart service
  status                  Show versions and status

Run without arguments for interactive menu.

Radio/GPIO configuration: cd $CLONE_DIR && sudo ./manage.sh
EOF
}

case "${1:-}" in
    -h|--help)  show_help ;;
    install)    setup_dialog; do_install "${2:-}" ;;
    upgrade)    setup_dialog; do_upgrade ;;
    uninstall)  setup_dialog; do_uninstall ;;
    start)      do_start ;;
    stop)       do_stop ;;
    restart)    do_restart ;;
    status)     do_status ;;
    "")
        setup_dialog
        while true; do show_menu || break; done
        ;;
    *)
        echo "Unknown command: $1"
        show_help
        exit 1
        ;;
esac
