#!/bin/bash

# Scanner Map Installation Script for Debian/Ubuntu-based Linux (e.g., Linux Mint)
# --- IMPORTANT ---
# 1. Run this script using: sudo bash linux_install_scanner_map.sh
# 2. This script assumes you are running a Debian/Ubuntu-based distribution.
# 3. Read the prompts carefully, especially regarding NVIDIA/CUDA installation and .env creation.
# 4. Manual configuration (.env, config.js, apikeys.json) is still required after running this script,
#    especially for API keys and specific talk group mappings.
# 5. Make sure you have a stable internet connection.

# --- Configuration ---
INSTALL_DIR="$HOME/scanner-map" # Default installation directory
GIT_REPO_URL="https://github.com/poisonednumber/Scanner-map.git" # Repository URL
OLLAMA_MODEL="llama3.1:8b" # Ollama model to pull (check README for recommendations)
# Default .env values (from user template)
DEFAULT_BOT_PORT="3306"
DEFAULT_API_KEY_FILE="data/apikeys.json"
DEFAULT_WEBSERVER_PORT="80"
DEFAULT_PUBLIC_DOMAIN="localhost"
DEFAULT_GEO_CITY="City"
DEFAULT_GEO_STATE="ST"
DEFAULT_GEO_COUNTRY="US"
DEFAULT_GEO_COUNTIES="County1,County2"
DEFAULT_WHISPER_MODEL="large-v3"
DEFAULT_TRANSCRIPTION_MODE="local" # Default to local mode
DEFAULT_WHISPER_SERVER_URL="http://localhost:8000" # Default remote server URL
DEFAULT_OLLAMA_URL="http://localhost:11434"
DEFAULT_OLLAMA_MODEL_ENV=$OLLAMA_MODEL # Use the same model pulled earlier
DEFAULT_MAPPED_TGS="1001,1002,2001,2002"
DEFAULT_TIMEZONE="US/Eastern"
DEFAULT_ENABLE_AUTH="false"
DEFAULT_TARGET_CITIES="City1,City2,City3,City4"
DEFAULT_SUMMARY_LOOKBACK_HOURS="1" # Added default summary hours
DEFAULT_ASK_AI_LOOKBACK_HOURS="8"   # <-- Add this default
# --- NEW: Storage Defaults ---
DEFAULT_STORAGE_MODE="local" # Default to local
DEFAULT_S3_ENDPOINT=""
DEFAULT_S3_BUCKET_NAME=""


# --- Helper Functions ---
print_message() {
  echo "--------------------------------------------------"
  echo "$1"
  echo "--------------------------------------------------"
}

run_command() {
  echo "Executing: $@"
  "$@"
  local status=$?
  if [ $status -ne 0 ]; then
    echo "Error: Command failed with status $status: $@" >&2
  fi
  return $status
}

prompt_yes_no() {
  local prompt_message="$1"
  local default_value="${2:-n}"
  local response
  while true; do
    read -r -p "$prompt_message [Y/n]: " response
    response=${response:-$default_value}
    case "$response" in
      [Yy]* ) return 0;;
      [Nn]* ) return 1;;
      * ) echo "Please answer yes (y) or no (n).";;
    esac
  done
}

