#!/bin/bash

# HOPS - Homelab Orchestration Provisioning Script
# Primary Management Script
# Version: 3.2.0

# Exit on any error
set -e

# Script version and metadata
readonly SCRIPT_VERSION="3.2.0"
readonly SCRIPT_NAME="HOPS"
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# Default script locations
readonly INSTALLER_SCRIPT="$SCRIPT_DIR/install"
readonly UNINSTALLER_SCRIPT="$SCRIPT_DIR/uninstall"
readonly SERVICE_DEFINITIONS="$SCRIPT_DIR/services"

# Color codes for output
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly BLUE='\033[0;34m'
readonly PURPLE='\033[0;35m'
readonly CYAN='\033[0;36m'
readonly WHITE='\033[1;37m'
readonly NC='\033[0m' # No Color

# Load system utilities
source "$SCRIPT_DIR/lib/system.sh"

# Logging setup (will be set by setup_logging)
LOG_DIR=""
LOG_FILE=""

# Initialize logging
init_logging() {
    setup_logging "hops-main"
}

# Logging function
log() {
    local message="$1"
    local timestamp="$(date '+%Y-%m-%d %T')"
    
    if [[ -w "$LOG_FILE" ]]; then
        echo "$timestamp - $message" >> "$LOG_FILE"
    fi
    
    echo -e "$message"
}

# Error handling
error_exit() {
    log "${RED}❌ ERROR: $1${NC}"
    exit 1
}

# Warning function
warning() {
    log "${YELLOW}⚠️ WARNING: $1${NC}"
}

# Success function
success() {
    log "${GREEN}✅ $1${NC}"
}

# Info function
info() {
    log "${BLUE}ℹ️ $1${NC}"
}

# Clear screen and show header
show_header() {
    clear
    cat << "EOF"

  _    _  ____  ____  ____  
 | |  | ||  _ \|  _ \/ ___| 
 | |__| || |_) | |_) \___ \ 
 |  __  ||  __/|  __/ ___) |
 |_|  |_||_|   |_|   |____/ 

EOF
    echo -e "${CYAN}🚀 Homelab Orchestration Provisioning Script v${SCRIPT_VERSION}${NC}"
    echo -e "${WHITE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\n"
}

# Check if running as root
check_root() {
    if [[ $EUID -ne 0 ]]; then
        error_exit "This script must be run as root or with sudo."
    fi
}

# Validate script dependencies
check_dependencies() {
    local missing_deps=()
    
    # Check for required scripts
    if [[ ! -f "$INSTALLER_SCRIPT" ]]; then
        missing_deps+=("Installer script: $INSTALLER_SCRIPT")
    fi
    
    if [[ ! -f "$UNINSTALLER_SCRIPT" ]]; then
        missing_deps+=("Uninstaller script: $UNINSTALLER_SCRIPT")
    fi
    
    if [[ ! -f "$SERVICE_DEFINITIONS" ]]; then
        missing_deps+=("Service definitions: $SERVICE_DEFINITIONS")
    fi
    
    # Check for required commands
    local required_commands=("curl" "wget" "systemctl")
    for cmd in "${required_commands[@]}"; do
        if ! command -v "$cmd" &>/dev/null; then
            missing_deps+=("Command: $cmd")
        fi
    done
    
    if [[ ${#missing_deps[@]} -gt 0 ]]; then
        error_exit "Missing dependencies:\n$(printf '  • %s\n' "${missing_deps[@]}")"
    fi
}

# Check system requirements
check_system_requirements() {
    info "Checking system requirements..."
    
    # Check OS
    # OS check is handled by lib/system.sh
    detect_os
    if [[ "$OS_NAME_LOWER" != "macos" && ! "$OS_NAME_LOWER" =~ ^(ubuntu|debian|mint)$ ]]; then
        warning "This script is designed for Ubuntu/Debian/Mint systems"
        echo -e "Continue anyway? [y/N]: "
        read -r continue_choice
        [[ ! "$continue_choice" =~ ^[Yy]$ ]] && exit 0
    fi
    
    # Check minimum requirements
    local ram_gb=$(free -g | awk '/^Mem:/{print $2}')
    local disk_gb=$(df -BG --output=avail / | tail -n 1 | tr -d 'G')
    
    if [[ $ram_gb -lt 2 ]]; then
        warning "Low RAM detected: ${ram_gb}GB (2GB+ recommended)"
    fi
    
    if [[ $disk_gb -lt 10 ]]; then
        warning "Low disk space: ${disk_gb}GB (10GB+ recommended)"
    fi
    
    success "System requirements check complete"
}

# Get HOPS installation status
get_installation_status() {
    local status="not_installed"
    local homelab_dirs=(
        "$HOME/hops"
        "/home/*/hops"
        "/opt/hops"
        "/srv/hops"
    )
    
    # Check for existing installation
    for dir in "${homelab_dirs[@]}"; do
        if [[ -f "$dir/docker-compose.yml" ]]; then
            status="installed"
            HOMELAB_DIR="$dir"
            break
        fi
    done
    
    # Check for running containers
    if command -v docker &>/dev/null && docker ps --format "{{.Names}}" | grep -qE "(sonarr|radarr|jellyfin|plex|portainer)"; then
        if [[ "$status" == "not_installed" ]]; then
            status="partial"
        else
            status="running"
        fi
    fi
    
    echo "$status"
}

# Show installation status
show_status() {
    local status=$(get_installation_status)
    
    echo -e "${WHITE}📊 Current Status:${NC}"
    case "$status" in
        "not_installed")
            echo -e "   ${RED}● Not Installed${NC}"
            ;;
        "installed")
            echo -e "   ${YELLOW}● Installed (stopped)${NC}"
            echo -e "   ${BLUE}📂 Location: $HOMELAB_DIR${NC}"
            ;;
        "running")
            echo -e "   ${GREEN}● Running${NC}"
            echo -e "   ${BLUE}📂 Location: $HOMELAB_DIR${NC}"
            ;;
        "partial")
            echo -e "   ${YELLOW}● Partial Installation${NC}"
            ;;
    esac
    echo
}

