/**
 * "Was that round fair?" — the phone half of the perceived-fairness pilot metric (spec §11).
 * Browser-only and fire-and-forget: feedback must never get in the way of the game.
 */

/** Largest request body /api/feedback reads. */
export const FEEDBACK_MAX_BYTES = 1024;

export interface FairnessFeedback {
  roomId: string;
  roundId: string;
  fair: boolean;
}

/** Rounds this phone already answered or dismissed, so the prompt shows once per round (also across reloads). */
const HANDLED_KEY = 'pintrush:fairness';
const MAX_REMEMBERED = 30;
const handledInTab = new Set<string>();

function storedHandled(): string[] {
  try {
    const list = JSON.parse(window.localStorage.getItem(HANDLED_KEY) ?? '[]') as unknown;
    return Array.isArray(list) ? list.filter((x): x is string => typeof x === 'string') : [];
  } catch {
    return [];
  }
}

export function fairnessHandled(roundId: string): boolean {
  return handledInTab.has(roundId) || storedHandled().includes(roundId);
}

export function markFairnessHandled(roundId: string): void {
  handledInTab.add(roundId);
  try {
    const next = [roundId, ...storedHandled().filter((id) => id !== roundId)].slice(0, MAX_REMEMBERED);
    window.localStorage.setItem(HANDLED_KEY, JSON.stringify(next));
  } catch {
    // storage unavailable: the in-tab set still keeps it to once per round
  }
}

/** Posts one answer; failures are ignored (a lost vote is better than an error on a game screen). */
export function sendFairness(feedback: FairnessFeedback): void {
  try {
    void fetch('/api/feedback', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(feedback),
      keepalive: true,
      cache: 'no-store',
    }).catch(() => undefined);
  } catch {
    // fetch unavailable
  }
}
