#!/usr/bin/env bash
# Instalação integração Mega Contas no servidor Mk-Auth
# Uso: wget -qO- https://megacontas.com.br/painel/public/integracao/mkauth/install.sh | bash

set -euo pipefail

MC_BASE_URL="${MC_BASE_URL:-https://megacontas.com.br}"
MC_INSTALL_DIR="${MC_INSTALL_DIR:-/opt/mk-auth/admin/addons/megacontas}"
MC_CONF="${MC_INSTALL_DIR}/megacontas.conf"
MC_LOG="/var/log/megacontas-mkauth.log"
MC_CRON_FILE="/etc/cron.d/megacontas-mkauth"
MC_DB_NAME="mkradius"

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

info()  { echo -e "${GREEN}[Mega Contas]${NC} $*"; }
warn()  { echo -e "${YELLOW}[Aviso]${NC} $*"; }
fail()  { echo -e "${RED}[Erro]${NC} $*" >&2; exit 1; }

tty_echo() {
  echo -e "$*" >/dev/tty
}

MC_UI=""
MC_UI_AUTO_INSTALLED=0

init_ui() {
  [[ -e /dev/tty ]] || fail "Sem terminal (TTY). Baixe e execute: bash install.sh"
  export TERM="${TERM:-linux}"
  if command -v whiptail >/dev/null 2>&1; then
    MC_UI=whiptail
    return 0
  fi
  if command -v dialog >/dev/null 2>&1; then
    MC_UI=dialog
    return 0
  fi
  if command -v apt-get >/dev/null 2>&1; then
    info "Instalando whiptail (janelas de configuração)..."
    if DEBIAN_FRONTEND=noninteractive apt-get install -y whiptail >/dev/null 2>&1 \
      && command -v whiptail >/dev/null 2>&1; then
      MC_UI=whiptail
      MC_UI_AUTO_INSTALLED=1
      return 0
    fi
  fi
  return 1
}

# Retorna valor no stdout; exit 1 = cancelou
ui_inputbox() {
  local title="$1"
  local text="$2"
  local default="${3:-}"
  $MC_UI --title "$title" --inputbox "$text" 16 78 "$default" 3>&1 1>&2 2>&3
}

ui_yesno() {
  local title="$1"
  local text="$2"
  $MC_UI --title "$title" --yesno "$text" 16 78
}

ui_msgbox() {
  local title="$1"
  local text="$2"
  $MC_UI --title "$title" --msgbox "$text" 12 78
}

# Fallback texto — quando whiptail/dialog indisponível
prompt_important() {
  local var_name="$1"
  local step="$2"
  local title="$3"
  local hint="${4:-}"
  local val=""
  [[ -e /dev/tty ]] || fail "Sem terminal (TTY). Baixe e execute: bash install.sh"
  tty_echo ""
  tty_echo "${CYAN}${BOLD}┌────────────────────────────────────────────────────────────┐${NC}"
  tty_echo "${CYAN}${BOLD}│  PASSO ${step} — ${title}${NC}"
  tty_echo "${CYAN}${BOLD}└────────────────────────────────────────────────────────────┘${NC}"
  [[ -n "$hint" ]] && tty_echo "${YELLOW}${hint}${NC}"
  tty_echo ""
  echo -en "${BOLD}${YELLOW}>>> Digite aqui e pressione ENTER:${NC} " >/dev/tty
  read -r val </dev/tty
  tty_echo ""
  printf -v "$var_name" '%s' "$val"
}

# wget | bash deixa stdin no pipe — prompts leem do terminal real
prompt() {
  local var_name="$1"
  local label="$2"
  local default="${3:-}"
  local val=""
  [[ -e /dev/tty ]] || fail "Sem terminal (TTY). Baixe e execute: bash install.sh"
  if [[ -n "$default" ]]; then
    read -r -p "${label} [${default}]: " val </dev/tty
    val="${val:-$default}"
  else
    read -r -p "${label}: " val </dev/tty
  fi
  printf -v "$var_name" '%s' "$val"
}