# Run installer
run_installer() {
    info "Launching HOPS installer..."
    
    if [[ ! -f "$INSTALLER_SCRIPT" ]]; then
        error_exit "Installer script not found: $INSTALLER_SCRIPT"
    fi
    
    # Source the installer function and run it
    if source "$INSTALLER_SCRIPT" && install_hops; then
        success "Installation completed successfully!"
    else
        error_exit "Installation failed. Check logs for details."
    fi
    
    echo -e "\n${WHITE}Press Enter to return to main menu...${NC}"
    read -r
}

# Run uninstaller
run_uninstaller() {
    info "Launching HOPS uninstaller..."
    
    if [[ ! -f "$UNINSTALLER_SCRIPT" ]]; then
        error_exit "Uninstaller script not found: $UNINSTALLER_SCRIPT"
    fi
    
    # Source the uninstaller function and run it
    if source "$UNINSTALLER_SCRIPT" && uninstall_hops; then
        success "Uninstallation completed successfully!"
    else
        error_exit "Uninstallation failed. Check logs for details."
    fi
    
    echo -e "\n${WHITE}Press Enter to return to main menu...${NC}"
    read -r
}

# Show service status
show_service_status() {
    show_header
    echo -e "${WHITE}🔍 Service Status Check${NC}\n"
    
    if ! command -v docker &>/dev/null; then
        warning "Docker is not installed"
        echo -e "\n${WHITE}Press Enter to return to main menu...${NC}"
        read -r
        return
    fi
    
    local status=$(get_installation_status)
    if [[ "$status" == "not_installed" ]]; then
        warning "HOPS is not installed"
        echo -e "\n${WHITE}Press Enter to return to main menu...${NC}"
        read -r
        return
    fi
    
    echo -e "${BLUE}📊 Docker Service Status:${NC}"
    if systemctl is-active --quiet docker; then
        echo -e "   ${GREEN}● Docker daemon: Running${NC}"
    else
        echo -e "   ${RED}● Docker daemon: Stopped${NC}"
    fi
    
    echo -e "\n${BLUE}📦 Container Status:${NC}"
    
    # Source service definitions to get port info
    if [[ -f "$SERVICE_DEFINITIONS" ]]; then
        source "$SERVICE_DEFINITIONS"
    fi
    
    # Known HOPS services with their ports
    local services=(
        "sonarr:8989" "radarr:7878" "lidarr:8686" "readarr:8787"
        "bazarr:6767" "prowlarr:9696" "jellyfin:8096" "plex:32400"
        "overseerr:5055" "jellyseerr:5056" "portainer:9000"
        "traefik:8080" "nginx-proxy-manager:81" "qbittorrent:8082"
        "transmission:9091" "nzbget:6789" "sabnzbd:8080"
        "uptime-kuma:3001" "jellystat:3000"
    )
    
    local running_count=0
    local total_count=0
    
    for service_info in "${services[@]}"; do
        local service_name="${service_info%:*}"
        local service_port="${service_info#*:}"
        
        if docker ps --format "{{.Names}}" | grep -q "^${service_name}$"; then
            ((total_count++))
            local status_symbol="${GREEN}●${NC}"
            local status_text="Running"
            
            # Check if port is accessible
            if curl -sSf --max-time 2 --connect-timeout 1 "http://localhost:${service_port}" >/dev/null 2>&1; then
                status_text="Running & Accessible"
                ((running_count++))
            else
                status_text="Running (starting up)"
                status_symbol="${YELLOW}●${NC}"
            fi
            
            printf "   %s %-20s %s (:%s)\n" "$status_symbol" "$service_name" "$status_text" "$service_port"
        elif docker ps -a --format "{{.Names}}" | grep -q "^${service_name}$"; then
            ((total_count++))
            printf "   %s %-20s %s\n" "${RED}●${NC}" "$service_name" "Stopped"
        fi
    done
    
    if [[ $total_count -eq 0 ]]; then
        echo -e "   ${YELLOW}No HOPS services found${NC}"
    else
        echo -e "\n${WHITE}📈 Summary: ${running_count}/${total_count} services running and accessible${NC}"
    fi
    
    echo -e "\n${WHITE}Press Enter to return to main menu...${NC}"
    read -r
}

