#!/bin/bash

LOG="/root/etiquetaai_install.log"

TOTAL_STEPS=11
CURRENT_STEP=0
STEP_NAME="Inicializando"
START_TIME=$(date +%s)
STATUS_PID=""

# =========================================================
# CORES
# =========================================================

GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
CYAN='\033[0;36m'
WHITE='\033[1;37m'
GRAY='\033[0;37m'
NC='\033[0m'

# =========================================================
# FUNÇÕES DE TELA
# =========================================================

clear_screen() {
    clear
    tput cup 0 0
}

elapsed_time() {
    local NOW
    local DIFF
    local MIN
    local SEC

    NOW=$(date +%s)
    DIFF=$((NOW - START_TIME))

    MIN=$((DIFF / 60))
    SEC=$((DIFF % 60))

    printf "%02d:%02d" "$MIN" "$SEC"
}

draw_header() {

    clear_screen

    echo -e "${CYAN}============================================================${NC}"
    echo -e "${WHITE}              INSTALADOR ETIQUETAAI${NC}"
    echo -e "${GRAY}              $(date '+%d/%m/%Y %H:%M:%S')${NC}"
    echo -e "${CYAN}============================================================${NC}"
    echo ""

    echo -e "${WHITE}Etapa:${NC} $CURRENT_STEP/$TOTAL_STEPS"
    echo -e "${WHITE}Status:${NC} $STEP_NAME"
    echo -e "${WHITE}Tempo:${NC} $(elapsed_time)"
    echo ""

    echo -e "${CYAN}------------------------------------------------------------${NC}"
    echo ""
}

step() {

    CURRENT_STEP=$((CURRENT_STEP + 1))
    STEP_NAME="$1"

    draw_header

    echo -e "${WHITE}[$CURRENT_STEP/$TOTAL_STEPS] $STEP_NAME${NC}"
    echo ""
}

message() {

    echo -e "$1"
}

ok() {

    echo ""
    echo -e "${GREEN}[OK]${NC} $1"

    echo "[OK] $1" >>"$LOG"
}

warn() {

    echo ""
    echo -e "${YELLOW}[AVISO]${NC} $1"

    echo "[AVISO] $1" >>"$LOG"
}

error() {

    echo ""
    echo -e "${RED}[ERRO]${NC} $1"

    echo "[ERRO] $1" >>"$LOG"
}

fail() {

    stop_status

    draw_header

    echo -e "${RED}============================================================${NC}"
    echo -e "${RED}[ERRO] $1${NC}"
    echo -e "${RED}============================================================${NC}"
    echo ""

    echo "Consulte o log:"
    echo ""
    echo "    $LOG"
    echo ""

    echo "A instalação foi interrompida."

    echo ""
    read -p "Pressione ENTER para sair..."

    exit 1
}

# =========================================================
# STATUS FIXO
# =========================================================

start_status() {

    (
        while true; do

            sleep 5

            tput sc

            tput cup 7 0

            echo -e "${GRAY}Status automático: instalador em execução | Etapa $CURRENT_STEP/$TOTAL_STEPS | $(date '+%H:%M:%S') | Tempo $(elapsed_time)${NC}"

            tput rc

        done
    ) &

    STATUS_PID=$!
}

stop_status() {

    if [ -n "$STATUS_PID" ]; then

        kill "$STATUS_PID" 2>/dev/null || true

        wait "$STATUS_PID" 2>/dev/null || true

        STATUS_PID=""

    fi
}

# =========================================================
# EXECUTAR COMANDO
# =========================================================

run() {

    "$@" >>"$LOG" 2>&1

    local STATUS=$?

    if [ $STATUS -ne 0 ]; then
        return $STATUS
    fi

    return 0
}

# =========================================================
# INÍCIO
# =========================================================

clear

echo "Instalador EtiquetaAI" >>"$LOG"
echo "Início: $(date)" >>"$LOG"

START_TIME=$(date +%s)

# =========================================================
# ROOT
# =========================================================

