import type { ObjectSchema, ParseResult, SchemaDescriptor } from "./index.ts";

export class ValidationError<T = Record<string, unknown>> extends Error {
  constructor(public readonly result: ParseResult<T>) {
    super("Validation failed");
    this.name = "ValidationError";
  }
}

export function parseOrThrow<T extends object>(schema: ObjectSchema<T>, input: unknown): T {
  const result = schema.parse(input);
  if (!result.ok) throw new ValidationError(result);
  return result.value;
}

export function validationResponse(
  result: ParseResult,
  options: { successStatus?: number; failureStatus?: number } = {},
): Response {
  return Response.json(
    result.ok
      ? { ok: true, value: result.value }
      : { ok: false, errors: result.errors, value: result.value },
    {
      status: result.ok ? (options.successStatus ?? 200) : (options.failureStatus ?? 422),
      headers: { "cache-control": "no-store" },
    },
  );
}

export function firstValidationError(errors: Record<string, string>): string | null {
  return Object.values(errors).find(Boolean) ?? null;
}

export function validationSummary(
  errors: Record<string, string>,
): Array<{ field: string; message: string }> {
  return Object.entries(errors)
    .filter(([, message]) => Boolean(message))
    .map(([field, message]) => ({ field, message }));
}

export function schemaFieldNames(schema: ObjectSchema | SchemaDescriptor): string[] {
  const descriptor = "describe" in schema ? schema.describe() : schema;
  return Object.keys(descriptor.fields);
}