# Manage services (start/stop/restart)
manage_services() {
    show_header
    echo -e "${WHITE}🎛️ Service Management${NC}\n"
    
    local status=$(get_installation_status)
    if [[ "$status" == "not_installed" ]]; then
        warning "HOPS is not installed"
        echo -e "\n${WHITE}Press Enter to return to main menu...${NC}"
        read -r
        return
    fi
    
    if [[ -z "$HOMELAB_DIR" ]]; then
        error_exit "Cannot locate homelab directory with docker-compose.yml"
    fi
    
    echo -e "${BLUE}Available actions:${NC}"
    echo -e "  1) Start all services"
    echo -e "  2) Stop all services"
    echo -e "  3) Restart all services"
    echo -e "  4) View logs (recent)"
    echo -e "  5) View logs (follow)"
    echo -e "  6) Update services"
    echo -e "  7) Restart individual service"
    echo -e "  8) Back to main menu"
    
    echo -e "\n${WHITE}Select an option [1-8]: ${NC}"
    read -r choice
    
    cd "$HOMELAB_DIR"
    
    case $choice in
        1)
            info "Starting all services..."
            if docker compose up -d; then
                success "Services started"
            else
                warning "Some services may have failed to start"
            fi
            ;;
        2)
            info "Stopping all services..."
            if docker compose down; then
                success "Services stopped"
            else
                warning "Some services may not have stopped cleanly"
            fi
            ;;
        3)
            info "Restarting all services..."
            if docker compose restart; then
                success "Services restarted"
            else
                warning "Some services may have failed to restart"
            fi
            ;;
        4)
            info "Showing recent logs..."
            docker compose logs --tail=100
            ;;
        5)
            info "Following logs (Ctrl+C to exit)..."
            docker compose logs -f --tail=50
            ;;
        6)
            info "Updating services..."
            if docker compose pull && docker compose up -d; then
                success "Services updated"
            else
                warning "Update may have failed"
            fi
            ;;
        7)
            echo -e "\n${WHITE}Available services:${NC}"
            docker compose ps --services | nl -w2 -s') '
            echo -e "\n${WHITE}Enter service name to restart: ${NC}"
            read -r service_name
            if [[ -n "$service_name" ]]; then
                info "Restarting $service_name..."
                if docker compose restart "$service_name"; then
                    success "$service_name restarted"
                else
                    warning "Failed to restart $service_name"
                fi
            fi
            ;;
        8)
            return
            ;;
        *)
            warning "Invalid option"
            ;;
    esac
    
    echo -e "\n${WHITE}Press Enter to continue...${NC}"
    read -r
}

