#!/bin/bash
set -e

# ============================================
# wepanel - One-Click Setup
# Usage: sh <(curl -fsSL https://get.wdpdev.co/setup.sh) [--license-key=KEY]
# ============================================

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

PANEL_VERSION="0.1.0"
PANEL_DIR="/opt/wepanel"
CONFIG_DIR="/etc/wepanel"
LOG_FILE="/var/log/wepanel-install.log"
LICENSE_KEY=""
SOURCE_URL="https://get.wdpdev.co/source.tar.gz"

log_info()  { echo -e "${GREEN}[INFO]${NC} $1"; }
log_step()  { echo -e "\n${CYAN}[${PANEL_VERSION}]${NC} ${BLUE}$1${NC}"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1" >&2; }
log_warn()  { echo -e "${YELLOW}[WARN]${NC} $1"; }

# --- Parse args ---
for arg in "$@"; do
    case $arg in
        --license-key=*) LICENSE_KEY="${arg#*=}" ;;
        --license-url=*) LICENSE_URL="${arg#*=}" ;;
        --source-url=*) SOURCE_URL="${arg#*=}" ;;
        --version=*) PANEL_VERSION="${arg#*=}" ;;
    esac
done

# --- Detect OS ---
detect_os() {
    . /etc/os-release 2>/dev/null || {
        log_error "Cannot detect OS. Unsupported system."
        exit 1
    }
    OS=$ID
    VER=$VERSION_ID
    log_info "Detected OS: ${PRETTY_NAME:-$OS $VER}"

    case $OS in
        ubuntu|debian) PKG_MGR="apt-get" ;;
        almalinux|rocky|rhel|centos) PKG_MGR="dnf" ;;
        *) log_error "Unsupported OS: $OS"; exit 1 ;;
    esac
}

