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

const ETS2_DOCS = path.join(
  process.env.USERPROFILE || os.homedir(),
  'Documents', 'Euro Truck Simulator 2'
);
const GAME_LOG = path.join(ETS2_DOCS, 'game.log');

let pending     = { speeding: 0, redLight: 0, collision: 0, wrongWay: 0, noLights: 0, other: 0, totalEur: 0 };
let lastSize    = -1;   // -1 = not yet initialized
let sessionMark = 0;    // byte offset of start of current game session

// Map ETS2 offence_type values to our categories
function classify(type) {
  const t = (type || '').toLowerCase().replace(/[\s-]/g, '_');
  if (/speed/.test(t))                                     return 'speeding';
  if (/red_light|red_l|traffic_light|signal/.test(t))      return 'redLight';
  if (/crash|collision|damage|avoid_vehicle|prohib/.test(t)) return 'collision';
  if (/wrong_way|wrong_dir|avoid_ped|pedestrian/.test(t))  return 'wrongWay';
  if (/no_head|headlight|no_light/.test(t))                return 'noLights';
  return 'other';
}

function parseChunk(text) {
  // ETS2 game.log formats seen in the wild:
  //   [gameplay] traffic_fine|type:speeding_camera|fine:800
  //   [gameplay] traffic_fine type=speeding_camera fine=800
  //   [gameplay] traffic_fine "offence_type" : "speeding" "amount" : 800
  //   Gameplay event: traffic_fine offence_type=speeding amount=800
  const patterns = [
    // pipe/colon form
    /traffic_fine[^\n]*?type[=:](\w+)[^\n]*?(?:fine|amount)[=:](-?\d+)/gi,
    // quoted JSON-ish form
    /traffic_fine[^\n]*?"offence_type"\s*:\s*"(\w+)"[^\n]*?"amount"\s*:\s*(-?\d+)/gi,
    // bare space-separated form
    /traffic_fine\s+(\w+)\s+(-?\d+)/gi,
  ];
  for (const re of patterns) {
    let m;
    re.lastIndex = 0;
    while ((m = re.exec(text)) !== null) {
      const cat    = classify(m[1]);
      const amount = Math.abs(parseInt(m[2], 10));   // game units = EUR cents in ETS2
      const eur    = amount / 100;
      pending[cat]++;
      pending.totalEur += eur;
      console.log(`[gamelog-fine] detectada: type=${m[1]} → ${cat}, ${amount} (${eur.toFixed(2)}€)`);
    }
  }
}

function poll() {
  try {
    if (!fs.existsSync(GAME_LOG)) return;
    const stat = fs.statSync(GAME_LOG);

    if (lastSize === -1) {
      // First call: mark current position; don't replay old lines
      lastSize    = stat.size;
      sessionMark = stat.size;
      return;
    }

    if (stat.size < lastSize) {
      // Log truncated → new game session
      console.log('[gamelog-fine] game.log reiniciado — nueva sesión ETS2');
      lastSize    = 0;
      sessionMark = 0;
      Object.keys(pending).forEach(k => (pending[k] = 0));
    }

    if (stat.size === lastSize) return;   // nothing new

    const toRead = Math.min(stat.size - lastSize, 128 * 1024); // max 128 KB per tick
    const buf = Buffer.alloc(toRead);
    const fd  = fs.openSync(GAME_LOG, 'r');
    fs.readSync(fd, buf, 0, toRead, lastSize);
    fs.closeSync(fd);
    lastSize = lastSize + toRead;

    parseChunk(buf.toString('utf8'));
  } catch (err) {
    // Non-fatal: game might not be running or log not flushed yet
  }
}

// Returns accumulated fines since last flush and resets counters.
// Call once per telemetry tick.
function flush() {
  const snapshot = { ...pending };
  Object.keys(pending).forEach(k => (pending[k] = 0));
  return snapshot;
}

module.exports = { poll, flush };
