#!/bin/bash

#######################################
# SKG UCP - Installation Script
# Self-hosted FiveM User Control Panel
#######################################

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'

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

# Default values
DEFAULT_DB_HOST="localhost"
DEFAULT_DB_PORT="3306"
DEFAULT_DB_NAME="skg_ucp"
DEFAULT_APP_PORT="3000"

echo -e "${CYAN}"
echo "=============================================="
echo "       SKG UCP - Installation Script         "
echo "=============================================="
echo -e "${NC}"

# Detect OS
detect_os() {
    if [ -f /etc/os-release ]; then
        . /etc/os-release
        OS=$ID
    elif [ -f /etc/debian_version ]; then
        OS="debian"
    else
        OS="unknown"
    fi
    echo -e "${BLUE}OS: ${OS}${NC}"
}

command_exists() {
    command -v "$1" >/dev/null 2>&1
}

# Install Node.js
install_nodejs() {
    echo -e "${YELLOW}[1/10] Installing Node.js...${NC}"
    
    if command_exists node; then
        NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
        if [ "$NODE_VERSION" -ge 18 ]; then
            echo -e "${GREEN}Node.js $(node -v) OK${NC}"
            return 0
        fi
    fi
    
    case $OS in
        ubuntu|debian)
            curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
            sudo apt-get install -y nodejs
            ;;
        centos|rhel|fedora|rocky|almalinux)
            curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -
            sudo yum install -y nodejs
            ;;
        arch|manjaro)
            sudo pacman -S --noconfirm nodejs npm
            ;;
        *)
            echo -e "${RED}Unsupported OS. Install Node.js 18+ manually.${NC}"
            exit 1
            ;;
    esac
    
    echo -e "${GREEN}Node.js $(node -v) installed${NC}"
}

install_pnpm() {
    echo -e "${YELLOW}[2/10] Installing pnpm...${NC}"
    if command_exists pnpm; then
        echo -e "${GREEN}pnpm OK${NC}"
        return 0
    fi
    npm install -g pnpm
    echo -e "${GREEN}pnpm installed${NC}"
}

install_pm2() {
    echo -e "${YELLOW}[3/10] Installing PM2...${NC}"
    if command_exists pm2; then
        echo -e "${GREEN}PM2 OK${NC}"
        return 0
    fi
    npm install -g pm2
    echo -e "${GREEN}PM2 installed${NC}"
}

install_mysql_client() {
    echo -e "${YELLOW}[4/10] Installing MySQL client...${NC}"
    if command_exists mysql; then
        echo -e "${GREEN}MySQL client OK${NC}"
        return 0
    fi
    
    case $OS in
        ubuntu|debian)
            sudo apt-get update
            sudo apt-get install -y mysql-client
            ;;
        centos|rhel|fedora|rocky|almalinux)
            sudo yum install -y mysql
            ;;
        arch|manjaro)
            sudo pacman -S --noconfirm mariadb-clients
            ;;
    esac
    echo -e "${GREEN}MySQL client installed${NC}"
}