# --- Quick Install Dependencies ---
install_deps() {
    log_step "Installing dependencies (this may take 5-10 minutes)..."

    export DEBIAN_FRONTEND=noninteractive
    export NEEDRESTART_MODE=a

    # Pre-configure Postfix to avoid interactive prompt
    if [ "$PKG_MGR" = "apt-get" ]; then
        echo "postfix postfix/mailname string localhost.localdomain" | debconf-set-selections 2>/dev/null || true
        echo "postfix postfix/main_mailer_type select Local only" | debconf-set-selections 2>/dev/null || true
        apt-get update -qq
    fi

    # --- PHP ---
    log_info "PHP 7.4-8.3 + extensions..."
    if [ "$PKG_MGR" = "apt-get" ]; then
        apt-get install -y -qq software-properties-common apt-transport-https ca-certificates > $LOG_FILE 2>&1
        add-apt-repository -y ppa:ondrej/php > $LOG_FILE 2>&1 || true
        apt-get update -qq > $LOG_FILE 2>&1
        for v in 7.4 8.0 8.1 8.2 8.3; do
            apt-get install -y -qq php${v}-fpm php${v}-cli php${v}-mysql php${v}-curl php${v}-gd php${v}-mbstring php${v}-xml php${v}-zip php${v}-opcache php${v}-intl php${v}-bcmath > $LOG_FILE 2>&1 || true
        done
        update-alternatives --set php /usr/bin/php8.3 > $LOG_FILE 2>&1 || true
    else
        dnf install -y epel-release > $LOG_FILE 2>&1
        dnf install -y https://rpms.remirepo.net/enterprise/remi-release-${VER}.rpm > $LOG_FILE 2>&1 || true
        dnf module reset php -y > $LOG_FILE 2>&1
        dnf module enable php:remi-8.3 -y > $LOG_FILE 2>&1
        dnf install -y php php-fpm php-mysqlnd php-curl php-gd php-mbstring php-xml php-zip php-opcache php-intl php-bcmath > $LOG_FILE 2>&1
    fi
    systemctl restart php8.3-fpm 2>/dev/null || true

    # --- Web Servers ---
    log_info "Nginx + Apache..."
    if [ "$PKG_MGR" = "apt-get" ]; then
        apt-get install -y -qq nginx apache2 > $LOG_FILE 2>&1
    else
        dnf install -y nginx httpd > $LOG_FILE 2>&1
    fi

    # --- Database ---
    log_info "MariaDB + PostgreSQL..."
    if [ "$PKG_MGR" = "apt-get" ]; then
        apt-get install -y -qq mariadb-server postgresql > $LOG_FILE 2>&1
    else
        dnf install -y mariadb-server postgresql-server > $LOG_FILE 2>&1
        postgresql-setup --initdb > $LOG_FILE 2>&1 || true
    fi

    systemctl start mariadb 2>/dev/null || systemctl start mysql 2>/dev/null || true
    systemctl start postgresql 2>/dev/null || true
    mysql -e "SET PASSWORD FOR 'root'@'localhost' = PASSWORD('wepanel_root'); FLUSH PRIVILEGES;" 2>/dev/null || true
    su - postgres -c "psql -c \"CREATE USER wepanel WITH PASSWORD 'wepanel' CREATEDB;\"" 2>/dev/null || true
    su - postgres -c "psql -c \"CREATE DATABASE wepanel OWNER wepanel;\"" 2>/dev/null || true

    # --- Other services ---
    log_info "Bind9, Postfix, Dovecot, Pure-FTPd, Redis..."
    if [ "$PKG_MGR" = "apt-get" ]; then
        apt-get install -y -qq bind9 postfix dovecot-core dovecot-imapd pure-ftpd redis-server pv > $LOG_FILE 2>&1 || true
    else
        dnf install -y bind postfix dovecot pure-ftpd redis pv > $LOG_FILE 2>&1 || true
    fi
    postconf -e "mydomain = localdomain" 2>/dev/null || true
    systemctl restart postfix 2>/dev/null || true

    # --- SSL ---
    log_info "acme.sh..."
    if ! command -v acme.sh &> /dev/null; then
        curl -fsSL https://get.acme.sh | sh > $LOG_FILE 2>&1
        ln -sf /root/.acme.sh/acme.sh /usr/local/bin/acme.sh 2>/dev/null || true
    fi

    # --- Database Managers ---
    log_info "phpMyAdmin + Adminer..."
    if [ "$PKG_MGR" = "apt-get" ]; then
        apt-get install -y -qq phpmyadmin > $LOG_FILE 2>&1 || {
            wget -q https://files.phpmyadmin.net/phpMyAdmin/latest-all-languages.tar.gz -O /tmp/pma.tar.gz
            tar -xzf /tmp/pma.tar.gz -C /usr/share/
            mv /usr/share/phpMyAdmin-* /usr/share/phpmyadmin 2>/dev/null || true
            rm -f /tmp/pma.tar.gz
        }
    else
        wget -q https://files.phpmyadmin.net/phpMyAdmin/latest-all-languages.tar.gz -O /tmp/pma.tar.gz
        tar -xzf /tmp/pma.tar.gz -C /usr/share/
        mv /usr/share/phpMyAdmin-* /usr/share/phpmyadmin 2>/dev/null || true
        rm -f /tmp/pma.tar.gz
    fi
    mkdir -p /usr/share/adminer
    wget -q https://www.adminer.org/latest.php -O /usr/share/adminer/index.php

    # --- Roundcube ---
    log_info "Roundcube Webmail..."
    if [ "$PKG_MGR" = "apt-get" ]; then
        apt-get install -y -qq roundcube roundcube-mysql > $LOG_FILE 2>&1 || {
            wget -q https://github.com/roundcube/roundcubemail/releases/latest/download/roundcubemail-latest-complete.tar.gz -O /tmp/rc.tar.gz
            tar -xzf /tmp/rc.tar.gz -C /usr/share/
            mv /usr/share/roundcubemail-* /usr/share/roundcube 2>/dev/null || true
            rm -f /tmp/rc.tar.gz
        }
    else
        wget -q https://github.com/roundcube/roundcubemail/releases/latest/download/roundcubemail-latest-complete.tar.gz -O /tmp/rc.tar.gz
        tar -xzf /tmp/rc.tar.gz -C /usr/share/
        mv /usr/share/roundcubemail-* /usr/share/roundcube 2>/dev/null || true
        rm -f /tmp/rc.tar.gz
    fi

    # --- Go (if needed for building) ---
    if ! command -v go &> /dev/null; then
        log_info "Installing Go 1.24..."
        GOTAR="/tmp/go.tar.gz"
        curl -fsSL "https://go.dev/dl/go1.24.4.linux-amd64.tar.gz" -o "$GOTAR" 2>/dev/null || \
        wget -q --timeout=60 "https://go.dev/dl/go1.24.4.linux-amd64.tar.gz" -O "$GOTAR" 2>/dev/null

        if [ -f "$GOTAR" ] && [ -s "$GOTAR" ]; then
            tar -C /usr/local -xzf "$GOTAR"
            ln -sf /usr/local/go/bin/go /usr/local/bin/go
            export PATH=/usr/local/go/bin:$PATH
            rm -f "$GOTAR"
            log_info "Go installed: $(go version)"
        else
            log_error "Failed to download Go. Check network."
            rm -f "$GOTAR"
            exit 1
        fi
    else
        export PATH=/usr/local/go/bin:$PATH
    fi
}

