// shared/logEvent.js — canonical event shape for UI/download/replay/analyze.
// One source of truth. All four consumers import this.
//
// Canonical event:
//   {
//     id, ts, type, message,
//     encounterId, encounterName, encounterPath,
//     payload,        // forward patch (null for no-op)
//     undo_payload,   // { encounterPath, updates, redo } or null
//     undone,         // bool
//     snapshot         // { round, currentTurnParticipantId, turnOrderIds, activeIds } or null
//   }
//
// Old logs (pre-refactor): { timestamp, message, encounterName, undo }.
// normalizeEvent fills defaults + lifts legacy undo into undo_payload.

const DEFAULTS = {
  ts: 0,
  type: 'unknown',
  message: '',
  encounterId: null,
  encounterName: null,
  encounterPath: null,
  payload: null,
  undo_payload: null,
  undone: false,
  snapshot: null,
};

// Canonical lean event shape:
//   {
//     id, ts, type, message,
//     encounterId, encounterName, encounterPath,
//     participantId, participantName,   // nullable (pause/nextTurn have none)
//     delta,                            // type-specific scalars (nullable)
//     undo,                             // id-based inverse (nullable)
//     undone,                           // bool
//     snapshot                          // {round, currentTurnParticipantId, turnOrderIds, activeIds}
//   }
// Legacy logs (pre-refactor, no type): display message only. Not undoable.
// Old bloated logs (payload/undo_payload): normalized to lean — payload dropped,
// undo_payload lifted to undo. Both display fine; undo expands via expandUndo.
function normalizeEvent(raw) {
  if (!raw) return null;
  if (!raw.type || raw.type === 'unknown') return null;
  const id = raw.id || (raw.path ? raw.path.split('/').pop() : null);
  return {
    id,
    ts: raw.ts || raw.timestamp || 0,
    type: raw.type,
    message: raw.message || '',
    encounterId: raw.encounterId || null,
    encounterName: raw.encounterName || null,
    encounterPath: raw.encounterPath || null,
    participantId: raw.participantId || null,
    participantName: raw.participantName || null,
    delta: raw.delta || null,
    undo: raw.undo || raw.undo_payload || null,
    undone: !!raw.undone,
    snapshot: raw.snapshot || null,
  };
}

// Serialize array of raw log entries (DB rows) → canonical JSON string.
// Legacy logs (no type) dropped by normalizeEvent. Sorted ascending by ts.
function serializeEvents(rawLogs) {
  return JSON.stringify(
    (rawLogs || [])
      .map(normalizeEvent)
      .filter(Boolean)
      .sort((a, b) => a.ts - b.ts),
    null, 2
  );
}

module.exports = { normalizeEvent, serializeEvents, DEFAULTS };
