/**
 * Módulo TEF — detecta e inicia o agente CliSiTef no Windows.
 *
 * Fluxo:
 *  - checkRunning(): roda `tasklist` filtrando por CliSiTef.exe
 *  - ensureRunning(): se não estiver rodando, faz spawn do primeiro caminho válido
 *
 * Caminhos podem ser customizados em %APPDATA%\LuxosPDV\config.json:
 *   { "tefExeName": "CliSiTef.exe", "tefPaths": ["C:\\TEF_Dial\\CliSiTef.exe"] }
 */
const { exec, spawn } = require("child_process");
const fs = require("fs");
const path = require("path");
const os = require("os");

const DEFAULT_EXE = "CliSiTef.exe";
// Executáveis adicionais cuja PRESENÇA em execução também é considerada
// como "TEF rodando". O sistema NUNCA tenta iniciar estes — apenas verifica.
const DEFAULT_CHECK_ONLY_EXES = ["agenteCliSiTef.exe"];
const DEFAULT_PATHS = [
  "C:\\TEF_Dial\\CliSiTef.exe",
  "C:\\TEF\\CliSiTef.exe",
  "C:\\Program Files\\CliSiTef\\CliSiTef.exe",
  "C:\\Program Files (x86)\\CliSiTef\\CliSiTef.exe",
  "C:\\Arquivos de Programas\\CliSiTef\\CliSiTef.exe",
  "C:\\agenteCliSiTef-1.0.0.16.r1-Producao-Win64\\bin\\agenteCliSiTef.exe",
];

function getConfigPath() {
  const appData = process.env.APPDATA || path.join(os.homedir(), "AppData", "Roaming");
  return path.join(appData, "LuxosPDV", "config.json");
}

function ensureConfigFile() {
  try {
    const cfgPath = getConfigPath();
    const dir = path.dirname(cfgPath);
    if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
    if (!fs.existsSync(cfgPath)) {
      const template = {
        _comentario:
          "Configuração do PDV Luxos D'Cacau. 'tefPaths' = caminhos do CliSiTef.exe que podem ser iniciados automaticamente. 'tefCheckOnlyExes' = executáveis adicionais cuja simples presença em execução já satisfaz o TEF (nunca iniciados pelo PDV).",
        tefExeName: DEFAULT_EXE,
        tefCheckOnlyExes: DEFAULT_CHECK_ONLY_EXES,
        tefPaths: DEFAULT_PATHS,
      };
      fs.writeFileSync(cfgPath, JSON.stringify(template, null, 2), "utf-8");
    }
    return cfgPath;
  } catch (e) {
    return null;
  }
}

function loadConfig() {
  const cfgPath = ensureConfigFile();
  try {
    if (cfgPath && fs.existsSync(cfgPath)) {
      const raw = fs.readFileSync(cfgPath, "utf-8");
      const cfg = JSON.parse(raw);
      return {
        configPath: cfgPath,
        tefExeName: cfg.tefExeName || DEFAULT_EXE,
        tefCheckOnlyExes:
          Array.isArray(cfg.tefCheckOnlyExes) && cfg.tefCheckOnlyExes.length
            ? cfg.tefCheckOnlyExes
            : DEFAULT_CHECK_ONLY_EXES,
        tefPaths: Array.isArray(cfg.tefPaths) && cfg.tefPaths.length ? cfg.tefPaths : DEFAULT_PATHS,
      };
    }
  } catch (e) {
    // ignora — usa defaults
  }
  return {
    configPath: cfgPath,
    tefExeName: DEFAULT_EXE,
    tefCheckOnlyExes: DEFAULT_CHECK_ONLY_EXES,
    tefPaths: DEFAULT_PATHS,
  };
}

function tasklistHas(exeName) {
  return new Promise((resolve) => {
    exec(`tasklist /FI "IMAGENAME eq ${exeName}" /NH`, (err, stdout) => {
      if (err) return resolve(false);
      resolve(String(stdout).toLowerCase().includes(String(exeName).toLowerCase()));
    });
  });
}

async function checkRunning() {
  if (process.platform !== "win32") {
    return { running: false, platform: process.platform, supported: false };
  }
  const { tefExeName, tefCheckOnlyExes } = loadConfig();
  const exes = [tefExeName, ...(tefCheckOnlyExes || [])].filter(Boolean);
  for (const exe of exes) {
    const isUp = await tasklistHas(exe);
    if (isUp) return { running: true, exe, supported: true };
  }
  return { running: false, exe: tefExeName, supported: true, checked: exes };
}

function findExePath() {
  const { tefPaths, tefCheckOnlyExes } = loadConfig();
  const skip = new Set((tefCheckOnlyExes || []).map((x) => String(x).toLowerCase()));
  for (const p of tefPaths) {
    try {
      const base = path.basename(p).toLowerCase();
      // Nunca tente iniciar executáveis listados como "somente verificar"
      if (skip.has(base)) continue;
      if (fs.existsSync(p)) return p;
    } catch (e) {
      // continua
    }
  }
  return null;
}


async function ensureRunning() {
  if (process.platform !== "win32") {
    return { ok: false, started: false, reason: "Plataforma não suportada (apenas Windows)" };
  }
  const status = await checkRunning();
  if (status.running) {
    return { ok: true, started: false, reason: "Agente TEF já estava rodando" };
  }
  const exePath = findExePath();
  if (!exePath) {
    return {
      ok: false,
      started: false,
      reason:
        "CliSiTef.exe não encontrado nos caminhos padrão. Edite %APPDATA%\\LuxosPDV\\config.json para informar o caminho correto.",
      triedPaths: loadConfig().tefPaths,
    };
  }
  try {
    const child = spawn(exePath, [], {
      detached: true,
      stdio: "ignore",
      cwd: path.dirname(exePath),
      windowsHide: false,
    });
    child.unref();

    // Aguarda até 4s para confirmar que subiu
    for (let i = 0; i < 8; i++) {
      await new Promise((r) => setTimeout(r, 500));
      const s = await checkRunning();
      if (s.running) {
        return { ok: true, started: true, reason: `Agente TEF iniciado a partir de ${exePath}` };
      }
    }
    return {
      ok: false,
      started: false,
      reason: `Tentei iniciar ${exePath}, mas o processo não apareceu na lista. Verifique permissões.`,
    };
  } catch (e) {
    return { ok: false, started: false, reason: `Falha ao iniciar: ${e.message}` };
  }
}

module.exports = { checkRunning, ensureRunning, loadConfig, getConfigPath, ensureConfigFile };