collect_db_config() {
    echo ""
    echo -e "${CYAN}========== UCP Database ==========${NC}"
    echo -e "${YELLOW}This database will be created automatically.${NC}"
    echo ""
    
    read -p "MySQL Host [$DEFAULT_DB_HOST]: " DB_HOST
    DB_HOST=${DB_HOST:-$DEFAULT_DB_HOST}
    
    read -p "MySQL Port [$DEFAULT_DB_PORT]: " DB_PORT
    DB_PORT=${DB_PORT:-$DEFAULT_DB_PORT}
    
    read -p "MySQL Username: " DB_USER
    while [ -z "$DB_USER" ]; do
        echo -e "${RED}Username required!${NC}"
        read -p "MySQL Username: " DB_USER
    done
    
    read -s -p "MySQL Password: " DB_PASS
    echo ""
    
    read -p "UCP Database Name [$DEFAULT_DB_NAME]: " DB_NAME
    DB_NAME=${DB_NAME:-$DEFAULT_DB_NAME}
    
    echo ""
    echo -e "${CYAN}========== FiveM Game Database ==========${NC}"
    echo -e "${YELLOW}Your existing ESX/QBCore database.${NC}"
    echo ""
    
    read -p "Game DB Host [$DB_HOST]: " GAME_DB_HOST
    GAME_DB_HOST=${GAME_DB_HOST:-$DB_HOST}
    
    read -p "Game DB Port [$DB_PORT]: " GAME_DB_PORT
    GAME_DB_PORT=${GAME_DB_PORT:-$DB_PORT}
    
    read -p "Game DB Name [es_extended]: " GAME_DB_NAME
    GAME_DB_NAME=${GAME_DB_NAME:-es_extended}
    
    read -p "Game DB User [$DB_USER]: " GAME_DB_USER
    GAME_DB_USER=${GAME_DB_USER:-$DB_USER}
    
    echo -n "Game DB Password [Enter = same as above]: "
    read -s GAME_DB_PASS_INPUT
    echo ""
    if [ -z "$GAME_DB_PASS_INPUT" ]; then
        GAME_DB_PASS="$DB_PASS"
    else
        GAME_DB_PASS="$GAME_DB_PASS_INPUT"
    fi
    
    echo ""
    echo -e "${CYAN}========== Application ==========${NC}"
    echo ""
    
    PUBLIC_IP=$(curl -s --connect-timeout 5 ifconfig.me 2>/dev/null || curl -s --connect-timeout 5 icanhazip.com 2>/dev/null || echo "localhost")
    
    read -p "Port [$DEFAULT_APP_PORT]: " APP_PORT
    APP_PORT=${APP_PORT:-$DEFAULT_APP_PORT}
    
    read -p "URL [http://${PUBLIC_IP}:${APP_PORT}]: " APP_URL
    APP_URL=${APP_URL:-http://${PUBLIC_IP}:${APP_PORT}}
}

setup_database() {
    echo -e "${YELLOW}[5/10] Setting up databases...${NC}"
    
    # Build MySQL command based on whether password is set
    if [ -z "$DB_PASS" ]; then
        MYSQL_CMD="mysql -h $DB_HOST -P $DB_PORT -u $DB_USER"
    else
        MYSQL_CMD="mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS"
    fi
    
    # Test MySQL connection (try multiple methods)
    echo -e "${BLUE}Testing MySQL connection...${NC}"
    
    # Method 1: Direct connection
    if $MYSQL_CMD -e "SELECT 1" >/dev/null 2>&1; then
        echo -e "${GREEN}MySQL connection OK${NC}"
    # Method 2: Try with sudo (for auth_socket)
    elif [ "$DB_USER" = "root" ] && sudo mysql -e "SELECT 1" >/dev/null 2>&1; then
        echo -e "${YELLOW}Using sudo for MySQL (auth_socket detected)${NC}"
        MYSQL_CMD="sudo mysql"
        echo -e "${GREEN}MySQL connection OK${NC}"
    # Method 3: Try without password
    elif mysql -h "$DB_HOST" -P "$DB_PORT" -u "$DB_USER" -e "SELECT 1" >/dev/null 2>&1; then
        echo -e "${YELLOW}Connected without password${NC}"
        MYSQL_CMD="mysql -h $DB_HOST -P $DB_PORT -u $DB_USER"
        echo -e "${GREEN}MySQL connection OK${NC}"
    else
        echo -e "${RED}ERROR: Cannot connect to MySQL!${NC}"
        echo -e "${RED}Host: $DB_HOST:$DB_PORT, User: $DB_USER${NC}"
        echo ""
        echo -e "${YELLOW}Troubleshooting tips:${NC}"
        echo "1. Check if MySQL is running: sudo systemctl status mysql"
        echo "2. Try connecting manually: mysql -u $DB_USER -p"
        echo "3. For root with auth_socket: sudo mysql"
        echo "4. Create a new user with password:"
        echo "   sudo mysql -e \"CREATE USER 'ucpuser'@'localhost' IDENTIFIED BY 'yourpassword';\""
        echo "   sudo mysql -e \"GRANT ALL ON *.* TO 'ucpuser'@'localhost';\""
        exit 1
    fi
    
    # Create UCP database
    echo -e "${BLUE}Creating UCP database '$DB_NAME'...${NC}"
    $MYSQL_CMD -e "CREATE DATABASE IF NOT EXISTS \`$DB_NAME\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" 2>/dev/null
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}Database '$DB_NAME' ready${NC}"
    else
        echo -e "${RED}Failed to create database. Trying with sudo...${NC}"
        sudo mysql -e "CREATE DATABASE IF NOT EXISTS \`$DB_NAME\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" 2>/dev/null
        echo -e "${GREEN}Database '$DB_NAME' ready${NC}"
    fi
    
    # Build Game DB MySQL command
    if [ -z "$GAME_DB_PASS" ]; then
        GAME_MYSQL_CMD="mysql -h $GAME_DB_HOST -P $GAME_DB_PORT -u $GAME_DB_USER"
    else
        GAME_MYSQL_CMD="mysql -h $GAME_DB_HOST -P $GAME_DB_PORT -u $GAME_DB_USER -p$GAME_DB_PASS"
    fi
    
    # Test FiveM game database
    echo -e "${BLUE}Testing FiveM game database...${NC}"
    if $GAME_MYSQL_CMD -e "USE \`$GAME_DB_NAME\`" >/dev/null 2>&1; then
        echo -e "${GREEN}Game database '$GAME_DB_NAME' OK${NC}"
        
        # Detect framework
        QB_CHECK=$($GAME_MYSQL_CMD -N -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='$GAME_DB_NAME' AND table_name='players';" 2>/dev/null || echo "0")
        
        if [ "$QB_CHECK" -gt 0 ] 2>/dev/null; then
            DETECTED_FRAMEWORK="qbcore"
            echo -e "${GREEN}Detected: QBCore${NC}"
        else
            DETECTED_FRAMEWORK="esx"
            echo -e "${GREEN}Detected: ESX${NC}"
        fi
    elif sudo mysql -e "USE \`$GAME_DB_NAME\`" >/dev/null 2>&1; then
        echo -e "${YELLOW}Using sudo for game database${NC}"
        GAME_MYSQL_CMD="sudo mysql"
        echo -e "${GREEN}Game database '$GAME_DB_NAME' OK${NC}"
        
        QB_CHECK=$($GAME_MYSQL_CMD -N -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='$GAME_DB_NAME' AND table_name='players';" 2>/dev/null || echo "0")
        if [ "$QB_CHECK" -gt 0 ] 2>/dev/null; then
            DETECTED_FRAMEWORK="qbcore"
            echo -e "${GREEN}Detected: QBCore${NC}"
        else
            DETECTED_FRAMEWORK="esx"
            echo -e "${GREEN}Detected: ESX${NC}"
        fi
    else
        echo -e "${YELLOW}Warning: Cannot access game database '$GAME_DB_NAME'${NC}"
        DETECTED_FRAMEWORK="esx"
    fi
}

create_env_file() {
    echo -e "${YELLOW}[6/10] Creating .env file...${NC}"
    
    JWT_SECRET=$(openssl rand -hex 32 2>/dev/null || head -c 64 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 64)
    API_KEY=$(openssl rand -hex 24 2>/dev/null || head -c 48 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 48)
    
    # URL encode passwords
    DB_PASS_ENCODED=$(printf '%s' "$DB_PASS" | sed 's/@/%40/g; s/:/%3A/g; s/\//%2F/g; s/?/%3F/g; s/#/%23/g')
    GAME_DB_PASS_ENCODED=$(printf '%s' "$GAME_DB_PASS" | sed 's/@/%40/g; s/:/%3A/g; s/\//%2F/g; s/?/%3F/g; s/#/%23/g')
    
    cat > "$SCRIPT_DIR/.env" << EOF
# SKG UCP - Generated $(date)

# UCP Database
DATABASE_URL="mysql://${DB_USER}:${DB_PASS_ENCODED}@${DB_HOST}:${DB_PORT}/${DB_NAME}"

# FiveM Game Database
GAME_DATABASE_URL="mysql://${GAME_DB_USER}:${GAME_DB_PASS_ENCODED}@${GAME_DB_HOST}:${GAME_DB_PORT}/${GAME_DB_NAME}"
GAME_DATABASE_HOST="${GAME_DB_HOST}"
GAME_DATABASE_PORT="${GAME_DB_PORT}"
GAME_DATABASE_NAME="${GAME_DB_NAME}"
GAME_DATABASE_USER="${GAME_DB_USER}"
GAME_DATABASE_PASSWORD="${GAME_DB_PASS}"
GAME_DATABASE_FRAMEWORK="${DETECTED_FRAMEWORK}"

# Application
NEXT_PUBLIC_APP_URL="${APP_URL}"
PORT=${APP_PORT}

# Security
JWT_SECRET="${JWT_SECRET}"
FIVEM_API_KEY="${API_KEY}"

# Discord (configure in web installer)
DISCORD_REDIRECT_URI="${APP_URL}/api/auth/discord/callback"

# Database already configured via Linux installer
DATABASE_CONFIGURED="true"
EOF
    
    chmod 600 "$SCRIPT_DIR/.env"
    FIVEM_API_KEY="$API_KEY"
    echo -e "${GREEN}.env created${NC}"
}

install_dependencies() {
    echo -e "${YELLOW}[7/10] Installing dependencies...${NC}"
    cd "$SCRIPT_DIR"
    
    # Clean install
    rm -rf node_modules/.prisma 2>/dev/null || true
    
    pnpm install
    echo -e "${GREEN}Dependencies installed${NC}"
}

setup_prisma() {
    echo -e "${YELLOW}[8/10] Setting up database schema...${NC}"
    cd "$SCRIPT_DIR"
    
    echo -e "${BLUE}Generating Prisma client...${NC}"
    npx prisma generate
    
    echo -e "${BLUE}Creating database tables...${NC}"
    npx prisma db push --accept-data-loss
    
    echo -e "${GREEN}Database schema ready${NC}"
}

build_app() {
    echo -e "${YELLOW}[9/10] Building application...${NC}"
    cd "$SCRIPT_DIR"
    
    NODE_ENV=production pnpm build
    
    if [ $? -ne 0 ]; then
        echo -e "${RED}Build failed! Check errors above.${NC}"
        exit 1
    fi
    
    echo -e "${GREEN}Build complete${NC}"
}

start_app() {
    echo -e "${YELLOW}[10/10] Starting application...${NC}"
    cd "$SCRIPT_DIR"
    
    # Stop any existing instance
    pm2 delete skg-ucp 2>/dev/null || true
    
    # Create logs directory
    mkdir -p "$SCRIPT_DIR/logs"
    
    # Create a start script that PM2 can execute
    cat > "$SCRIPT_DIR/start-server.sh" << 'STARTSCRIPT'
#!/bin/bash
cd "$(dirname "$0")"
exec npx next start -H 0.0.0.0 -p ${PORT:-3000}
STARTSCRIPT
    chmod +x "$SCRIPT_DIR/start-server.sh"
    
    # Replace PORT placeholder with actual port
    sed -i "s/\${PORT:-3000}/${APP_PORT}/g" "$SCRIPT_DIR/start-server.sh"
    
    # Create ecosystem file for PM2
    cat > "$SCRIPT_DIR/ecosystem.config.cjs" << EOF
module.exports = {
  apps: [{
    name: 'skg-ucp',
    script: '${SCRIPT_DIR}/start-server.sh',
    cwd: '${SCRIPT_DIR}',
    interpreter: '/bin/bash',
    instances: 1,
    exec_mode: 'fork',
    autorestart: true,
    watch: false,
    max_memory_restart: '1G',
    env: {
      NODE_ENV: 'production',
      PORT: ${APP_PORT}
    },
    error_file: '${SCRIPT_DIR}/logs/error.log',
    out_file: '${SCRIPT_DIR}/logs/out.log',
    log_file: '${SCRIPT_DIR}/logs/combined.log',
    time: true
  }]
}
EOF
    
    # Start with PM2 using the ecosystem file
    echo -e "${BLUE}Starting with PM2...${NC}"
    pm2 start ecosystem.config.cjs
    
    # Wait for startup
    echo -e "${BLUE}Waiting for application to start...${NC}"
    sleep 8
    
    # Check status multiple times (app might take time to initialize)
    for i in 1 2 3; do
        PM2_STATUS=$(pm2 jlist 2>/dev/null | grep -o '"status":"[^"]*"' | head -1 | cut -d'"' -f4)
        if [ "$PM2_STATUS" = "online" ]; then
            break
        fi
        sleep 3
    done
    
    if [ "$PM2_STATUS" = "online" ]; then
        echo -e "${GREEN}Application is running!${NC}"
        
        # Health check - try multiple times
        echo -e "${BLUE}Running health check...${NC}"
        for i in 1 2 3 4 5; do
            sleep 2
            HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "http://127.0.0.1:${APP_PORT}/" --connect-timeout 5 2>/dev/null || echo "000")
            
            if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 400 ]; then
                echo -e "${GREEN}Health check passed! (HTTP $HTTP_CODE)${NC}"
                break
            elif [ "$HTTP_CODE" = "000" ]; then
                echo -e "${YELLOW}Attempt $i: Waiting for server...${NC}"
            else
                echo -e "${YELLOW}Attempt $i: HTTP $HTTP_CODE${NC}"
            fi
        done
    else
        echo -e "${RED}Application failed to start!${NC}"
        echo ""
        echo -e "${YELLOW}Error logs:${NC}"
        cat "$SCRIPT_DIR/logs/error.log" 2>/dev/null | tail -50
        echo ""
        echo -e "${YELLOW}Output logs:${NC}"
        cat "$SCRIPT_DIR/logs/out.log" 2>/dev/null | tail -20
        echo ""
        echo -e "${YELLOW}Try running manually:${NC}"
        echo "  cd $SCRIPT_DIR && pnpm start"
        exit 1
    fi
    
    pm2 save
    pm2 startup systemd -u $(whoami) --hp $(eval echo ~$(whoami)) 2>/dev/null || true
}