if [ "$EUID" -ne 0 ]; then

    echo "Este instalador precisa ser executado como root."

    exit 1

fi

# =========================================================
# ESCOLHA NODE
# =========================================================

draw_header

echo -e "${WHITE}Escolha a versão do Node.js para instalar:${NC}"
echo ""

echo "  1 - Node 24 LTS (Recomendado)"
echo "  2 - Node 22 LTS"
echo "  3 - Node 20 LTS (Legado)"
echo ""

read -p "Digite 1, 2 ou 3: " NODE_OPTION

case $NODE_OPTION in

    1)

        NODE_SETUP="setup_24.x"
        NODE_VERSION="Node 24 LTS"

        ;;

    2)

        NODE_SETUP="setup_22.x"
        NODE_VERSION="Node 22 LTS"

        ;;

    3)

        NODE_SETUP="setup_20.x"
        NODE_VERSION="Node 20 LTS"

        ;;

    *)

        echo ""
        echo "Opção inválida."

        exit 1

        ;;

esac

echo "Node escolhido: $NODE_VERSION" >>"$LOG"

# =========================================================
# HEARTBEAT
# =========================================================

start_status

# =========================================================
# 1
# =========================================================

step "Atualizando sistema"

message "Executando apt update..."
message ""
message "A saída completa está sendo registrada no log."

if ! run apt update -y; then
    fail "Falha no apt update."
fi

ok "apt update concluído"

message "Executando apt upgrade..."

if ! run apt upgrade -y; then
    fail "Falha no apt upgrade."
fi

ok "Sistema atualizado"

sleep 1

# =========================================================
# 2
# =========================================================

step "Instalando dependências"

message "Instalando:"
message ""
message "  curl"
message "  unzip"
message "  wget"
message "  vim"
message "  netplan.io"
message "  wpasupplicant"
message ""

if ! run apt install -y curl unzip wget vim netplan.io wpasupplicant; then
    fail "Falha na instalação das dependências."
fi

ok "Dependências instaladas"

sleep 1

# =========================================================
# 3
# =========================================================

step "Instalando $NODE_VERSION"

message "Configurando NodeSource..."
message ""

if ! curl -fsSL "https://deb.nodesource.com/$NODE_SETUP" | bash - >>"$LOG" 2>&1; then
    fail "Falha ao configurar NodeSource."
fi

message "Instalando Node.js..."
message ""

if ! run apt install -y nodejs; then
    fail "Falha na instalação do Node.js."
fi

NODE_INSTALLED=$(node --version 2>/dev/null)

if [ -z "$NODE_INSTALLED" ]; then
    fail "Node.js não foi encontrado."
fi

ok "Node.js instalado: $NODE_INSTALLED"

sleep 1

# =========================================================
# 4
# =========================================================

step "Baixando projeto EtiquetaAI"

mkdir -p /root/etiquetaai

cd /root/etiquetaai || fail "Não foi possível acessar /root/etiquetaai."

message "Baixando projeto..."

if ! wget -O etiquetaai.zip \
    https://update.pedeaqui.app/etiquetaai/Etiquetaai_spooler.zip \
    >>"$LOG" 2>&1; then

    fail "Falha ao baixar o projeto."
fi

ok "Projeto baixado"

message "Extraindo arquivos..."

if ! run unzip -o etiquetaai.zip; then
    fail "Falha ao extrair o projeto."
fi

ok "Projeto extraído"

sleep 1

# =========================================================
# 5
# =========================================================

step "Instalando dependências do projeto"

message "Executando npm install..."
message ""
message "Esta etapa pode demorar alguns minutos."
message ""
message "O status no topo continuará sendo atualizado."
message ""

if ! run npm install; then
    fail "Falha no npm install."
fi

ok "Dependências do projeto instaladas"

sleep 1

# =========================================================
# 6
# =========================================================

step "Configurando PM2"

message "Instalando PM2..."

if ! run npm install -g pm2@latest; then
    fail "Falha na instalação do PM2."
