/**
 * Minimal validation primitives.
 *
 * `shared` stays dependency-free so the browser bundle and the Hono server can
 * both import it without agreeing on a validation library — worth the hand
 * written predicates, since this code sits on two trust boundaries (cloud saves
 * and peer messages).
 */

export type ValidationResult<T> = { ok: true; value: T } | { ok: false; errors: string[] };

export const isRecord = (value: unknown): value is Record<string, unknown> =>
  typeof value === "object" && value !== null && !Array.isArray(value);

export const isVec3 = (value: unknown): boolean =>
  isRecord(value) &&
  Number.isFinite(value["x"]) &&
  Number.isFinite(value["y"]) &&
  Number.isFinite(value["z"]);

export const isStringArray = (value: unknown): value is string[] =>
  Array.isArray(value) && value.every((entry) => typeof entry === "string");

/** Rejects NaN and Infinity, which JSON.parse will happily produce from input. */
export const isFiniteNumber = (value: unknown): value is number => Number.isFinite(value);

export const ok = <T>(value: T): ValidationResult<T> => ({ ok: true, value });
export const fail = <T>(...errors: string[]): ValidationResult<T> => ({ ok: false, errors });