open_firewall() {
    echo -e "${BLUE}Opening firewall port ${APP_PORT}...${NC}"
    
    if command_exists ufw; then
        sudo ufw allow ${APP_PORT}/tcp 2>/dev/null || true
        echo -e "${GREEN}UFW: Port ${APP_PORT} opened${NC}"
    elif command_exists firewall-cmd; then
        sudo firewall-cmd --permanent --add-port=${APP_PORT}/tcp 2>/dev/null || true
        sudo firewall-cmd --reload 2>/dev/null || true
        echo -e "${GREEN}Firewalld: Port ${APP_PORT} opened${NC}"
    else
        echo -e "${YELLOW}No firewall detected. Manually open port ${APP_PORT} if needed.${NC}"
    fi
}

setup_apache_proxy() {
    echo ""
    read -p "Setup Apache reverse proxy (access via port 80)? (y/n) [n]: " SETUP_PROXY
    
    if [[ "$SETUP_PROXY" =~ ^[Yy]$ ]]; then
        if command_exists apache2 || command_exists httpd; then
            sudo a2enmod proxy proxy_http 2>/dev/null || true
            
            sudo tee /etc/apache2/sites-available/skg-ucp.conf > /dev/null << EOF
<VirtualHost *:80>
    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:${APP_PORT}/
    ProxyPassReverse / http://127.0.0.1:${APP_PORT}/
</VirtualHost>
EOF
            
            sudo a2ensite skg-ucp.conf 2>/dev/null || true
            sudo a2dissite 000-default.conf 2>/dev/null || true
            sudo systemctl restart apache2 2>/dev/null || true
            
            echo -e "${GREEN}Apache configured for port 80${NC}"
        fi
    fi
}

