"use client";

/**
 * "Did I just do this myself?"
 *
 * Realtime mutations fan out to *every* active member including the one who
 * made them, and the payloads carry no actor — `task:updated` looks identical
 * whether you moved the card or a colleague did. Without this, marking your own
 * task done pops a notification telling you your task was marked done.
 *
 * The alternative (an `actorUserId` on every event payload) is a wire-format
 * change across four event families for a purely local concern, so instead the
 * one place every mutation already funnels through — lib/api.ts — records what
 * it just changed, and the notification router ignores echoes of it.
 *
 * The window is short on purpose: it only has to cover the round trip from
 * request to fanout. Anything later is genuinely someone else.
 */

const ECHO_WINDOW_MS = 6_000;

type EchoKind = "task" | "event" | "call" | "message";

const recent = new Map<string, number>();

function key(kind: EchoKind, id: number | string): string {
  return `${kind}:${id}`;
}

/** Called right after a successful mutation, with the row the server returned. */
export function markSelfAction(kind: EchoKind, id: number | string | null | undefined): void {
  if (id == null) return;
  const now = Date.now();
  recent.set(key(kind, id), now);
  // Opportunistic sweep — this map would otherwise grow for the life of the
  // tab, and there is no natural moment to clear it.
  if (recent.size > 64) {
    for (const [entry, at] of recent) {
      if (now - at > ECHO_WINDOW_MS) recent.delete(entry);
    }
  }
}

export function wasSelfAction(kind: EchoKind, id: number | string): boolean {
  const at = recent.get(key(kind, id));
  if (at == null) return false;
  if (Date.now() - at > ECHO_WINDOW_MS) {
    recent.delete(key(kind, id));
    return false;
  }
  return true;
}