fi

ok "PM2 instalado"

message "Iniciando aplicação..."

pm2 delete etiqueta.ai_spoller_raspberry >>"$LOG" 2>&1 || true

if ! pm2 start npm \
    --name etiqueta.ai_spoller_raspberry \
    -- start >>"$LOG" 2>&1; then

    fail "Falha ao iniciar a aplicação."
fi

pm2 save >>"$LOG" 2>&1

ok "Aplicação iniciada"

sleep 1

# =========================================================
# 7
# =========================================================

step "Configurando inicialização automática"

CURRENT_PATH=$PATH

TMP=$(mktemp)

crontab -l >"$TMP" 2>/dev/null || true

if ! grep -q "pm2 resurrect" "$TMP"; then

    echo "PATH=$CURRENT_PATH" >>"$TMP"
    echo "@reboot pm2 resurrect &> /dev/null" >>"$TMP"

fi

crontab "$TMP"

rm -f "$TMP"

ok "PM2 configurado para iniciar automaticamente"

sleep 1

# =========================================================
# 8
# =========================================================

step "Instalando Tailscale"

message "Instalando Tailscale..."
message ""

if ! curl -fsSL https://tailscale.com/install.sh | sh >>"$LOG" 2>&1; then
    fail "Falha na instalação do Tailscale."
fi

ok "Tailscale instalado"

message "Desabilitando gerenciamento de DNS pelo Tailscale..."

if tailscale set --accept-dns=false >>"$LOG" 2>&1; then

    ok "DNS do Tailscale desabilitado"

else

    warn "Não foi possível configurar accept-dns=false."

fi

sleep 1

# =========================================================
# 9
# =========================================================

step "Preparando configuração de rede"

message "IMPORTANTE:"
message ""
message "A rede atual NÃO será alterada nesta etapa."
message ""

message "Removendo configurações antigas do Netplan..."

