// Local activity log for auto-exit runner events.
// Records why each auto-close or trailing-SL adjustment happened,
// including timestamp, thresholds, signal values, and executed order details.

const STORAGE_KEY = "auto-exit-activity-log:v1";
const MAX_ENTRIES = 500;

export type AutoExitKind =
  | "reversal_close"
  | "reversal_close_failed"
  | "trailing_sl_update"
  | "trailing_sl_failed";

export interface AutoExitLogEntry {
  id: string;
  ts: number;
  kind: AutoExitKind;
  symbol: string;
  positionId: string;
  positionSide: "LONG" | "SHORT";
  entryPrice: number;
  markPrice: number;
  // Reversal-specific
  signalId?: string;
  signalSide?: "LONG" | "SHORT";
  signalConfidence?: number;
  reverseMinConfidence?: number;
  // Trailing-specific
  peakPrice?: number;
  profitPct?: number;
  trailingActivatePct?: number;
  trailingDistancePct?: number;
  previousSl?: number;
  newSl?: number;
  // Execution result
  orderId?: string;
  orderStatus?: string;
  error?: string;
  note?: string;
}

type Listener = (entries: AutoExitLogEntry[]) => void;
const listeners = new Set<Listener>();

function safeRead(): AutoExitLogEntry[] {
  if (typeof window === "undefined") return [];
  try {
    const raw = window.localStorage.getItem(STORAGE_KEY);
    if (!raw) return [];
    const parsed = JSON.parse(raw);
    return Array.isArray(parsed) ? (parsed as AutoExitLogEntry[]) : [];
  } catch {
    return [];
  }
}

function safeWrite(entries: AutoExitLogEntry[]) {
  if (typeof window === "undefined") return;
  try {
    window.localStorage.setItem(STORAGE_KEY, JSON.stringify(entries));
  } catch {
    // ignore quota errors
  }
}

export function getAutoExitLog(): AutoExitLogEntry[] {
  return safeRead();
}

export function appendAutoExitLog(entry: Omit<AutoExitLogEntry, "id" | "ts"> & { ts?: number }) {
  const full: AutoExitLogEntry = {
    id:
      typeof crypto !== "undefined" && "randomUUID" in crypto
        ? crypto.randomUUID()
        : `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`,
    ts: entry.ts ?? Date.now(),
    ...entry,
  };
  const next = [full, ...safeRead()].slice(0, MAX_ENTRIES);
  safeWrite(next);
  listeners.forEach((l) => {
    try {
      l(next);
    } catch {
      /* noop */
    }
  });
  return full;
}

export function clearAutoExitLog() {
  safeWrite([]);
  listeners.forEach((l) => l([]));
}

export function subscribeAutoExitLog(listener: Listener) {
  listeners.add(listener);
  // Emit initial snapshot
  listener(safeRead());
  return () => {
    listeners.delete(listener);
  };
}

export function autoExitLogToCsv(entries: AutoExitLogEntry[]): string {
  const headers = [
    "timestamp",
    "kind",
    "symbol",
    "position_id",
    "position_side",
    "entry_price",
    "mark_price",
    "signal_id",
    "signal_side",
    "signal_confidence",
    "reverse_min_confidence",
    "peak_price",
    "profit_pct",
    "trailing_activate_pct",
    "trailing_distance_pct",
    "previous_sl",
    "new_sl",
    "order_id",
    "order_status",
    "error",
    "note",
  ];
  const rows = entries.map((e) => [
    new Date(e.ts).toISOString(),
    e.kind,
    e.symbol,
    e.positionId,
    e.positionSide,
    e.entryPrice,
    e.markPrice,
    e.signalId ?? "",
    e.signalSide ?? "",
    e.signalConfidence ?? "",
    e.reverseMinConfidence ?? "",
    e.peakPrice ?? "",
    e.profitPct ?? "",
    e.trailingActivatePct ?? "",
    e.trailingDistancePct ?? "",
    e.previousSl ?? "",
    e.newSl ?? "",
    e.orderId ?? "",
    e.orderStatus ?? "",
    e.error ? `"${String(e.error).replace(/"/g, '""')}"` : "",
    e.note ? `"${String(e.note).replace(/"/g, '""')}"` : "",
  ]);
  return [headers.join(","), ...rows.map((r) => r.join(","))].join("\n");
}