# --- Setup Panel ---
setup_panel() {
    log_step "Setting up wepanel..."

    mkdir -p "$PANEL_DIR" "$CONFIG_DIR" /var/log/wepanel /home /home/vmail /home/backups
    mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled
    mkdir -p /etc/bind/zones /etc/ssl/wepanel
    mkdir -p /var/spool/cron/crontabs

    id -u vmail &>/dev/null || useradd -r -d /home/vmail -m -s /sbin/nologin vmail

    JWT_SECRET=$(head -c 32 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 32)
    ADMIN_API_KEY=$(head -c 16 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 16)

    cat > "$CONFIG_DIR/config.env" << EOF
PORT=8080
DATABASE_URL=postgres://wepanel:wepanel@localhost:5432/wepanel?sslmode=disable
MYSQL_DSN=root:wepanel_root@tcp(localhost:3306)/?parseTime=true
JWT_SECRET=${JWT_SECRET}
REDIS_URL=redis://localhost:6379/0
LICENSE_URL=${LICENSE_URL:-https://license.monit.my.id}
LICENSE_KEY=${LICENSE_KEY}
EOF

    # Build or download panel
    log_info "Preparing wepanel source..."
    export PATH=/usr/local/go/bin:$PATH
    SOURCE_DIR="${SOURCE_DIR:-$(dirname "$0")/../backend}"

    if [ ! -f "$SOURCE_DIR/go.mod" ]; then
        log_info "Source not found locally, downloading..."
        mkdir -p /tmp/wepanel-src
        curl -fsSL --max-time 120 "$SOURCE_URL" -o /tmp/wepanel-src.tar.gz 2>/dev/null || \
            wget -q --timeout=120 "$SOURCE_URL" -O /tmp/wepanel-src.tar.gz 2>/dev/null

        if [ -s /tmp/wepanel-src.tar.gz ]; then
            tar -xzf /tmp/wepanel-src.tar.gz -C /tmp/wepanel-src 2>/dev/null || true
            SOURCE_DIR=$(find /tmp/wepanel-src -name "go.mod" -type f 2>/dev/null | head -1)
            [ -n "$SOURCE_DIR" ] && SOURCE_DIR=$(dirname "$SOURCE_DIR")
            [ -z "$SOURCE_DIR" ] && SOURCE_DIR="/tmp/wepanel-src/backend"
            rm -f /tmp/wepanel-src.tar.gz
        else
            log_warn "Source download failed. Will try prebuilt binary."
            rm -f /tmp/wepanel-src.tar.gz
        fi
    fi

    if [ -f "$SOURCE_DIR/go.mod" ]; then
        log_info "Building wepanel from source..."
        export GOPATH=/tmp/gopath
        export PATH=/usr/local/go/bin:$PATH
        cd "$SOURCE_DIR"

        # Download modules first
        log_info "Downloading Go modules..."
        go mod download 2>&1 | tail -3 || true

        # Build server
        log_info "Compiling server..."
        if go build -o "$PANEL_DIR/server" ./cmd/server/ 2>&1; then
            log_info "Server binary built: $(ls -lh $PANEL_DIR/server | awk '{print $5}')"
        else
            log_error "Server build FAILED. Check Go dependencies."
            return 1
        fi

        # Build agent
        go build -o "$PANEL_DIR/agent" ./cmd/agent/ 2>/dev/null && \
            log_info "Agent built" || \
            log_warn "Agent build skipped (non-critical)"

        cp -r i18n "$PANEL_DIR/" 2>/dev/null || true
    else
        log_warn "No source found. Trying prebuilt binary..."
        ARCH=$(uname -m)
        [ "$ARCH" = "x86_64" ] && ARCH="amd64"
        curl -fsSL "https://releases.wepanel.com/${PANEL_VERSION}/wepanel-${ARCH}.tar.gz" -o /tmp/wepanel-bin.tar.gz 2>/dev/null || \
            wget -q "https://releases.wepanel.com/${PANEL_VERSION}/wepanel-${ARCH}.tar.gz" -O /tmp/wepanel-bin.tar.gz 2>/dev/null
        tar -xzf /tmp/wepanel-bin.tar.gz -C "$PANEL_DIR/" 2>/dev/null || true
        rm -f /tmp/wepanel-bin.tar.gz
    fi

    # Nginx configs for tools
    php_socket="/run/php/php8.3-fpm.sock"
    cat > /etc/nginx/sites-available/wepanel-tools.conf << NGX
server {
    listen 8082; server_name _;
    root /usr/share/phpmyadmin; index index.php;
    location / { try_files \$uri \$uri/ /index.php?\$args; }
    location ~ \.php\$ { include fastcgi_params; fastcgi_pass unix:${php_socket}; fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name; }
}
server {
    listen 8083; server_name _;
    root /usr/share/adminer; index index.php;
    location / { try_files \$uri \$uri/ /index.php?\$args; }
    location ~ \.php\$ { include fastcgi_params; fastcgi_pass unix:${php_socket}; fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name; }
}
server {
    listen 8084; server_name _;
    root /usr/share/roundcube; index index.php;
    location / { try_files \$uri \$uri/ /index.php?\$args; }
    location ~ \.php\$ { include fastcgi_params; fastcgi_pass unix:${php_socket}; fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name; }
}
NGX
    ln -sf /etc/nginx/sites-available/wepanel-tools.conf /etc/nginx/sites-enabled/

    # --- systemd services ---
    cat > /etc/systemd/system/wepanel.service << EOF
[Unit]
Description=wepanel Hosting Panel
After=network.target postgresql.service redis.service
[Service]
Type=simple
WorkingDirectory=$PANEL_DIR
EnvironmentFile=$CONFIG_DIR/config.env
ExecStart=$PANEL_DIR/server
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF

    cat > /etc/systemd/system/wepanel-agent.service << EOF
[Unit]
Description=wepanel License Agent
After=network.target
[Service]
Type=simple
EnvironmentFile=$CONFIG_DIR/config.env
ExecStart=$PANEL_DIR/agent
Restart=always
RestartSec=30
[Install]
WantedBy=multi-user.target
EOF

    # Fix PostgreSQL auth for local connections
    log_info "Configuring PostgreSQL authentication..."
    PG_HBA=$(find /etc/postgresql -name pg_hba.conf 2>/dev/null | head -1)
    if [ -n "$PG_HBA" ]; then
        sed -i 's/^host.*all.*all.*127\.0\.0\.1.*scram-sha-256/host    all             all             127.0.0.1\/32            md5/' "$PG_HBA" 2>/dev/null || true
        sed -i 's/^host.*all.*all.*::1.*scram-sha-256/host    all             all             ::1\/128                 md5/' "$PG_HBA" 2>/dev/null || true
        sed -i 's/^local.*all.*all.*peer/local   all             all                                     md5/' "$PG_HBA" 2>/dev/null || true
    fi

    systemctl restart postgresql 2>/dev/null || true
    sleep 2

    su postgres -c "psql -c \"ALTER USER wepanel WITH PASSWORD 'wepanel';\"" 2>/dev/null || true
    su postgres -c "psql -c \"CREATE DATABASE IF NOT EXISTS wepanel OWNER wepanel;\"" 2>/dev/null 2>&1 || true
    su postgres -c "psql -c \"GRANT ALL PRIVILEGES ON DATABASE wepanel TO wepanel;\"" 2>/dev/null || true

    systemctl daemon-reload

    # Start services
    log_info "Starting services..."
    for svc in nginx apache2 php8.3-fpm mariadb postgresql bind9 postfix dovecot pure-ftpd redis; do
        systemctl enable $svc 2>/dev/null || true
        systemctl restart $svc 2>/dev/null || true
    done
    systemctl enable wepanel 2>/dev/null || true
    systemctl restart wepanel 2>/dev/null || true
    systemctl enable wepanel-agent 2>/dev/null || true
    systemctl restart wepanel-agent 2>/dev/null || true

    # Reload nginx untuk tools
    systemctl reload nginx 2>/dev/null || systemctl restart nginx 2>/dev/null || true
}

# --- Print Done ---
print_complete() {
    SERVER_IP=$(hostname -I 2>/dev/null | awk '{print $1}' || echo "YOUR-IP")
    echo ""
    echo -e "${GREEN}============================================${NC}"
    echo -e "${GREEN}  wepanel v${PANEL_VERSION} installed!${NC}"
    echo -e "${GREEN}============================================${NC}"
    echo ""
    echo -e "  ${BLUE}Panel:${NC}        http://${SERVER_IP}:8080"
    echo -e "  ${BLUE}phpMyAdmin:${NC}   http://${SERVER_IP}:8082"
    echo -e "  ${BLUE}Adminer:${NC}      http://${SERVER_IP}:8083"
    echo -e "  ${BLUE}Webmail:${NC}      http://${SERVER_IP}:8084"
    echo ""
    echo -e "  ${YELLOW}Create admin account:${NC}"
    echo -e "  curl -X POST http://localhost:8080/api/v1/auth/register \\"
    echo -e "    -H 'Content-Type: application/json' \\"
    echo -e "    -d '{\"username\":\"admin\",\"email\":\"admin@example.com\",\"password\":\"YOUR_PASS\"}'"
    echo ""
    echo -e "  ${YELLOW}Set license key:${NC}"
    echo -e "  Edit ${CONFIG_DIR}/config.env and set LICENSE_KEY="
    echo ""
    echo -e "  systemctl [start|stop|restart|status] wepanel"
    echo -e "  journalctl -u wepanel -f     # View logs"
    echo ""
}

# ===============
#    MAIN
# ===============
echo ""
echo -e "${CYAN}"
echo "  _    _ _____  _____          _ "
echo " | |  | | ____||  __ \   /\  | |"
echo " | |  | |  _|  | |__) | /  \ | |"
echo " | |/\| | |___ |  ___/ / /\ \| |"
echo "  \/  \/|_____||_|    /_/  \_\_|"
echo ""
echo -e "${NC}  Hosting Panel v${PANEL_VERSION} - One-Click Installer"
echo ""

[ "$(id -u)" -ne 0 ] && { log_error "Run as root (use sudo)"; exit 1; }

detect_os
install_deps
setup_panel
print_complete
