import { Type, TSchema, TUnion, TNull } from "@sinclair/typebox";

function Nullable<T extends TSchema>(schema: T): TUnion<[T, TNull]> {
  return { ...schema, nullable: true } as any;
}

export const Word = Type.Object({
  id: Type.String({ format: "uuid" }),
  image: Type.String(),
  ocr_confidence: Type.Number({ minimum: 0, maximum: 1 }),
  ocr_transcript: Type.String(),
});

export const Game = Type.Object({
  id: Type.Readonly(Type.String({ format: "uuid" })),
  began_at: Nullable(Type.String({ format: "date-time" })),
  ended_at: Nullable(Type.String({ format: "date-time" })),
});

export const Clue = Type.Object({
  id: Type.Readonly(Type.String({ format: "uuid" })),
  game_id: Type.Readonly(Type.String({ format: "uuid" })),
  word_id: Type.Readonly(Type.String({ format: "uuid" })),
  began_at: Nullable(Type.String({ format: "date-time" })),
  ended_at: Nullable(Type.String({ format: "date-time" })),
});

export const Shot = Type.Object({
  id: Type.Readonly(Type.String({ format: "uuid" })),
  game_id: Type.Readonly(Type.String({ format: "uuid" })),
  clue_id: Nullable(Type.String({ format: "uuid" })),
  began_at: Type.String({ format: "date-time" }),
  ended_at: Type.String({ format: "date-time" }),
  typed: Type.String(),
  final: Type.String(),
});

export const GameUpdate = Type.Omit(Game, ["id"]);
export const ClueCreate = Type.Pick(Clue, ["word_id"]);
export const ClueUpdate = Type.Pick(Clue, ["began_at", "ended_at"]);
export const ShotCreate = Type.Omit(Shot, ["id", "game_id"]);