prompt_input() {
    local prompt_message="$1"
    local default_value="$2"
    local variable_name="$3"
    local user_input
    read -r -p "$prompt_message [$default_value]: " user_input
    if [[ -z "$user_input" ]]; then
        eval "$variable_name=\"$default_value\""
    else
        user_input=$(echo "$user_input" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
        eval "$variable_name=\"$user_input\""
    fi
}

# --- Installation Steps ---

install_prerequisites() {
  print_message "Updating package lists and installing prerequisites..."
  run_command apt-get update -y || { echo "Failed to update apt lists. Check internet connection and permissions."; exit 1; }
  run_command apt-get install -y git build-essential python3 python3-pip python3-venv ffmpeg nodejs npm curl gpg wget || { echo "Failed to install base packages."; exit 1; }
  print_message "Base prerequisites installed."
}

install_ollama() {
  print_message "Installing Ollama..."
  if command -v ollama &> /dev/null; then
      echo "Ollama appears to be already installed."
  else
      run_command curl -fsSL https://ollama.com/install.sh | sh || { echo "Failed to install Ollama."; return 1; }
  fi
  echo "Pulling Ollama model: $OLLAMA_MODEL (this may take a while)..."
  run_command ollama pull "$OLLAMA_MODEL" || echo "Warning: Failed to pull Ollama model. You may need to run 'ollama pull $OLLAMA_MODEL' manually later."
  print_message "Ollama installation attempted."
}

install_nvidia_components() {
  print_message "NVIDIA GPU Components Check (CUDA/cuDNN/cuBLAS)"
  if ! command -v nvidia-smi &> /dev/null; then
      echo "NVIDIA driver not detected (nvidia-smi command not found)."
      echo "Skipping CUDA/cuDNN/cuBLAS installation guidance. If you have an NVIDIA GPU, please install drivers first."
      export T_DEVICE="cpu"
      return 1
  fi
  if prompt_yes_no "Do you intend to use an NVIDIA GPU for transcription (requires manual CUDA/cuDNN/cuBLAS installation)?"; then
    echo ""
    echo "--- Manual NVIDIA Installation Required ---"
    echo "Okay. Please ensure you have the correct NVIDIA drivers installed."
    echo "You will need to manually install the NVIDIA CUDA Toolkit, cuDNN, and cuBLAS libraries."
    echo "This script will NOT install them automatically."
    echo ""
    echo "Helpful Links (Login likely required):"
    echo "1. CUDA Toolkit: https://developer.nvidia.com/cuda-toolkit-archive"
    echo "   (Choose version matching your driver. Follow NVIDIA's Linux install guide for your distribution)."
    echo "2. cuDNN:        https://developer.nvidia.com/cudnn"
    echo "   (Download the Library for Linux matching your CUDA version. Follow NVIDIA's instructions to install)."
    echo "3. cuBLAS:       https://developer.nvidia.com/cublas"
    echo "   (Often included with CUDA Toolkit. Verify installation or download if needed)."
    echo ""
    echo "After manual installation, make sure to select the 'cuda' option when installing PyTorch below."
    echo "------------------------------------------"
    export T_DEVICE="cuda"
    print_message "NVIDIA components require MANUAL installation."
  else
    echo "Skipping NVIDIA components. PyTorch will be installed for CPU."
    export T_DEVICE="cpu"
  fi
}

clone_repo() {
  print_message "Cloning repository into $INSTALL_DIR..."
  if [ -d "$INSTALL_DIR" ]; then
    echo "Directory $INSTALL_DIR already exists."
    if prompt_yes_no "Do you want to remove the existing directory and re-clone?"; then
      rm -rf "$INSTALL_DIR" || sudo rm -rf "$INSTALL_DIR" || { echo "Failed to remove existing directory."; exit 1; }
    else
      echo "Skipping clone. Using existing directory."
      cd "$INSTALL_DIR" || { echo "Failed to navigate to $INSTALL_DIR"; exit 1; }
      return 0
    fi
  fi
  run_command mkdir -p "$INSTALL_DIR" || { echo "Failed to create directory $INSTALL_DIR."; exit 1; }
  local original_user=${SUDO_USER:-$(whoami)}
  local original_group=$(id -gn "$original_user")
  run_command chown "$original_user:$original_group" "$INSTALL_DIR"
  cd "$INSTALL_DIR" || { echo "Failed to navigate to $INSTALL_DIR"; exit 1; }
  sudo -u "$original_user" git clone "$GIT_REPO_URL" . || { echo "Failed to clone repository."; exit 1; }
  run_command chown -R "$original_user:$original_group" "$INSTALL_DIR"
  print_message "Repository cloned."
}

# *** UPDATED FUNCTION ***
create_env_file() {
    print_message "Creating .env configuration file..."
    cd "$INSTALL_DIR" || exit 1
    local env_file=".env"
    local needs_manual_edit=() # Array to track items needing manual input

    if [ -f "$env_file" ]; then
        if ! prompt_yes_no "$env_file already exists. Overwrite it?"; then
            echo "Skipping .env creation. Please configure manually."
            return
        fi
        rm "$env_file"
    fi

    echo "Please provide the following configuration values. Press Enter to accept the default."

    # Helper to append to file
    append_env() { echo "$1" >> "$env_file"; }

    # --- Discord ---
    append_env "#################################################################"
    append_env "##                       DISCORD BOT SETTINGS                  ##"
    append_env "#################################################################"
    append_env ""
    append_env "# Discord Bot Token (Required)"
    read -r -p "Enter DISCORD_TOKEN: " discord_token
    if [[ -z "$discord_token" ]]; then
        append_env "DISCORD_TOKEN=your_discord_token_here # <<< MANUALLY EDIT REQUIRED"
        needs_manual_edit+=("DISCORD_TOKEN")
    else
        append_env "DISCORD_TOKEN=$discord_token"
    fi
    append_env "# CLIENT_ID is no longer required by the bot."
    append_env "CLIENT_ID="
    append_env ""
    
    # --- Storage ---
    append_env "#################################################################"
    append_env "##                     STORAGE SETTINGS                        ##"
    append_env "#################################################################"
    append_env ""
    append_env "# --- Storage Mode ---"
    append_env "# Select 'local' (saves audio files to ./audio folder) or 's3' (saves to S3-compatible storage)"
    prompt_input "Enter STORAGE_MODE ('local' or 's3')" "$DEFAULT_STORAGE_MODE" storage_mode
    append_env "STORAGE_MODE=$storage_mode"
    append_env ""
    append_env "# --- S3 Settings (Only used if STORAGE_MODE=s3) ---"
    if [[ "$storage_mode" == "s3" ]]; then
        prompt_input "Enter S3_ENDPOINT (URL of your S3-compatible storage)" "$DEFAULT_S3_ENDPOINT" s3_endpoint
        if [[ -z "$s3_endpoint" ]]; then
             append_env "S3_ENDPOINT=                     # <<< MANUALLY EDIT REQUIRED if STORAGE_MODE=s3"
             needs_manual_edit+=("S3_ENDPOINT")
        else
             append_env "S3_ENDPOINT=$s3_endpoint"
        fi
        prompt_input "Enter S3_BUCKET_NAME" "$DEFAULT_S3_BUCKET_NAME" s3_bucket_name
        if [[ -z "$s3_bucket_name" ]]; then
             append_env "S3_BUCKET_NAME=                 # <<< MANUALLY EDIT REQUIRED if STORAGE_MODE=s3"
             needs_manual_edit+=("S3_BUCKET_NAME")
        else
             append_env "S3_BUCKET_NAME=$s3_bucket_name"
        fi
        read -r -p "Enter S3_ACCESS_KEY_ID: " s3_access_key_id
        if [[ -z "$s3_access_key_id" ]]; then
             append_env "S3_ACCESS_KEY_ID=              # <<< MANUALLY EDIT REQUIRED if STORAGE_MODE=s3"
             needs_manual_edit+=("S3_ACCESS_KEY_ID")
        else
             append_env "S3_ACCESS_KEY_ID=$s3_access_key_id"
        fi
        read -r -p "Enter S3_SECRET_ACCESS_KEY: " s3_secret_access_key
        if [[ -z "$s3_secret_access_key" ]]; then
             append_env "S3_SECRET_ACCESS_KEY=           # <<< MANUALLY EDIT REQUIRED if STORAGE_MODE=s3"
             needs_manual_edit+=("S3_SECRET_ACCESS_KEY")
        else
             append_env "S3_SECRET_ACCESS_KEY=$s3_secret_access_key"
        fi
    else
        append_env "S3_ENDPOINT=                     # Ignored if STORAGE_MODE=local"
        append_env "S3_BUCKET_NAME=                 # Ignored if STORAGE_MODE=local"
        append_env "S3_ACCESS_KEY_ID=              # Ignored if STORAGE_MODE=local"
        append_env "S3_SECRET_ACCESS_KEY=           # Ignored if STORAGE_MODE=local"
    fi
    append_env ""

    # --- Server Ports & Network ---
    append_env "#################################################################"
    append_env "##                  SERVER & NETWORK SETTINGS                  ##"
    append_env "#################################################################"
    append_env ""
    append_env "# Port for incoming SDRTrunk/TrunkRecorder uploads"
    prompt_input "Enter BOT_PORT (for SDRTrunk/TR)" "$DEFAULT_BOT_PORT" bot_port
    append_env "BOT_PORT=$bot_port"
    append_env ""
    append_env "# Port for the web interface/API server"
    prompt_input "Enter WEBSERVER_PORT (e.g., 80, 8080)" "$DEFAULT_WEBSERVER_PORT" webserver_port
    append_env "WEBSERVER_PORT=$webserver_port"
    append_env ""
    append_env "# Public domain name or IP address used for creating audio playback links"
    prompt_input "Enter PUBLIC_DOMAIN (IP or domain name for audio links)" "$DEFAULT_PUBLIC_DOMAIN" public_domain
    append_env "PUBLIC_DOMAIN=$public_domain"
    append_env ""
    append_env "# Timezone for logging timestamps (e.g., US/Eastern, America/Chicago, UTC)"
    prompt_input "Enter TIMEZONE" "$DEFAULT_TIMEZONE" timezone
    append_env "TIMEZONE=$timezone"
    append_env ""

    # --- Auth & API Keys ---
    append_env "#################################################################"
    append_env "##                   AUTHENTICATION & API KEYS                 ##"
    append_env "#################################################################"
    append_env ""
    append_env "# Path to the JSON file containing hashed API keys for SDRTrunk/TR uploads"
    prompt_input "Enter API_KEY_FILE path" "$DEFAULT_API_KEY_FILE" api_key_file
    append_env "API_KEY_FILE=$api_key_file      # Edit and run GenApiKey.js to create/update keys"
    append_env ""
    append_env "# Enable/disable password authentication for the web interface"
    prompt_input "Enable Webserver Authentication? (true/false)" "$DEFAULT_ENABLE_AUTH" enable_auth
    append_env "ENABLE_AUTH=$enable_auth                 # Set to 'true' to enable password login"
    append_env "# Password for web interface login (only used if ENABLE_AUTH=true)"
    if [[ "$enable_auth" == "true" ]]; then
        read -r -p "Enter WEBSERVER_PASSWORD (for web login): " webserver_password
        if [[ -z "$webserver_password" ]]; then
             append_env "WEBSERVER_PASSWORD=your_password # <<< MANUALLY EDIT REQUIRED"
             needs_manual_edit+=("WEBSERVER_PASSWORD (since auth enabled)")
        else
             append_env "WEBSERVER_PASSWORD=$webserver_password"
        fi
    else
         append_env "WEBSERVER_PASSWORD=whatappisthat  # Run init-admin.js after changing this if auth is enabled"
    fi
    append_env ""

    # --- Transcription ---
    append_env "#################################################################"
    append_env "##                    TRANSCRIPTION SETTINGS                   ##"
    append_env "#################################################################"
    append_env ""
    append_env "# --- Transcription Provider Selection ---"
    append_env "# Specifies the service to use for audio transcription."
    append_env "# 'local': Uses a local Python script (requires appropriate hardware and setup)."
    append_env "# 'remote': Uses a self-hosted faster-whisper compatible API endpoint."
    append_env "# 'openai': Uses the official OpenAI Whisper API (requires OPENAI_API_KEY)."
    append_env "# 'icad': Uses a custom faster-whisper server with OpenAI-compatible interface and profiles."
    append_env "# This setting is REQUIRED."
    prompt_input "Enter TRANSCRIPTION_MODE ('local', 'remote', 'openai', or 'icad')" "$DEFAULT_TRANSCRIPTION_MODE" transcription_mode
    append_env "TRANSCRIPTION_MODE=$transcription_mode"
    append_env ""
    append_env "# --- Local Transcription Settings (Required if TRANSCRIPTION_MODE is 'local') ---"
    append_env "# Specifies the hardware to use for transcription."
    append_env "# Use 'cuda' for an NVIDIA GPU (recommended for performance) or 'cpu' for the CPU."
    if [[ "$transcription_mode" == "local" ]]; then
        prompt_input "Enter TRANSCRIPTION_DEVICE ('cpu' or 'cuda')" "${T_DEVICE:-cpu}" transcription_device
        append_env "TRANSCRIPTION_DEVICE=$transcription_device"
    else
        append_env "TRANSCRIPTION_DEVICE=cpu # Ignored unless TRANSCRIPTION_MODE=local"
    fi
    append_env ""
    append_env "# --- Faster-Whisper Settings (Required if TRANSCRIPTION_MODE is 'remote') ---"
    append_env "# The URL of your self-hosted transcription server."
    if [[ "$transcription_mode" == "remote" ]]; then
        prompt_input "Enter FASTER_WHISPER_SERVER_URL" "$DEFAULT_WHISPER_SERVER_URL" whisper_server_url
        append_env "FASTER_WHISPER_SERVER_URL=$whisper_server_url"
        append_env "# Optional: Specify a model for the remote server to use."
        prompt_input "Enter WHISPER_MODEL" "$DEFAULT_WHISPER_MODEL" whisper_model
        append_env "WHISPER_MODEL=$whisper_model"
    else
        append_env "FASTER_WHISPER_SERVER_URL=$DEFAULT_WHISPER_SERVER_URL # Ignored unless TRANSCRIPTION_MODE=remote"
        append_env "WHISPER_MODEL=$DEFAULT_WHISPER_MODEL # Ignored unless TRANSCRIPTION_MODE=remote"
    fi
    append_env ""
    append_env "# --- ICAD Transcription Settings (Required if TRANSCRIPTION_MODE is 'icad') ---"
    append_env "# The URL of your ICAD transcription API server (OpenAI-compatible interface)."
    if [[ "$transcription_mode" == "icad" ]]; then
        prompt_input "Enter ICAD_URL" "http://127.0.0.1:8080" icad_url
        append_env "ICAD_URL=$icad_url"
        append_env "# Optional: API key for ICAD authentication (if your ICAD server requires it)."
        read -r -p "Enter ICAD_API_KEY (leave blank if not needed): " icad_api_key
        if [[ -z "$icad_api_key" ]]; then
            append_env "# ICAD_API_KEY=your_icad_api_key_here"
        else
            append_env "ICAD_API_KEY=$icad_api_key"
        fi
        append_env "# Optional: Specify a model or profile for ICAD to use (e.g., \"tiny|analog-radio\")."
        append_env "# If not specified, defaults to 'whisper-1'. Profiles allow you to combine model and settings."
        prompt_input "Enter ICAD_PROFILE (model or model|profile)" "tiny" icad_profile
        append_env "ICAD_PROFILE=$icad_profile"
    else
        append_env "ICAD_URL=http://127.0.0.1:8080 # Ignored unless TRANSCRIPTION_MODE=icad"
        append_env "# ICAD_API_KEY=your_icad_api_key_here # Ignored unless TRANSCRIPTION_MODE=icad"
        append_env "ICAD_PROFILE=tiny # Ignored unless TRANSCRIPTION_MODE=icad"
    fi
    append_env ""
    append_env "# Note: The OPENAI_API_KEY from the section below is used if TRANSCRIPTION_MODE is 'openai'."
    append_env ""
    
    # --- OpenAI Transcription Prompt (Only used if TRANSCRIPTION_MODE=openai) ---
    append_env "# Custom prompt to improve scanner audio transcription quality"
    append_env "# This helps OpenAI better understand and transcribe police/fire/EMS scanner audio"
    append_env "OPENAI_TRANSCRIPTION_PROMPT=\"This is audio from a police/fire/EMS scanner radio system. The audio may contain:"
    append_env "- Emergency dispatch calls and responses"
    append_env "- Radio communication between first responders"
    append_env "- Background noise, static, and radio artifacts"
    append_env "- Police codes, fire terminology, and emergency abbreviations"
    append_env "- Addresses, locations, and incident descriptions"
    append_env "- Names, unit numbers, and call signs"
    append_env ""
    append_env "Please transcribe the audio clearly, maintaining the original meaning and context. If you hear addresses, locations, or specific details, transcribe them accurately. Handle background noise gracefully and focus on the main communication content.\""
    append_env ""
    
    # Note: whisper-1 automatically handles VAD and chunking on OpenAI's servers
    # No additional configuration needed - just send the audio file
    append_env ""

    # --- Geocoding ---
    append_env "#################################################################"
    append_env "##                  GEOCODING & LOCATION SETTINGS              ##"
    append_env "#################################################################"
    append_env ""
    append_env "# --- Geocoding API Keys ---"
    append_env "# INSTRUCTIONS:"
    append_env "# 1. Ensure you are using the correct 'geocoding.js' file for your desired provider (Google or LocationIQ)."
    append_env "# 2. Provide the API key ONLY for the provider whose 'geocoding.js' file you are using."
    append_env "# 3. You can comment out the unused key with a '#' to avoid confusion."
    append_env ""
    append_env "# Google Maps API Key (Required ONLY if using the Google version of 'geocoding.js')"
    read -r -p "Enter GOOGLE_MAPS_API_KEY (leave blank if using LocationIQ): " google_maps_key
    if [[ -z "$google_maps_key" ]]; then
        append_env "# GOOGLE_MAPS_API_KEY=your_google_maps_api_key_here"
        needs_manual_edit+=("GOOGLE_MAPS_API_KEY (if using Google geocoding.js)")
    else
        append_env "GOOGLE_MAPS_API_KEY=$google_maps_key"
    fi
    append_env ""
    append_env "# LocationIQ API Key (Required ONLY if using the LocationIQ version of 'geocoding.js')"
    read -r -p "Enter LOCATIONIQ_API_KEY (leave blank if using Google): " location_iq_key
    if [[ -z "$location_iq_key" ]]; then
        append_env "# LOCATIONIQ_API_KEY=your_locationiq_api_key_here"
        needs_manual_edit+=("LOCATIONIQ_API_KEY (if using LocationIQ geocoding.js)")
    else
        append_env "LOCATIONIQ_API_KEY=$location_iq_key"
    fi
    append_env ""
    append_env "# --- Location Hints (Used by both providers) ---"
    append_env "# Default location hints for the geocoder"
    prompt_input "Enter GEOCODING_CITY (Default City)" "$DEFAULT_GEO_CITY" geo_city
    append_env "GEOCODING_CITY=\"$geo_city\"        # Default city"
    prompt_input "Enter GEOCODING_STATE (Default State Abbreviation, e.g., ST)" "$DEFAULT_GEO_STATE" geo_state
    append_env "GEOCODING_STATE=$geo_state                    # Default state abbreviation (e.g., MD, VA)"
    prompt_input "Enter GEOCODING_COUNTRY (Default Country Abbreviation)" "$DEFAULT_GEO_COUNTRY" geo_country
    append_env "GEOCODING_COUNTRY=$geo_country                  # Default country abbreviation"
    append_env ""
    append_env "# Target counties for address validation (comma-separated)"
    prompt_input "Enter GEOCODING_TARGET_COUNTIES" "$DEFAULT_GEO_COUNTIES" geo_counties
    append_env "GEOCODING_TARGET_COUNTIES=\"$geo_counties\""
    append_env ""
    append_env "# Target cities for address extraction hints (comma-separated)"
    prompt_input "Enter TARGET_CITIES_LIST" "$DEFAULT_TARGET_CITIES" target_cities_list
    append_env "TARGET_CITIES_LIST=$target_cities_list"
    append_env ""


    # --- LLM & AI Summary ---
    append_env "#################################################################"
    append_env "##                LLM & AI SUMMARY SETTINGS                    ##"
    append_env "#################################################################"
    append_env ""
    append_env "# --- AI Provider Selection ---"
    append_env "# Specifies the AI service to use for all AI-powered features (summary, ask AI, etc.)."
    append_env "# Use 'ollama' for a local instance, or 'openai' for the OpenAI API."
    append_env "# This setting is REQUIRED."
    prompt_input "Enter AI_PROVIDER ('ollama' or 'openai')" "ollama" ai_provider
    append_env "AI_PROVIDER=$ai_provider"
    append_env ""
    append_env "# --- Ollama Settings (Required if AI_PROVIDER is 'ollama') ---"
    append_env "# URL for your running Ollama instance."
    if [[ "$ai_provider" == "ollama" ]]; then
        prompt_input "Enter OLLAMA_URL" "$DEFAULT_OLLAMA_URL" ollama_url
        append_env "OLLAMA_URL=$ollama_url"
        append_env "# The Ollama model to use for address extraction, summarization, etc."
        prompt_input "Enter OLLAMA_MODEL (e.g., llama3.1:8b)" "$DEFAULT_OLLAMA_MODEL_ENV" ollama_model_env
        append_env "OLLAMA_MODEL=$ollama_model_env"
    else
        append_env "OLLAMA_URL=$DEFAULT_OLLAMA_URL # Ignored unless AI_PROVIDER=ollama"
        append_env "OLLAMA_MODEL=$DEFAULT_OLLAMA_MODEL_ENV # Ignored unless AI_PROVIDER=ollama"
    fi
    append_env ""
    append_env "# --- OpenAI Settings (Required if AI_PROVIDER is 'openai') ---"
    append_env "# Your API key from OpenAI. Also used for 'openai' transcription mode."
    if [[ "$ai_provider" == "openai" || "$transcription_mode" == "openai" ]]; then
        read -r -p "Enter OPENAI_API_KEY: " openai_key
        if [[ -z "$openai_key" ]]; then
            append_env "OPENAI_API_KEY=your_openai_api_key_here # <<< MANUALLY EDIT REQUIRED"
            needs_manual_edit+=("OPENAI_API_KEY")
        else
            append_env "OPENAI_API_KEY=$openai_key"
        fi
        append_env "# Transcription Model (fixed to whisper-1 for OpenAI transcription)"
        append_env "# whisper-1 supports VAD chunking strategy and is the most reliable option"
        append_env "OPENAI_TRANSCRIPTION_MODEL=whisper-1"
        append_env ""
        append_env "# Model for AI features like address extraction, summaries, etc. (gpt-4o, gpt-4o-mini, gpt-3.5-turbo)"
        prompt_input "Enter OPENAI_AI_MODEL (e.g., gpt-4o, gpt-4o-mini)" "gpt-4o-mini" openai_ai_model
        append_env "OPENAI_AI_MODEL=$openai_ai_model"
    else
        append_env "OPENAI_API_KEY=your_openai_api_key_here # Ignored unless AI_PROVIDER=openai or TRANSCRIPTION_MODE=openai"
        append_env "OPENAI_TRANSCRIPTION_MODEL=gpt-4o-mini-transcribe # Ignored unless TRANSCRIPTION_MODE=openai"
        append_env "OPENAI_AI_MODEL=gpt-4o-mini # Ignored unless AI_PROVIDER=openai"
    fi
    append_env ""
    append_env "# --- Summary Settings ---"
    append_env "# How many hours back the AI summary should cover."
    prompt_input "Enter SUMMARY_LOOKBACK_HOURS (e.g., 1, 0.5)" "$DEFAULT_SUMMARY_LOOKBACK_HOURS" summary_hours
    append_env "SUMMARY_LOOKBACK_HOURS=$summary_hours"
    append_env "# How many hours of history the 'Ask AI' feature should consider."
    prompt_input "Enter ASK_AI_LOOKBACK_HOURS (e.g., 8, 12)" "$DEFAULT_ASK_AI_LOOKBACK_HOURS" ask_ai_hours
    append_env "ASK_AI_LOOKBACK_HOURS=$ask_ai_hours"
    append_env ""

    # --- Talk Group Mappings ---
    append_env "#################################################################"
    append_env "##                     TALK GROUP MAPPINGS                     ##"
    append_env "#################################################################"
    append_env ""
    append_env "# --- Address Extraction Mapping ---"
    append_env "# Comma-separated list of Talk Group IDs where address extraction should be attempted"
    append_env "# Recommend using dispatch talkgroups only."
    prompt_input "Enter MAPPED_TALK_GROUPS" "$DEFAULT_MAPPED_TGS" mapped_tgs
    append_env "MAPPED_TALK_GROUPS=$mapped_tgs"
    append_env ""
    append_env "# --- Location Descriptions for Mapped Talk Groups ---"
    append_env "# REQUIRED: Add one line for EACH Talk Group ID listed in MAPPED_TALK_GROUPS above."
    append_env "# Format: TALK_GROUP_<ID>=Location Description for LLM context"
    append_env "# Example: TALK_GROUP_1234=Any Town or Area within Your County ST"
    append_env "# --- MANUALLY EDIT THE FOLLOWING SECTION ---"
    # Split the mapped TGs and add commented out examples
    IFS=',' read -ra tgs_array <<< "$mapped_tgs"
    for tgId in "${tgs_array[@]}"; do
        # Trim whitespace
        tgId=$(echo "$tgId" | sed 's/^[ \t]*//;s/[ \t]*$//')
        if [[ -n "$tgId" ]]; then
            append_env "# TALK_GROUP_${tgId}=<Location Description for $tgId>"
        fi
    done
    append_env "# --- END MANUAL EDIT SECTION ---"
    needs_manual_edit+=("TALK_GROUP_XXXX mappings")
    append_env ""

    # --- Two-Tone Detection Settings ---
    append_env "#################################################################"
    append_env "##              TWO-TONE DETECTION SETTINGS                    ##"
    append_env "#################################################################"
    append_env ""
    append_env "# Enable/disable two-tone detection mode"
    append_env "ENABLE_TWO_TONE_MODE=true"
    append_env ""
    append_env "# Comma-separated list of Talk Group IDs for two-tone detection"
    append_env "TWO_TONE_TALK_GROUPS=4005"
    append_env ""
    append_env "# Number of calls to check for addresses after tone detection"
    append_env "TWO_TONE_QUEUE_SIZE=1"
    append_env ""
    append_env "# Tone detection type: 'auto', 'cli', or 'python'"
    append_env "TONE_DETECTION_TYPE=auto"
    append_env ""
    append_env "# --- Two-tone parameters ---"
    append_env "TWO_TONE_MIN_TONE_LENGTH=0.7"
    append_env "TWO_TONE_MAX_TONE_LENGTH=3.0"
    append_env "TWO_TONE_BW_HZ=50"
    append_env "TWO_TONE_MIN_PAIR_SEPARATION_HZ=100"
    append_env ""
    append_env "# --- Pulsed tone parameters ---"
    append_env "PULSED_MIN_CYCLES=3"
    append_env "PULSED_MIN_ON_MS=50"
    append_env "PULSED_MAX_ON_MS=500"
    append_env "PULSED_MIN_OFF_MS=25"
    append_env "PULSED_MAX_OFF_MS=800"
    append_env "PULSED_BANDWIDTH_HZ=50"
    append_env ""
    append_env "# --- Long tone parameters ---"
    append_env "LONG_TONE_MIN_LENGTH=0.5"
    append_env "LONG_TONE_BANDWIDTH_HZ=75"
    append_env ""
    append_env "# --- General detection parameters ---"
    append_env "TONE_DETECTION_THRESHOLD=0.3"
    append_env "TONE_FREQUENCY_BAND=300,1500"
    append_env "TONE_TIME_RESOLUTION_MS=15"
    append_env ""

    # Ensure correct ownership of .env file
    local original_user=${SUDO_USER:-$(whoami)}
    local original_group=$(id -gn "$original_user")
    chown "$original_user:$original_group" "$env_file"

    print_message ".env file created in $INSTALL_DIR"
    # Store the list of items needing manual edit for the final reminder
    # Join array elements into a space-separated string for export
    export MANUAL_EDIT_LIST=$(IFS=' '; echo "${needs_manual_edit[*]}")

}

# *** UPDATED FUNCTION ***
install_node_deps() {
  print_message "Installing Node.js dependencies..."
  cd "$INSTALL_DIR" || exit 1
  # Attempt npm install - Added form-data and aws-sdk
  local original_user=${SUDO_USER:-$(whoami)}
  echo "Running npm install as user: $original_user"
  sudo -u "$original_user" npm install dotenv express sqlite3 bcrypt uuid busboy winston moment-timezone @discordjs/opus discord.js @discordjs/voice prism-media node-fetch@2 socket.io csv-parser form-data aws-sdk
  if [ $? -ne 0 ]; then
      echo "npm install failed. Trying again..."
      sudo -u "$original_user" npm install dotenv express sqlite3 bcrypt uuid busboy winston moment-timezone @discordjs/opus discord.js @discordjs/voice prism-media node-fetch@2 socket.io csv-parser form-data aws-sdk || echo "Warning: npm install failed again. Please check errors and try running 'npm install' manually as user '$original_user' in $INSTALL_DIR."
  fi
  print_message "Node.js dependency installation attempted."
}

setup_python_venv() {
  print_message "Setting up Python virtual environment and installing dependencies..."
  cd "$INSTALL_DIR" || exit 1
  local original_user=${SUDO_USER:-$(whoami)}
  local original_group=$(id -gn "$original_user")
  echo "Creating Python virtual environment (.venv) as user: $original_user ..."
  sudo -u "$original_user" python3 -m venv .venv || { echo "Failed to create Python venv."; return 1; }
  echo "Activating virtual environment (for this script)..."
  source .venv/bin/activate || { echo "Failed to activate Python venv."; return 1; }
  echo "Upgrading pip..."
  run_command pip install --upgrade pip
  local torch_install_cmd=""
  local use_cuda=false
  if [[ "$T_DEVICE" == "cuda" ]]; then
      if prompt_yes_no "Install PyTorch with CUDA support (based on your earlier choice)?"; then
          use_cuda=true
      fi
  fi
  if $use_cuda; then
      echo "Please specify your CUDA version for PyTorch (e.g., 11.8, 12.1). Check https://pytorch.org/get-started/locally/"
      read -r -p "Enter CUDA version (leave blank to attempt latest): " cuda_version
      if [[ -z "$cuda_version" ]]; then
           echo "Attempting PyTorch install for latest CUDA (usually 12.1)..."
           torch_install_cmd="pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121"
      elif [[ "$cuda_version" == "11.8" ]]; then
           echo "Installing PyTorch for CUDA 11.8..."
           torch_install_cmd="pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118"
      elif [[ "$cuda_version" == "12.1" ]]; then
           echo "Installing PyTorch for CUDA 12.1..."
           torch_install_cmd="pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121"
      else
           echo "Warning: Unsupported CUDA version specified. Attempting latest CUDA 12.1 install."
           torch_install_cmd="pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121"
      fi
  else
      echo "Installing CPU-only version of PyTorch..."
      torch_install_cmd="pip install torch torchvision torchaudio"
      export T_DEVICE="cpu"
  fi
  run_command $torch_install_cmd || { echo "Failed to install PyTorch."; deactivate; return 1; }
  echo "Installing faster-whisper, python-dotenv, and pydub..."
  run_command pip install faster-whisper python-dotenv pydub || { echo "Failed to install faster-whisper/python-dotenv/pydub."; deactivate; return 1; }
  echo "Installing icad-tone-detection..."
  run_command pip install icad-tone-detection || { echo "Failed to install icad-tone-detection."; deactivate; return 1; }
  echo "Deactivating virtual environment."
  deactivate
  print_message "Python environment setup complete."
}

create_dirs() {
  print_message "Creating required directories..."
  cd "$INSTALL_DIR" || exit 1
  local original_user=${SUDO_USER:-$(whoami)}
  local original_group=$(id -gn "$original_user")
  run_command mkdir -p audio
  run_command mkdir -p data
  run_command mkdir -p logs
  run_command chown -R "$original_user:$original_group" audio data logs
  print_message "Directories created."
}

import_talkgroups() {
    print_message "Import Talk Group Data (Required)"
    echo "This application requires talk group data exported from RadioReference.com."
    echo "1. Go to RadioReference.com and find your desired trunked radio system."
    echo "2. Look for an option to export talk groups (usually requires a Premium Subscription)."
    echo "3. Export the talk groups as a CSV file."
    echo "4. Save the file as 'talkgroups.csv' inside the '$INSTALL_DIR' directory."
    echo "5. (Optional) Export frequencies as 'frequencies.csv' and save it in the same directory."
    echo ""
    local talkgroups_file="$INSTALL_DIR/talkgroups.csv"
    local original_user=${SUDO_USER:-$(whoami)}
    while true; do
        read -r -p "Have you downloaded and saved 'talkgroups.csv' to '$INSTALL_DIR'? [y/n/skip]: " response
        case "$response" in
            [Yy]* )
                if sudo -u "$original_user" [ -f "$talkgroups_file" ]; then
                    echo "Found '$talkgroups_file'. Running import script as user '$original_user'..."
                    cd "$INSTALL_DIR" || exit 1
                    sudo -u "$original_user" node import_csv.js || echo "Warning: Talk group import script encountered an error. Check output."
                    print_message "Talk group import attempted."
                    break
                else
                    echo "Error: '$talkgroups_file' not found in '$INSTALL_DIR' or not accessible by user '$original_user'."
                    echo "Please make sure the file is correctly named and placed, and check permissions."
                fi
                ;;
            [Nn]* )
                echo "Please download the file and place it in the directory, then run this script again or run 'node import_csv.js' manually later as user '$original_user'."
                ;;
            [Ss][Kk][Ii][Pp]* )
                echo "Skipping talk group import. You MUST run 'node import_csv.js' manually later as user '$original_user' after placing the file."
                print_message "Talk group import skipped."
                break
                ;;
            * )
                echo "Please answer yes (y), no (n), or skip (s)."
                ;;
        esac
    done
}