# Show quick access URLs
show_access_info() {
    show_header
    echo -e "${WHITE}🌐 Service Access Information${NC}\n"
    
    local status=$(get_installation_status)
    if [[ "$status" == "not_installed" ]]; then
        warning "HOPS is not installed"
        echo -e "\n${WHITE}Press Enter to return to main menu...${NC}"
        read -r
        return
    fi
    
    echo -e "${BLUE}📱 Access your services at:${NC}"
    
    # Get local IP
    local local_ip=$(get_primary_ip)
    
    # Service URLs with paths
    local services=(
        "Sonarr:8989:/sonarr"
        "Radarr:7878:/radarr"
        "Lidarr:8686:/lidarr"
        "Readarr:8787:/readarr"
        "Bazarr:6767:"
        "Prowlarr:9696:"
        "Jellyfin:8096:"
        "Plex:32400:/web"
        "Overseerr:5055:"
        "Jellyseerr:5056:"
        "Portainer:9000:"
        "Traefik:8080:"
        "NPM:81:"
        "qBittorrent:8082:"
        "Transmission:9091:"
        "NZBGet:6789:"
        "SABnzbd:8080:"
        "Uptime-Kuma:3001:"
        "Jellystat:3000:"
    )
    
    local active_services=0
    for service_info in "${services[@]}"; do
        local service_name="${service_info%%:*}"
        local service_port="${service_info#*:}"
        local service_path="${service_port#*:}"
        service_port="${service_port%:*}"
        
        if docker ps --format "{{.Names}}" | grep -qi "${service_name,,}"; then
            local url="http://${local_ip}:${service_port}${service_path}"
            printf "   ${GREEN}●${NC} %-15s %s\n" "$service_name" "$url"
            ((active_services++))
        fi
    done
    
    if [[ $active_services -eq 0 ]]; then
        echo -e "   ${YELLOW}No services currently running${NC}"
    fi
    
    echo -e "\n${YELLOW}💡 Tips:${NC}"
    echo -e "   • Bookmark these URLs for easy access"
    echo -e "   • Default credentials are in the .env file"
    echo -e "   • Change default passwords after first login"
    echo -e "   • Some services may take a few minutes to fully start"
    
    echo -e "\n${WHITE}Press Enter to return to main menu...${NC}"
    read -r
}

