import { purchaseInputSchema, type PurchaseInput } from "@/features/purchases/schemas/purchase.schema";

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

export type PurchaseRequestPayload = {
  payload: PurchaseInput;
  costProofFiles: Array<{ index: number; file: File }>;
};

const COST_PROOF_PREFIX = "cost_proof_";

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

function normalizeFormIndex(rawIndex: string) {
  const index = Number(rawIndex);
  if (!Number.isInteger(index) || index < 0) return null;
  return index;
}

export async function parsePurchaseRequestPayload(
  request: Request
): Promise<PurchaseRequestPayload> {
  const contentType = request.headers.get("content-type") ?? "";
  if (contentType.includes("multipart/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 = purchaseInputSchema.safeParse(payloadJson);
    if (!parsedPayload.success) {
      throw createValidationError("Validasi gagal", parsedPayload.error.flatten().fieldErrors);
    }

    const costProofFiles: Array<{ index: number; file: File }> = [];
    for (const [key, value] of formData.entries()) {
      if (!key.startsWith(COST_PROOF_PREFIX)) continue;
      if (!(value instanceof File)) continue;
      const index = normalizeFormIndex(key.slice(COST_PROOF_PREFIX.length));
      if (index === null) continue;
      costProofFiles.push({ index, file: value });
    }

    return { payload: parsedPayload.data, costProofFiles };
  }

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

  const parsedPayload = purchaseInputSchema.safeParse(payloadJson);
  if (!parsedPayload.success) {
    throw createValidationError("Validasi gagal", parsedPayload.error.flatten().fieldErrors);
  }
  return { payload: parsedPayload.data, costProofFiles: [] };
}

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