import {
  washingInputSchema,
  type WashingInput
} from "@/features/washing/schemas/washing.schema";

type WashingPayloadParseError = {
  errors: Record<string, string[]>;
};

function createValidationError(message: string, errors: Record<string, string[]>) {
  const error = new Error(message) as Error & WashingPayloadParseError;
  error.errors = errors;
  return error;
}

export type WashingRequestPayload = {
  payload: WashingInput;
  receiptFile: File | null;
};

export async function parseWashingRequestPayload(
  request: Request
): Promise<WashingRequestPayload> {
  const contentType = request.headers.get("content-type") ?? "";
  if (!contentType.includes("multipart/form-data")) {
    throw createValidationError("Payload form-data tidak valid", {
      payload: ["Request washing wajib dikirim sebagai form-data"]
    });
  }

  const formData = await request.formData();
  const payloadRaw = formData.get("payload");
  if (typeof payloadRaw !== "string") {
    throw createValidationError("Payload JSON tidak valid", {
      payload: ["Payload JSON wajib dikirim di field payload"]
    });
  }

  let payloadJson: unknown;
  try {
    payloadJson = JSON.parse(payloadRaw);
  } catch {
    throw createValidationError("Payload JSON tidak valid", {
      payload: ["Format JSON payload tidak valid"]
    });
  }

  const parsedPayload = washingInputSchema.safeParse(payloadJson);
  if (!parsedPayload.success) {
    throw createValidationError("Validasi gagal", parsedPayload.error.flatten().fieldErrors);
  }

  const receiptCandidate = formData.get("receipt_file");
  return {
    payload: parsedPayload.data,
    receiptFile: receiptCandidate instanceof File && receiptCandidate.size > 0 ? receiptCandidate : null
  };
}

export function isWashingPayloadValidationError(
  error: unknown
): error is Error & WashingPayloadParseError {
  return (
    error instanceof Error &&
    "errors" in error &&
    typeof (error as Error & WashingPayloadParseError).errors === "object"
  );
}