# Show logs
show_logs() {
    show_header
    echo -e "${WHITE}📋 HOPS Logs${NC}\n"
    
    if [[ ! -d "$LOG_DIR" ]]; then
        warning "No log directory found"
        echo -e "\n${WHITE}Press Enter to return to main menu...${NC}"
        read -r
        return
    fi
    
    echo -e "${BLUE}Available log files:${NC}"
    local log_files=($(find "$LOG_DIR" -name "*.log" -type f | sort -r))
    
    if [[ ${#log_files[@]} -eq 0 ]]; then
        warning "No log files found"
        echo -e "\n${WHITE}Press Enter to return to main menu...${NC}"
        read -r
        return
    fi
    
    local count=1
    for log_file in "${log_files[@]}"; do
        local basename_log=$(basename "$log_file")
        local size=$(du -h "$log_file" | cut -f1)
        local date=$(stat -c %y "$log_file" | cut -d' ' -f1)
        
        printf "  %d) %-40s (%s, %s)\n" "$count" "$basename_log" "$size" "$date"
        ((count++))
    done
    
    echo -e "\n${WHITE}Select a log file to view [1-${#log_files[@]}] or 0 to go back: ${NC}"
    read -r choice
    
    if [[ "$choice" -eq 0 ]]; then
        return
    elif [[ "$choice" -gt 0 && "$choice" -le ${#log_files[@]} ]]; then
        local selected_log="${log_files[$((choice-1))]}"
        echo -e "\n${BLUE}Showing last 50 lines of $(basename "$selected_log"):${NC}\n"
        tail -50 "$selected_log"
    else
        warning "Invalid selection"
    fi
    
    echo -e "\n${WHITE}Press Enter to return to main menu...${NC}"
    read -r
}

# Show help information
show_help() {
    show_header
    echo -e "${WHITE}📚 HOPS Help & Documentation${NC}\n"
    
    echo -e "${BLUE}🎯 What is HOPS?${NC}"
    echo -e "HOPS (Homelab Orchestration Provisioning Script) is an automated installer"
    echo -e "for popular homelab applications including media servers, download clients,"
    echo -e "and monitoring tools.\n"
    
    echo -e "${BLUE}🚀 Quick Start:${NC}"
    echo -e "  1. Run this script as root/sudo"
    echo -e "  2. Choose 'Install HOPS' from the menu"
    echo -e "  3. Configure directories and timezone"
    echo -e "  4. Select your desired services"
    echo -e "  5. Wait for installation to complete"
    echo -e "  6. Access services via the provided URLs\n"
    
    echo -e "${BLUE}📱 Supported Services:${NC}"
    echo -e "  • Media Management: Sonarr, Radarr, Lidarr, Readarr, Bazarr, Prowlarr"
    echo -e "  • Download Clients: qBittorrent, Transmission, NZBGet, SABnzbd"
    echo -e "  • Media Servers: Jellyfin, Plex, Emby, Jellystat"
    echo -e "  • Request Management: Overseerr, Jellyseerr, Ombi"
    echo -e "  • Reverse Proxy: Traefik, Nginx Proxy Manager"
    echo -e "  • Monitoring: Portainer, Uptime Kuma, Watchtower\n"
    
    echo -e "${BLUE}🔧 Requirements:${NC}"
    echo -e "  • Ubuntu/Debian/Mint Linux"
    echo -e "  • 2GB+ RAM (4GB+ recommended)"
    echo -e "  • 10GB+ free disk space"
    echo -e "  • Root/sudo access"
    echo -e "  • Internet connection\n"
    
    echo -e "${BLUE}📁 Default Locations:${NC}"
    local default_homelab_path=$(get_default_homelab_path)
    local default_config_path=$(get_default_config_path)
    local default_media_path=$(get_default_media_path)
    
    echo -e "  • Homelab directory: $default_homelab_path/"
    echo -e "  • App configurations: $default_config_path/"
    echo -e "  • Media storage: $default_media_path/"
    echo -e "  • Logs: $LOG_DIR/\n"
    
    echo -e "${BLUE}🆘 Troubleshooting:${NC}"
    echo -e "  • Check logs in the 'View Logs' menu"
    echo -e "  • Verify Docker is running: docker info"
    echo -e "  • Check container status: docker ps"
    echo -e "  • View service logs: docker logs [service-name]"
    echo -e "  • Restart services: docker compose restart [service-name]\n"
    
    echo -e "${BLUE}🔐 Security Notes:${NC}"
    echo -e "  • Change default passwords in .env file after installation"
    echo -e "  • Configure firewall rules as needed"
    echo -e "  • Regularly update services using the management menu\n"
    
    echo -e "${WHITE}Press Enter to return to main menu...${NC}"
    read -r
}

# Main menu
show_main_menu() {
    local status=$(get_installation_status)
    
    echo -e "${WHITE}🎛️ Main Menu:${NC}"
    echo -e "  1) Install HOPS"
    
    if [[ "$status" != "not_installed" ]]; then
        echo -e "  2) Uninstall HOPS"
        echo -e "  3) Manage Services"
        echo -e "  4) Service Status"
        echo -e "  5) Access Information"
    else
        echo -e "  2) Uninstall HOPS ${YELLOW}(not installed)${NC}"
        echo -e "  3) Manage Services ${YELLOW}(not installed)${NC}"
        echo -e "  4) Service Status ${YELLOW}(not installed)${NC}"
        echo -e "  5) Access Information ${YELLOW}(not installed)${NC}"
    fi
    
    echo -e "  6) View Logs"
    echo -e "  7) Help & Documentation"
    echo -e "  8) Exit"
    
    echo -e "\n${WHITE}Select an option [1-8]: ${NC}"
}

# Main program loop
main() {
    init_logging
    check_root
    check_dependencies
    
    while true; do
        show_header
        show_status
        show_main_menu
        
        read -r choice
        
        case $choice in
            1)
                check_system_requirements
                run_installer
                ;;
            2)
                run_uninstaller
                ;;
            3)
                manage_services
                ;;
            4)
                show_service_status
                ;;
            5)
                show_access_info
                ;;
            6)
                show_logs
                ;;
            7)
                show_help
                ;;
            8)
                info "Thank you for using HOPS!"
                exit 0
                ;;
            *)
                warning "Invalid option. Please select 1-8."
                sleep 2
                ;;
        esac
    done
}

# Script entry point
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main "$@"
fi