print_complete() {
    echo ""
    echo -e "${GREEN}=============================================="
    echo "         Installation Complete!              "
    echo "==============================================${NC}"
    echo ""
    echo -e "${CYAN}Next Steps:${NC}"
    echo -e "  1. Open: ${YELLOW}${APP_URL}/installucp${NC}"
    echo -e "  2. Configure Discord OAuth"
    echo -e "  3. Set your Admin Discord ID"
    echo ""
    echo -e "${CYAN}FiveM API Key:${NC}"
    echo -e "  ${YELLOW}${FIVEM_API_KEY}${NC}"
    echo ""
    echo -e "${CYAN}PM2 Commands:${NC}"
    echo "  pm2 status           - Check status"
    echo "  pm2 logs skg-ucp     - View logs"
    echo "  pm2 restart skg-ucp  - Restart app"
    echo ""
    echo -e "${CYAN}Logs:${NC}"
    echo "  $SCRIPT_DIR/logs/"
    echo ""
}

# Main
main() {
    detect_os
    echo ""
    
    install_nodejs
    install_pnpm
    install_pm2
    install_mysql_client
    
    collect_db_config
    setup_database
    create_env_file
    install_dependencies
    setup_prisma
    build_app
    start_app
    open_firewall
    setup_apache_proxy
    
    print_complete
}

main