prompt_secret() {
  local var_name="$1"
  local label="$2"
  local default="${3:-}"
  local val=""
  [[ -e /dev/tty ]] || fail "Sem terminal (TTY). Baixe e execute: bash install.sh"
  read -r -s -p "${label} [${default}]: " val </dev/tty
  echo "" >/dev/tty
  val="${val:-$default}"
  printf -v "$var_name" '%s' "$val"
}

confirm() {
  local label="$1"
  local val=""
  [[ -e /dev/tty ]] || fail "Sem terminal (TTY). Baixe e execute: bash install.sh"
  read -r -p "${label} " val </dev/tty
  printf '%s' "$val"
}

require_root() {
  if [[ "$(id -u)" -ne 0 ]]; then
    fail "Execute como root (SSH do servidor Mk-Auth)"
  fi
}

require_cmds() {
  local missing=()
  for c in mysql curl; do
    command -v "$c" >/dev/null 2>&1 || missing+=("$c")
  done
  [[ ${#missing[@]} -eq 0 ]] || fail "Comandos ausentes: ${missing[*]}"
}

detect_mkauth_db() {
  MC_DB_HOST="127.0.0.1"
  MC_DB_USER="root"
  MC_DB_PASS="vertrigo"
  MC_DB_NAME="mkradius"

  local cfg="/opt/mk-auth/include/configure.php"
  if [[ -f "$cfg" ]]; then
    local val
    val="$(grep -E "define\s*\(\s*['\"]MYSQL_HOST['\"]" "$cfg" 2>/dev/null | sed -n "s/.*['\"]\\([^'\"]*\\)['\"].*/\\1/p" | head -1 || true)"
    [[ -n "$val" ]] && MC_DB_HOST="$val"
    val="$(grep -E "define\s*\(\s*['\"]MYSQL_USER['\"]" "$cfg" 2>/dev/null | sed -n "s/.*['\"]\\([^'\"]*\\)['\"].*/\\1/p" | head -1 || true)"
    [[ -n "$val" ]] && MC_DB_USER="$val"
    val="$(grep -E "define\s*\(\s*['\"]MYSQL_PASS(W)?['\"]" "$cfg" 2>/dev/null | sed -n "s/.*['\"]\\([^'\"]*\\)['\"].*/\\1/p" | head -1 || true)"
    [[ -n "$val" ]] && MC_DB_PASS="$val"
    val="$(grep -E "define\s*\(\s*['\"]MYSQL_DB['\"]" "$cfg" 2>/dev/null | sed -n "s/.*['\"]\\([^'\"]*\\)['\"].*/\\1/p" | head -1 || true)"
    [[ -n "$val" ]] && MC_DB_NAME="$val"
    info "Credenciais lidas de ${cfg}"
  else
    warn "configure.php não encontrado — informe credenciais MySQL manualmente"
  fi
}

mysql_test() {
  if [[ -n "$MC_DB_PASS" ]]; then
    MYSQL_PWD="$MC_DB_PASS" mysql -h "$MC_DB_HOST" -u "$MC_DB_USER" "$MC_DB_NAME" -e "SELECT 1" >/dev/null 2>&1
  else
    mysql -h "$MC_DB_HOST" -u "$MC_DB_USER" "$MC_DB_NAME" -e "SELECT 1" >/dev/null 2>&1
  fi
}

mysql_exec() {
  local sql="$1"
  if [[ -n "$MC_DB_PASS" ]]; then
    MYSQL_PWD="$MC_DB_PASS" mysql -h "$MC_DB_HOST" -u "$MC_DB_USER" "$MC_DB_NAME" -e "$sql"
  else
    mysql -h "$MC_DB_HOST" -u "$MC_DB_USER" "$MC_DB_NAME" -e "$sql"
  fi
}

column_exists() {
  local table="$1"
  local column="$2"
  local cnt
  if [[ -n "$MC_DB_PASS" ]]; then
    cnt="$(MYSQL_PWD="$MC_DB_PASS" mysql -h "$MC_DB_HOST" -u "$MC_DB_USER" "$MC_DB_NAME" -N -B -e "
      SELECT COUNT(*) FROM information_schema.COLUMNS
      WHERE TABLE_SCHEMA='${MC_DB_NAME}' AND TABLE_NAME='${table}' AND COLUMN_NAME='${column}';
    " 2>/dev/null | tr -d '\r' || echo 0)"
  else
    cnt="$(mysql -h "$MC_DB_HOST" -u "$MC_DB_USER" "$MC_DB_NAME" -N -B -e "
      SELECT COUNT(*) FROM information_schema.COLUMNS
      WHERE TABLE_SCHEMA='${MC_DB_NAME}' AND TABLE_NAME='${table}' AND COLUMN_NAME='${column}';
    " 2>/dev/null | tr -d '\r' || echo 0)"
  fi
  [[ "${cnt:-0}" -gt 0 ]]
}

table_exists() {
  local table="$1"
  local cnt
  if [[ -n "$MC_DB_PASS" ]]; then
    cnt="$(MYSQL_PWD="$MC_DB_PASS" mysql -h "$MC_DB_HOST" -u "$MC_DB_USER" "$MC_DB_NAME" -N -B -e "
      SELECT COUNT(*) FROM information_schema.TABLES
      WHERE TABLE_SCHEMA='${MC_DB_NAME}' AND TABLE_NAME='${table}';
    " 2>/dev/null | tr -d '\r' || echo 0)"
  else
    cnt="$(mysql -h "$MC_DB_HOST" -u "$MC_DB_USER" "$MC_DB_NAME" -N -B -e "
      SELECT COUNT(*) FROM information_schema.TABLES
      WHERE TABLE_SCHEMA='${MC_DB_NAME}' AND TABLE_NAME='${table}';
    " 2>/dev/null | tr -d '\r' || echo 0)"
  fi
  [[ "${cnt:-0}" -gt 0 ]]
}

validate_date() {
  [[ "$1" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]
}

validate_date_br() {
  [[ "$1" =~ ^([0-3][0-9])/(0[1-9]|1[0-2])/([0-9]{4})$ ]] || return 1
  local d="${BASH_REMATCH[1]}" m="${BASH_REMATCH[2]}" y="${BASH_REMATCH[3]}"
  d="${d#0}"; [[ -z "$d" ]] && d=0
  m="${m#0}"; [[ -z "$m" ]] && m=0
  [[ "$d" -ge 1 && "$d" -le 31 && "$m" -ge 1 && "$m" -le 12 ]] || return 1
  if command -v date >/dev/null 2>&1; then
    date -d "${y}-${m}-${d}" >/dev/null 2>&1 || return 1
  fi
}

date_br_to_iso() {
  local br="$1"
  local d="${br:0:2}" m="${br:3:2}" y="${br:6:4}"
  echo "${y}-${m}-${d}"
}

date_iso_to_br() {
  local iso="$1"
  iso="$(echo "$iso" | tr -d '\r\n')"
  if validate_date_br "$iso"; then
    echo "$iso"
    return 0
  fi
  validate_date "$iso" || return 1
  echo "${iso:8:2}/${iso:5:2}/${iso:0:4}"
}

MC_CONF_FOUND=0
MC_DEFAULT_TOKEN=""
MC_DEFAULT_DATA_CORTE_BR=""

load_existing_conf() {
  MC_DEFAULT_TOKEN=""
  MC_DEFAULT_DATA_CORTE_BR="$(date '+%d/%m/%Y')"
  MC_CONF_FOUND=0

  if [[ ! -f "$MC_CONF" ]]; then
    return 0
  fi

  MC_CONF_FOUND=1
  info "Configuração anterior encontrada: ${MC_CONF}"

  # shellcheck disable=SC1090
  source "$MC_CONF"

  MC_DEFAULT_TOKEN="${MC_CONTA_TOKEN:-}"
  if [[ -n "${MC_DATA_CORTE:-}" ]]; then
    MC_DEFAULT_DATA_CORTE_BR="$(date_iso_to_br "$MC_DATA_CORTE" 2>/dev/null || echo "$MC_DEFAULT_DATA_CORTE_BR")"
  fi

  MC_DB_HOST="${MC_DB_HOST:-127.0.0.1}"
  MC_DB_USER="${MC_DB_USER:-root}"
  MC_DB_PASS="${MC_DB_PASS:-vertrigo}"
  MC_DB_NAME="${MC_DB_NAME:-mkradius}"
}

download_scripts() {
  mkdir -p "$MC_INSTALL_DIR"
  local base="${MC_BASE_URL}/painel/public/integracao/mkauth"
  if [[ -f "${MC_INSTALL_DIR}/sync.sh" ]]; then
    info "Atualizando scripts do repositório Mega Contas..."
  else
    info "Baixando scripts do repositório Mega Contas..."
  fi
  info "Origem: ${base}"
  curl -fsSL "${base}/megacontas-common.sh" -o "${MC_INSTALL_DIR}/megacontas-common.sh"
  curl -fsSL "${base}/sync.sh" -o "${MC_INSTALL_DIR}/sync.sh"
  curl -fsSL "${base}/install.sh" -o "${MC_INSTALL_DIR}/install.sh"
  chmod 755 "${MC_INSTALL_DIR}/megacontas-common.sh" "${MC_INSTALL_DIR}/sync.sh" "${MC_INSTALL_DIR}/install.sh"
  info "Scripts atualizados em ${MC_INSTALL_DIR}"
}

install_ddl() {
  info "Verificando tabelas sis_* do Mk-Auth..."
  table_exists "sis_lanc" || fail "Tabela sis_lanc não encontrada em ${MC_DB_NAME}"
  table_exists "sis_cliente" || fail "Tabela sis_cliente não encontrada em ${MC_DB_NAME}"

  if column_exists "sis_lanc" "enviado_mc"; then
    warn "Coluna sis_lanc.enviado_mc já existe — pulando ALTER"
  else
    info "Criando coluna sis_lanc.enviado_mc..."
    mysql_exec "ALTER TABLE sis_lanc ADD COLUMN enviado_mc CHAR(1) NOT NULL DEFAULT 'n';"
    info "Coluna enviado_mc criada"
  fi
}

wizard_intro_dialog() {
  if [[ "$MC_CONF_FOUND" -eq 1 ]]; then
    ui_msgbox "Mega Contas — Reinstalação / atualização" \
"Configuração anterior encontrada:

${MC_CONF}

• Scripts serão atualizados do repositório
• Token e data de corte virão pré-preenchidos
• Revise os valores e confirme para gravar

Painel: Cadastros → Integração Mk-Auth"
  else
    ui_msgbox "Mega Contas — Integração Mk-Auth" \
"Configure a ligação com o painel Mega Contas.

No painel: Cadastros → Integração Mk-Auth
Gere o Token da conta e copie na próxima tela."
  fi
}

wizard_tty() {
  tty_echo ""
  tty_echo "${GREEN}${BOLD}════════════════════════════════════════════════════════════${NC}"
  if [[ "$MC_CONF_FOUND" -eq 1 ]]; then
    tty_echo "${GREEN}${BOLD}   REINSTALAÇÃO — CONFIG ANTERIOR ENCONTRADA${NC}"
    tty_echo "${GREEN}${BOLD}════════════════════════════════════════════════════════════${NC}"
    tty_echo ""
    warn "Arquivo: ${MC_CONF}"
    tty_echo "Scripts já atualizados. Campos abaixo pré-preenchidos — Enter mantém o valor."
  else
    tty_echo "${GREEN}${BOLD}   CONFIGURAÇÃO MEGA CONTAS — INFORME OS DADOS ABAIXO${NC}"
    tty_echo "${GREEN}${BOLD}════════════════════════════════════════════════════════════${NC}"
    tty_echo ""
    tty_echo "Copie no painel Mega Contas: Cadastros → Integração Mk-Auth"
  fi
  tty_echo ""

  prompt MC_CONTA_TOKEN "Token da conta" "$MC_DEFAULT_TOKEN"
  [[ -n "$MC_CONTA_TOKEN" ]] || fail "Token da conta é obrigatório"
  MC_CONTA_TOKEN="$(echo "$MC_CONTA_TOKEN" | tr -d '[:space:]')"

  prompt MC_DATA_CORTE_BR "Data de corte (DD/MM/AAAA)" "$MC_DEFAULT_DATA_CORTE_BR"
  validate_date_br "$MC_DATA_CORTE_BR" || fail "Data de corte inválida (use DD/MM/AAAA)"
  MC_DATA_CORTE="$(date_br_to_iso "$MC_DATA_CORTE_BR")"

  wizard_finish_tty
}

wizard_dialog() {
  wizard_intro_dialog

  MC_CONTA_TOKEN="$(ui_inputbox "Passo 1/2 — Token da conta" \
"Cole o Token da conta (Ctrl+Shift+V ou botão direito).

Conta bancária que recebe os boletos do Mk-Auth:" "$MC_DEFAULT_TOKEN")" \
    || fail "Instalação cancelada"

  MC_CONTA_TOKEN="$(echo "$MC_CONTA_TOKEN" | tr -d '[:space:]')"
  [[ -n "$MC_CONTA_TOKEN" ]] || fail "Token da conta é obrigatório"

  MC_DATA_CORTE_BR="$(ui_inputbox "Passo 2/2 — Data de corte" \
"Formato DD/MM/AAAA.

Só serão enviados boletos pagos a partir desta data (inclusive):" "$MC_DEFAULT_DATA_CORTE_BR")" \
    || fail "Instalação cancelada"

  validate_date_br "$MC_DATA_CORTE_BR" || fail "Data de corte inválida (use DD/MM/AAAA)"
  MC_DATA_CORTE="$(date_br_to_iso "$MC_DATA_CORTE_BR")"

  wizard_finish_dialog
}

wizard_finish_common() {
  MC_API_URL="${MC_BASE_URL}/painel/api/public"

  if ! mysql_test; then
    warn "Conexão automática falhou — informe credenciais MySQL (banco mkradius / sis_*)"
    if [[ -n "$MC_UI" ]]; then
      MC_DB_HOST="$(ui_inputbox "MySQL — Host" "Host do banco Mk-Auth:" "$MC_DB_HOST")" \
        || fail "Instalação cancelada"
      MC_DB_USER="$(ui_inputbox "MySQL — Usuário" "Usuário MySQL:" "$MC_DB_USER")" \
        || fail "Instalação cancelada"
      MC_DB_PASS="$(ui_inputbox "MySQL — Senha" "Senha MySQL:" "$MC_DB_PASS")" \
        || fail "Instalação cancelada"
      MC_DB_NAME="$(ui_inputbox "MySQL — Banco" "Nome do banco (sis_lanc):" "$MC_DB_NAME")" \
        || fail "Instalação cancelada"
    else
      prompt MC_DB_HOST "Host MySQL" "$MC_DB_HOST"
      prompt MC_DB_USER "Usuário MySQL" "$MC_DB_USER"
      prompt_secret MC_DB_PASS "Senha MySQL" "vertrigo"
      prompt MC_DB_NAME "Banco de dados" "$MC_DB_NAME"
    fi
    mysql_test || fail "Não foi possível conectar ao MySQL"
  fi
}

wizard_finish_dialog() {
  wizard_finish_common
  local titulo="Confirmar instalação"
  [[ "$MC_CONF_FOUND" -eq 1 ]] && titulo="Confirmar atualização"
  ui_yesno "$titulo" \
"Resumo:

Token:      ${MC_CONTA_TOKEN}
Data corte: ${MC_DATA_CORTE_BR}
API:        ${MC_API_URL}
Banco:      ${MC_DB_USER}@${MC_DB_HOST}/${MC_DB_NAME}
Scripts:    ${MC_INSTALL_DIR} (atualizados)

Confirmar e salvar?" || fail "Instalação cancelada"
}

wizard_finish_tty() {
  wizard_finish_common
  echo ""
  info "Resumo:"
  echo "  Token:      ${MC_CONTA_TOKEN}"
  echo "  Data corte: ${MC_DATA_CORTE_BR}"
  echo "  API:        ${MC_API_URL}"
  echo "  Banco:      ${MC_DB_USER}@${MC_DB_HOST}/${MC_DB_NAME}"
  echo ""
  local confirm_val
  confirm_val="$(confirm "Confirmar instalação? [s/N]:")"
  confirm_lc="$(echo "$confirm_val" | tr '[:upper:]' '[:lower:]')"
  [[ "$confirm_lc" == "s" || "$confirm_lc" == "sim" ]] || fail "Instalação cancelada"
}

wizard() {
  if init_ui; then
    info "Abrindo janelas de configuração (${MC_UI})..."
    wizard_dialog
  else
    warn "whiptail/dialog não disponível — usando prompts no terminal"
    wizard_tty
  fi
}

mark_history() {
  info "Marcando títulos anteriores à data de corte (sis_lanc.enviado_mc = s)..."
  mysql_exec "
    UPDATE sis_lanc
    SET enviado_mc = 's'
    WHERE valorpag IS NOT NULL
      AND datapag IS NOT NULL
      AND DATE(datapag) < '${MC_DATA_CORTE}';
  "
  info "Títulos anteriores à data de corte marcados com enviado_mc = s"
}

save_conf() {
  umask 077
  cat > "$MC_CONF" <<EOF
# Mega Contas — integração Mk-Auth (gerado $(date '+%Y-%m-%d %H:%M:%S'))
MC_CONTA_TOKEN='${MC_CONTA_TOKEN}'
MC_API_URL='${MC_API_URL}'
MC_DATA_CORTE='${MC_DATA_CORTE}'
MC_DB_HOST='${MC_DB_HOST}'
MC_DB_USER='${MC_DB_USER}'
MC_DB_PASS='${MC_DB_PASS}'
MC_DB_NAME='${MC_DB_NAME}'
MC_BATCH_LIMIT='50'
MC_INSTALL_DIR='${MC_INSTALL_DIR}'
MC_CONF='${MC_CONF}'
MC_LOG='${MC_LOG}'
EOF
  chmod 600 "$MC_CONF"
  info "Config salva em ${MC_CONF}"
}

install_cron() {
  cat > "$MC_CRON_FILE" <<EOF
# Mega Contas — sync pagamentos sis_lanc → SaaS
*/5 * * * * root ${MC_INSTALL_DIR}/sync.sh >> ${MC_LOG} 2>&1
EOF
  chmod 644 "$MC_CRON_FILE"
  info "Cron instalado: ${MC_CRON_FILE} (a cada 5 minutos)"
}

run_initial_sync() {
  if [[ -n "$MC_UI" ]]; then
    if ui_yesno "Sincronização inicial" "Executar a primeira sincronização agora?"; then
      info "Executando sync inicial..."
      MC_CONF="$MC_CONF" "${MC_INSTALL_DIR}/sync.sh" || warn "Sync inicial retornou erro — ver ${MC_LOG}"
    fi
    return 0
  fi
  local run_now
  run_now="$(confirm "Executar sincronização inicial agora? [S/n]:")"
  run_lc="$(echo "$run_now" | tr '[:upper:]' '[:lower:]')"
  if [[ -z "$run_now" || "$run_lc" == "s" || "$run_lc" == "sim" ]]; then
    info "Executando sync inicial..."
    MC_CONF="$MC_CONF" "${MC_INSTALL_DIR}/sync.sh" || warn "Sync inicial retornou erro — ver ${MC_LOG}"
  fi
}

main() {
  require_root
  require_cmds
  detect_mkauth_db
  load_existing_conf
  download_scripts
  install_ddl
  wizard
  mark_history
  save_conf
  install_cron
  touch "$MC_LOG" 2>/dev/null || true
  chmod 644 "$MC_LOG" 2>/dev/null || true
  run_initial_sync
  echo ""
  info "Instalação concluída!"
  echo "  Config: ${MC_CONF}"
  echo "  Log:    ${MC_LOG}"
  echo "  Sync:   ${MC_INSTALL_DIR}/sync.sh"
  echo "  Local:  bash ${MC_INSTALL_DIR}/install.sh  (reinstalar/atualizar)"
}

main "$@"
