#!/usr/bin/env bash
set -Eeuo pipefail
cd "$(dirname "$0")"

verde='\033[0;32m'; amarelo='\033[1;33m'; vermelho='\033[0;31m'; nc='\033[0m'
log(){ printf "%b%s%b\n" "$verde" "$*" "$nc"; }
aviso(){ printf "%b%s%b\n" "$amarelo" "$*" "$nc"; }
falha(){ printf "%b%s%b\n" "$vermelho" "$*" "$nc" >&2; exit 1; }

printf '\nAlpha Dente — instalador do Painel Central\n'
printf 'Destino lógico: https://clinicas.alphadente.com.br\n\n'

command -v node >/dev/null || falha 'Node.js não encontrado. Use Node 20+.'
command -v npm  >/dev/null || falha 'npm não encontrado.'
command -v psql >/dev/null || falha 'psql não encontrado. Instale o cliente PostgreSQL antes de continuar.'
NODE_MAJOR="$(node -p "process.versions.node.split('.')[0]")"
[[ "$NODE_MAJOR" -ge 20 ]] || falha "Node $(node -v) é antigo. Use Node 20+."
log "Node $(node -v), npm $(npm -v) e psql disponíveis."

if [[ ! -f .env ]]; then
  echo
  echo 'Informe a URL do banco PostgreSQL JÁ CRIADO para o painel.'
  echo 'Exemplo: postgresql://usuario:senha@127.0.0.1:5432/alpha_control'
  read -r -p 'CONTROL_DATABASE_URL: ' DBURL
  [[ "$DBURL" == postgresql://* || "$DBURL" == postgres://* ]] || falha 'URL PostgreSQL inválida.'
  read -r -p 'Porta local do Node [8899]: ' PORTA
  PORTA="${PORTA:-8899}"
  ALPHA_INSTALL_DB_URL="$DBURL" ALPHA_INSTALL_PORT="$PORTA" node tools/gerar-config.mjs
else
  aviso '.env já existe. Segredos atuais serão preservados.'
fi

set -a
# shellcheck disable=SC1091
source ./.env
set +a

log 'Instalando dependências Node de produção...'
(cd app && npm ci --omit=dev --ignore-scripts)

EXISTE="$(psql "$CONTROL_DATABASE_URL" -Atqc "SELECT CASE WHEN to_regclass('control.plan') IS NULL THEN '0' ELSE '1' END" 2>/dev/null || true)"
if [[ "$EXISTE" != '1' ]]; then
  log 'Inicializando o banco do painel central...'
  psql "$CONTROL_DATABASE_URL" -v ON_ERROR_STOP=1 \
    -f app/control/schema.sql \
    -f app/control/seed.sql \
    -f app/control/migracao-01-tres-eixos.sql \
    -f app/control/migracao-02-identidade.sql \
    -f app/control/migracao-03-backup.sql \
    -f app/control/migracao-04-incremental.sql \
    -f app/control/migracao-05-financeiro.sql \
    -f app/control/migracao-06-comandos.sql \
    -f app/control/migracao-07-instalacao.sql \
    -f app/control/migracao-08-autenticacao.sql \
    -f app/control/migracao-09-ia.sql
else
  aviso 'Banco control já existe. Não vou recriar nem apagar nada.'
fi

node tools/registrar-chave.mjs

ATIVOS="$(psql "$CONTROL_DATABASE_URL" -Atqc "SELECT count(*) FROM control.admin_user WHERE active AND role='super_admin'" 2>/dev/null || echo 0)"
if [[ "$ATIVOS" == '0' ]]; then
  echo
  log 'Vamos criar o primeiro superadministrador com MFA.'
  read -r -p 'Nome do superadmin: ' ADMIN_NOME
  read -r -p 'E-mail do superadmin: ' ADMIN_EMAIL
  while true; do
    read -r -s -p 'Senha (mínimo 12 caracteres): ' ADMIN_SENHA; echo
    read -r -s -p 'Repita a senha: ' ADMIN_SENHA2; echo
    [[ "$ADMIN_SENHA" == "$ADMIN_SENHA2" ]] || { aviso 'As senhas não conferem.'; continue; }
    [[ ${#ADMIN_SENHA} -ge 12 ]] || { aviso 'Use pelo menos 12 caracteres.'; continue; }
    break
  done
  PREP="$(ALPHA_ADMIN_NOME="$ADMIN_NOME" ALPHA_ADMIN_EMAIL="$ADMIN_EMAIL" ALPHA_ADMIN_SENHA="$ADMIN_SENHA" node tools/bootstrap-admin.mjs preparar)"
  unset ADMIN_SENHA ADMIN_SENHA2
  SECRET="$(printf '%s\n' "$PREP" | sed -n 's/^TOTP_SECRET=//p')"
  URI="$(printf '%s\n' "$PREP" | sed -n 's/^TOTP_URI=//p')"
  if [[ -n "$SECRET" ]]; then
    echo
    echo 'No Microsoft Authenticator, Google Authenticator ou equivalente, adicione uma conta manualmente:'
    printf '  Chave TOTP: %s\n' "$SECRET"
    printf '  URI (para gerador de QR, se desejar): %s\n' "$URI"
    echo
    read -r -p 'Digite o código de 6 dígitos exibido no autenticador: ' CODIGO
    CONF="$(ALPHA_ADMIN_EMAIL="$ADMIN_EMAIL" ALPHA_ADMIN_TOTP="$CODIGO" node tools/bootstrap-admin.mjs confirmar)"
    echo "$CONF" | grep -q '^CONFIRMADO=1$' || falha 'Não foi possível confirmar o MFA.'
    mkdir -p saida
    printf '%s\n' "$CONF" | sed -n 's/^RECOVERY=//p' > saida/CODIGOS-RECUPERACAO.txt
    chmod 600 saida/CODIGOS-RECUPERACAO.txt 2>/dev/null || true
    aviso 'Códigos de recuperação gravados em saida/CODIGOS-RECUPERACAO.txt. Guarde-os fora do servidor e apague o arquivo depois.'
  fi
else
  aviso "Já existe $ATIVOS superadmin ativo. O instalador não criará outro."
fi

log 'Fazendo teste local de inicialização...'
node start.cjs > saida/teste-start.log 2>&1 & PID=$!
cleanup(){ kill "$PID" 2>/dev/null || true; }
trap cleanup EXIT
OK=0
for _ in $(seq 1 30); do
  if node -e "fetch('http://127.0.0.1:${PORT}/saude').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"; then OK=1; break; fi
  sleep 1
done
[[ "$OK" == '1' ]] || { tail -80 saida/teste-start.log || true; falha 'O painel não respondeu em /saude.'; }
cleanup; trap - EXIT; wait "$PID" 2>/dev/null || true

log 'Instalação-base concluída.'
echo
echo 'Arquivos importantes:'
echo '  .env                         segredos do painel (NÃO compartilhar)'
echo '  saida/chaves-painel.json    chave PÚBLICA para embutir no Alpha Dente desktop'
echo '  saida/CODIGOS-RECUPERACAO.txt  códigos do primeiro superadmin (se criado)'
echo
echo 'No cPanel/Node Application Manager:'
echo "  Application root: $(pwd)"
echo '  Startup file:     start.cjs'
echo '  Domain:           clinicas.alphadente.com.br'
echo 'Depois reinicie a aplicação pelo cPanel e teste /saude.'
