import { Type, type Static } from "@sinclair/typebox";

import { GenerationErrorCategorySchema } from "./api.js";
import { ProjectIdSchema, ProjectRatioSchema } from "./projects.js";

const uuidPattern = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$";
const isoTimestampPattern = "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{3}Z$";

export const GenerationTaskStatusSchema = Type.Union([
  Type.Literal("queued"),
  Type.Literal("running"),
  Type.Literal("succeeded"),
  Type.Literal("failed"),
  Type.Literal("rejected"),
], { $id: "GenerationTaskStatus" });

export const GenerationTaskResponseSchema = Type.Object({
  confirmed_credit_cost: Type.Integer({ minimum: 1 }),
  created_at: Type.String({ pattern: isoTimestampPattern }),
  error_category: Type.Union([Type.Ref(GenerationErrorCategorySchema), Type.Null()]),
  generation_id: Type.String({ pattern: uuidPattern }),
  model_config_version: Type.Integer({ minimum: 1 }),
  model_id: Type.String({ maxLength: 160, minLength: 1 }),
  project_id: Type.Ref(ProjectIdSchema),
  prompt: Type.String({ maxLength: 4_000, minLength: 1 }),
  ratio: Type.Ref(ProjectRatioSchema),
  reference_asset_ids: Type.Array(Type.String({ pattern: uuidPattern }), { maxItems: 16 }),
  reference_count: Type.Integer({ minimum: 0 }),
  reserved_credits: Type.Integer({ minimum: 0 }),
  status: Type.Ref(GenerationTaskStatusSchema),
  updated_at: Type.String({ pattern: isoTimestampPattern }),
}, { additionalProperties: false, $id: "GenerationTaskResponse" });

export const GenerationCreateResponseSchema = Type.Object({
  created: Type.Boolean(),
  task: Type.Ref(GenerationTaskResponseSchema),
}, { additionalProperties: false, $id: "GenerationCreateResponse" });

export const GenerationParamsSchema = Type.Object({
  generationId: Type.String({ pattern: uuidPattern }),
}, { additionalProperties: false, $id: "GenerationParams" });

export const GenerationCreateHeadersSchema = Type.Object({
  "idempotency-key": Type.String({ maxLength: 200, minLength: 32, pattern: "^[A-Za-z0-9_-]+$" }),
  "x-csrf-token": Type.String({ maxLength: 64, minLength: 43, pattern: "^[A-Za-z0-9_-]+$" }),
}, { additionalProperties: true, $id: "GenerationCreateHeaders" });

export const GenerationMultipartBodySchema = Type.Object({
  client_submission_id: Type.String({ pattern: uuidPattern }),
  confirmed_credit_cost: Type.String({ pattern: "^[1-9][0-9]*$" }),
  creation_mode: Type.Union([Type.Literal("new_project"), Type.Literal("existing_project")]),
  existing_reference_asset_ids: Type.Optional(Type.String({ maxLength: 12_000 })),
  model_config_version: Type.String({ pattern: "^[1-9][0-9]*$" }),
  model_id: Type.String({ maxLength: 160, minLength: 1 }),
  project_id: Type.Optional(Type.String({ pattern: uuidPattern })),
  prompt: Type.String({ maxLength: 4_000, minLength: 1 }),
  ratio: Type.Ref(ProjectRatioSchema),
  reference_files: Type.Optional(Type.Array(Type.String({ format: "binary" }), { maxItems: 16 })),
  reference_manifest: Type.Optional(Type.String({ maxLength: 16_384 })),
}, { additionalProperties: false, $id: "GenerationMultipartBody" });

export type GenerationCreateHeaders = Static<typeof GenerationCreateHeadersSchema>;
export type GenerationParams = Static<typeof GenerationParamsSchema>;
export type GenerationTaskResponse = Static<typeof GenerationTaskResponseSchema>;