# *** UPDATED FUNCTION ***
manual_steps_reminder() {
  print_message "--- MANUAL CONFIGURATION REQUIRED ---"
  echo "The script has completed the automated steps and created a base .env file."
  echo "You MUST now manually review and potentially edit the following files in '$INSTALL_DIR':"
  echo ""
  echo "1.  '.env' file ('nano $INSTALL_DIR/.env'):"
  echo "    - Verify all values are correct for your setup."
  echo "    - CRITICAL: Add your actual keys/tokens for:"
  local needs_edit_str=""
  # Convert space-separated string back to array-like structure for looping
  for item in $MANUAL_EDIT_LIST; do
      needs_edit_str+="$item, "
  done
  if [[ -n "$needs_edit_str" ]]; then
      needs_edit_str=${needs_edit_str%, }
      echo "      -> $needs_edit_str"
  else
      echo "      -> (Review all placeholders like 'your_..._here')"
  fi
  echo "    - Verify STORAGE_MODE is set correctly ('local' or 's3')."
  echo "    - If STORAGE_MODE=s3, ensure S3 settings are correct."
  echo "    - Verify AI_PROVIDER is set correctly ('ollama' or 'openai')."
      echo "    - If using 'openai', ensure OPENAI_API_KEY, OPENAI_TRANSCRIPTION_MODEL, and OPENAI_AI_MODEL are set."
  echo "    - If using 'ollama', ensure OLLAMA_URL and OLLAMA_MODEL are set."
      echo "    - Verify TRANSCRIPTION_MODE is set correctly ('local', 'remote', 'openai', or 'icad')."
    echo "    - If TRANSCRIPTION_MODE=remote, ensure FASTER_WHISPER_SERVER_URL is correct."
    echo "    - If TRANSCRIPTION_MODE=local, ensure TRANSCRIPTION_DEVICE is correct ('cuda' or 'cpu')."
    echo "    - If TRANSCRIPTION_MODE=openai, ensure OPENAI_API_KEY is also set."
    echo "    - If TRANSCRIPTION_MODE=icad, ensure ICAD_URL is correct and ICAD_API_KEY/ICAD_PROFILE are set if needed."
  echo "    - Choose the correct 'geocoding.js' file (Google vs LocationIQ) for your setup."
  echo "    - Ensure the corresponding API key (GOOGLE_MAPS_API_KEY or LOCATIONIQ_API_KEY) is uncommented and correct."
  echo "    - CRITICAL: Add your specific 'TALK_GROUP_XXXX=Location Description' lines."
  echo ""
  echo "2.  'public/config.js' ('nano $INSTALL_DIR/public/config.js'):"
  echo "    - Review map center, zoom, icons, etc."
  echo ""
  echo "3.  API Key for SDRTrunk/TrunkRecorder:"
  echo "    - API key is now AUTO-GENERATED on first boot!"
  echo "    - Watch the console when you first run 'node bot.js' - it will display the generated key"
  echo "    - Save this key for your SDRTrunk/TrunkRecorder configuration"
  echo "    - The hashed version is automatically saved to 'data/apikeys.json'"
  echo ""
  echo "4.  (If Skipped) Import Talk Groups:"
  echo "    - Place 'talkgroups.csv' / 'frequencies.csv' in '$INSTALL_DIR'."
  echo "    - Talkgroups are now AUTO-IMPORTED on first boot if the CSV file exists!"
  echo ""
  echo "5.  Admin User (if ENABLE_AUTH=true in .env):"
  echo "    - Admin user is now AUTO-CREATED on first boot!"
  echo "    - Uses the WEBSERVER_PASSWORD from your .env file"
  echo ""
  echo "--- HOW TO RUN (NEW INTEGRATED MODE) ---"
  echo "IMPORTANT: The bot now handles everything automatically!"
  echo "1. Open Terminal: cd $INSTALL_DIR && source .venv/bin/activate && node bot.js"
  echo ""
  echo "The bot will now automatically:"
  echo "  ✅ Create database and tables"
  echo "  ✅ Generate API key on first boot"
  echo "  ✅ Import talkgroups from CSV (if not already imported)"
  echo "  ✅ Create admin user (if ENABLE_AUTH=true)"
  echo "  ✅ Start Discord bot services"
  echo "  ✅ Start webserver last (after everything is ready)"
  echo ""
  echo "You NO LONGER need to:"
  echo "  ❌ Run 'node webserver.js' separately"
  echo "  ❌ Run 'node GenApiKey.js' manually"
  echo "  ❌ Run 'node init-admin.js' manually"
  echo "  ❌ Run 'node import_csv.js' manually (if talkgroups.csv exists)"
  echo ""
  echo "Just run 'node bot.js' and everything starts automatically!"
  echo "Note: sudo might still be needed if using privileged ports (80/443) for webserver"
  echo "-------------------------------------"

}

# --- Main Script Execution ---
print_message "Starting Scanner Map Installation..."

# Check if running as root
if [ "$EUID" -ne 0 ]; then
  echo "Please run this script using sudo: sudo bash $0"
  exit 1
fi

install_prerequisites
install_ollama
install_nvidia_components # Will prompt user and provide links
clone_repo
create_env_file # Uses updated function
install_node_deps # Uses updated function
setup_python_venv # Will use T_DEVICE set earlier
create_dirs
import_talkgroups # Uses updated function
manual_steps_reminder # Uses updated function

# --- PAUSE ---
print_message "Installation script finished. Please review the manual steps above."
read -r -p "Press Enter to exit the script..."

exit 0