/**
 * Shared shape validation for bug-report payloads.
 * Used by the Pages Function (via functions/_lib re-export) and Node unit tests.
 */

export const BUG_REPORT_MAX_BYTES = 2 * 1024 * 1024;

export type BugReportVersions = {
  vault: string;
  corpus: string;
  app: string;
};

export type BugReportBody = {
  prompt: string;
  events: unknown[];
  problems: unknown[];
  metrics: unknown;
  versions: BugReportVersions;
  contact?: string;
};

export type BugReportValidation =
  | { ok: true; body: BugReportBody }
  | { ok: false; error: string };

function isPlainObject(v: unknown): v is Record<string, unknown> {
  return !!v && typeof v === 'object' && !Array.isArray(v);
}

/**
 * Validate a parsed JSON value as a bug-report POST body.
 * Does not check byte size — callers enforce BUG_REPORT_MAX_BYTES on the raw body.
 */
export function validateBugReportBody(raw: unknown): BugReportValidation {
  if (!isPlainObject(raw)) return { ok: false, error: 'body must be a JSON object' };

  if (typeof raw.prompt !== 'string') return { ok: false, error: 'prompt must be a string' };
  if (!Array.isArray(raw.events)) return { ok: false, error: 'events must be an array' };
  if (!Array.isArray(raw.problems)) return { ok: false, error: 'problems must be an array' };
  if (!('metrics' in raw)) return { ok: false, error: 'metrics is required' };

  if (!isPlainObject(raw.versions)) return { ok: false, error: 'versions must be an object' };
  const v = raw.versions;
  for (const k of ['vault', 'corpus', 'app'] as const) {
    if (typeof v[k] !== 'string') return { ok: false, error: `versions.${k} must be a string` };
  }

  if (raw.contact !== undefined && typeof raw.contact !== 'string') {
    return { ok: false, error: 'contact must be a string when provided' };
  }

  const body: BugReportBody = {
    prompt: raw.prompt,
    events: raw.events,
    problems: raw.problems,
    metrics: raw.metrics,
    versions: {
      vault: v.vault as string,
      corpus: v.corpus as string,
      app: v.app as string,
    },
  };
  if (typeof raw.contact === 'string') body.contact = raw.contact;
  return { ok: true, body };
}