rm -f /etc/netplan/*.yaml

message "Criando configuração Netplan..."

cat >/etc/netplan/01-network.yaml <<'EOF'
network:
  version: 2
  renderer: networkd

  ethernets:
    eth0:
      dhcp4: true
      dhcp6: false
      accept-ra: false
      dhcp4-overrides:
        use-dns: false
      nameservers:
        addresses:
          - 1.1.1.1
          - 8.8.8.8

  wifis:
    wlan0:
      dhcp4: true
      dhcp6: false
      accept-ra: false
      dhcp4-overrides:
        use-dns: false
      nameservers:
        addresses:
          - 1.1.1.1
          - 8.8.8.8
      access-points:
        "Moto G (5) 7787":
          password: "123@vai@foi"
        "Eder G85":
          password: "11223344"
        "Galaxy S22 Essrrom":
          password: "12345678"
EOF

chmod 600 /etc/netplan/01-network.yaml

message "Validando configuração..."

if ! run netplan generate; then
    fail "Configuração Netplan inválida."
fi

ok "Configuração Netplan validada"

sleep 1

# =========================================================
# 10
# =========================================================

step "Preparando serviços de rede"

message "A rede atual continuará funcionando."
message ""

message "Desabilitando NetworkManager..."

systemctl disable NetworkManager 2>/dev/null || true

message "Removendo NetworkManager..."

apt purge -y network-manager >>"$LOG" 2>&1 || true

apt autoremove -y >>"$LOG" 2>&1 || true

message "Habilitando systemd-networkd para o próximo boot..."

if ! run systemctl enable systemd-networkd; then
    fail "Falha ao habilitar systemd-networkd."
fi

message "Habilitando wpa_supplicant para o próximo boot..."

if ! run systemctl enable wpa_supplicant; then
    fail "Falha ao habilitar wpa_supplicant."
fi

ok "Serviços preparados"

sleep 1

# =========================================================
# 11
# =========================================================

step "Configurando DNS"

cat >/etc/resolv.conf <<'EOF'
nameserver 1.1.1.1
nameserver 8.8.8.8
EOF

chmod 644 /etc/resolv.conf

ok "DNS configurado: 1.1.1.1 / 8.8.8.8"

sleep 1

# =========================================================
# FINAL - PARAR STATUS
# =========================================================

stop_status

draw_header

echo -e "${GREEN}############################################################${NC}"
echo -e "${GREEN}              INSTALAÇÃO FINALIZADA${NC}"
echo -e "${GREEN}############################################################${NC}"
echo ""

echo -e "${GREEN}[OK]${NC} Node.js instalado"
echo -e "${GREEN}[OK]${NC} EtiquetaAI instalado"
echo -e "${GREEN}[OK]${NC} PM2 configurado"
echo -e "${GREEN}[OK]${NC} Tailscale instalado"
echo -e "${GREEN}[OK]${NC} Netplan configurado"
echo -e "${GREEN}[OK]${NC} DNS configurado"
echo -e "${GREEN}[OK]${NC} Serviços de rede preparados"

echo ""
echo -e "${CYAN}============================================================${NC}"
echo -e "${WHITE}                 PRÓXIMA ETAPA${NC}"
echo -e "${CYAN}============================================================${NC}"
echo ""

echo "O Tailscale foi instalado, mas ainda NÃO foi autenticado."
echo ""
echo "Após a rede voltar, execute:"
echo ""
echo -e "${WHITE}    tailscale up --ssh${NC}"
echo ""
echo "Será exibido um endereço para autenticação no navegador."

echo ""
echo -e "${YELLOW}============================================================${NC}"
echo -e "${YELLOW}                    ATENÇÃO${NC}"
echo -e "${YELLOW}============================================================${NC}"
echo ""

echo "A partir deste ponto serão aplicadas as configurações"
echo "definitivas de rede."
echo ""
echo -e "${YELLOW}A conexão SSH PODE SER INTERROMPIDA.${NC}"
echo ""
echo "Isso é esperado e NÃO significa que a instalação falhou."
echo ""
echo "Se a conexão cair:"
echo ""
echo "  1. Aguarde alguns segundos."
echo "  2. Localize o novo IP da Raspberry."
echo "  3. Conecte-se novamente via SSH."
echo "  4. Execute:"
echo ""
echo -e "${WHITE}       tailscale up --ssh${NC}"
echo ""

echo -e "${YELLOW}============================================================${NC}"
echo -e "${YELLOW}       REINICIANDO SERVIÇOS DE REDE EM 5 SEGUNDOS${NC}"
echo -e "${YELLOW}============================================================${NC}"
echo ""

for i in 5 4 3 2 1; do

    echo -ne "\r    Iniciando em ${i} segundos... "

    sleep 1

done

echo ""
echo ""

# =========================================================
# APLICAÇÃO FINAL DA REDE
# =========================================================

echo "    [REDE] Aplicando configuração Netplan..."

netplan apply >>"$LOG" 2>&1

echo "    [REDE] Reiniciando systemd-networkd..."

systemctl restart systemd-networkd >>"$LOG" 2>&1

echo "    [REDE] Reiniciando wpa_supplicant..."

systemctl restart wpa_supplicant >>"$LOG" 2>&1

echo ""
echo -e "${GREEN}############################################################${NC}"
echo -e "${GREEN}        SERVIÇOS DE REDE REINICIADOS${NC}"
echo -e "${GREEN}############################################################${NC}"
echo ""

echo "A conexão SSH pode ter sido interrompida."
echo ""
echo "Caso tenha perdido a conexão:"
echo ""
echo "  Aguarde alguns segundos e conecte-se novamente"
echo "  utilizando o novo IP da Raspberry."
echo ""
echo "Depois execute:"
echo ""
echo -e "${WHITE}    tailscale up --ssh${NC}"
echo ""
echo "Log completo:"
echo ""
echo "    $LOG"
echo ""

echo "Instalação concluída em $(elapsed_time)." >>"$LOG"
echo "Fim: $(date)" >>"$LOG"