const fs   = require("fs");
const path = require("path");
const os   = require("os");

const MOD_NAME    = "eurotrans_override.scs";
const DOCS_ETS2   = path.join(
  process.env.USERPROFILE || os.homedir(),
  "Documents", "Euro Truck Simulator 2"
);
const PROFILES_PATH = path.join(DOCS_ETS2, "profiles");

// Detecta si un buffer es texto SiiNunit plano (no binario ni cifrado).
// Los archivos cifrados/binarios empiezan con "Scsc", "ScsB" o bytes altos.
function isPlainSii(buf) {
  if (buf.length < 8) return false;
  const sig = buf.slice(0, 4).toString("latin1");
  if (sig === "Scsc" || sig === "ScsB" || sig === "BSII") return false;
  return buf.slice(0, 8).toString("latin1").startsWith("SiiNunit");
}

// Inyecta el mod en la lista active_mods de un texto SiiNunit.
// Soporta dos formatos que usa ETS2 según la versión:
//   Formato bloque: active_mods : N { active_mods[0]: "file.scs" }
//   Formato plano:  active_mods: N\n active_mods[0]: "file.scs"
function injectMod(content) {
  if (content.includes(MOD_NAME)) return null; // ya activo

  // ── Formato bloque ────────────────────────────────────────────────────
  const blockRe = /active_mods\s*:\s*(\d+)\s*\{([^}]*)\}/s;
  const blockM  = content.match(blockRe);
  if (blockM) {
    const n    = parseInt(blockM[1], 10);
    const body = blockM[2];
    return content.replace(
      blockRe,
      `active_mods : ${n + 1} {${body} active_mods[${n}]: "${MOD_NAME}"\n}`
    );
  }

  // ── Formato plano ─────────────────────────────────────────────────────
  // Busca "active_mods: N" y el último "active_mods[N-1]:" para insertar después
  const flatCountRe = /^([ \t]*active_mods\s*:\s*)(\d+)([ \t]*)$/m;
  const flatCountM  = content.match(flatCountRe);
  if (flatCountM) {
    const n      = parseInt(flatCountM[2], 10);
    const indent = flatCountM[1].match(/^([ \t]*)/)[1];
    // Incrementar el contador
    let updated = content.replace(
      flatCountRe,
      `${flatCountM[1]}${n + 1}${flatCountM[3]}`
    );
    // Añadir la nueva entrada después del último active_mods[N-1]
    const lastEntry = new RegExp(`(active_mods\\[${n - 1}\\][^\\n]*\\n)`);
    if (lastEntry.test(updated)) {
      updated = updated.replace(
        lastEntry,
        `$1${indent}active_mods[${n}]: "${MOD_NAME}"\n`
      );
    } else {
      // No hay entradas previas, añadir justo después del contador
      updated = updated.replace(
        flatCountRe,
        `${flatCountM[1]}${n + 1}${flatCountM[3]}\n${indent}active_mods[0]: "${MOD_NAME}"`
      );
    }
    return updated;
  }

  // ── Sin lista previa: insertar bloque nuevo ───────────────────────────
  // Añadir antes del cierre del primer bloque de datos
  const insertPoint = content.lastIndexOf("}");
  if (insertPoint === -1) return null;
  return (
    content.slice(0, insertPoint) +
    ` active_mods : 1 {\n  active_mods[0]: "${MOD_NAME}"\n }\n` +
    content.slice(insertPoint)
  );
}

// Intenta escribir el mod en un archivo SII de texto del perfil.
function tryInjectFile(filePath) {
  try {
    if (!fs.existsSync(filePath)) return false;
    const buf = fs.readFileSync(filePath);
    if (!isPlainSii(buf)) return false;           // binario → no tocar

    const content = buf.toString("utf8");
    const updated = injectMod(content);
    if (!updated) return false;                   // ya estaba o sin cambios

    fs.writeFileSync(filePath, updated, "utf8");
    return true;
  } catch (_) {
    return false;
  }
}

// Comprueba si el mod está ya listado en algún archivo de perfil legible.
// NO modifica nada — en ETS2 1.47+ los archivos son binarios/cifrados y
// cualquier escritura los corrompe. El usuario activa el mod manualmente
// una sola vez desde el Mod Manager del juego; ETS2 lo recuerda.
function ensureModInProfiles() {
  try {
    if (!fs.existsSync(PROFILES_PATH)) return;
    const entries = fs.readdirSync(PROFILES_PATH, { withFileTypes: true });
    for (const entry of entries) {
      if (!entry.isDirectory()) continue;
      const base = path.join(PROFILES_PATH, entry.name);
      for (const fn of ["game.sii", "profile.sii"]) {
        const fp = path.join(base, fn);
        try {
          if (!fs.existsSync(fp)) continue;
          const buf = fs.readFileSync(fp);
          if (isPlainSii(buf) && buf.toString("utf8").includes(MOD_NAME))
            console.log(`[mod-guard] mod activo confirmado en ${fn} → perfil ${entry.name}`);
        } catch (_) {}
      }
    }
  } catch (_) {}
}

function checkAll() {
  ensureModInProfiles();
}

let watchers = [];

function startGuard() {
  checkAll();

  if (!fs.existsSync(PROFILES_PATH)) {
    console.log("[mod-guard] carpeta de perfiles no encontrada, reintentando en 10s...");
    setTimeout(checkAll, 10000);
    return;
  }

  try {
    const w = fs.watch(PROFILES_PATH, { persistent: false, recursive: true },
      (_, filename) => {
        if (filename && (filename.endsWith("game.sii") || filename.endsWith("profile.sii")))
          setTimeout(checkAll, 1200);
      }
    );
    watchers.push(w);
    console.log("[mod-guard] activo — vigilando perfiles de ETS2");
  } catch (err) {
    console.warn("[mod-guard] watch no disponible:", err.message);
  }
}

function stopGuard() {
  watchers.forEach(w => { try { w.close(); } catch (_) {} });
  watchers = [];
}

module.exports = { startGuard, stopGuard };
