import {
  jitSaleCloseSchema,
  jitSaleCreateSchema,
  type JitSaleCloseInput,
  type JitSaleCreateInput
} from "@/features/sales-jit/schemas/jit-sale.schema";

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

type UploadFile = File;

export type JitSaleCreateRequestPayload = {
  payload: JitSaleCreateInput;
  shippingReceiptFile: UploadFile | null;
};

export type JitSaleCloseRequestPayload = {
  payload: JitSaleCloseInput;
  shippingReceiptFile: UploadFile | null;
};

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

async function parseJsonPayload(request: Request): Promise<unknown> {
  try {
    return await request.json();
  } catch {
    throw createValidationError("Payload JSON tidak valid", {
      payload: ["Format JSON payload tidak valid"]
    });
  }
}

async function parseMultipartPayload(request: Request) {
  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 receiptValue = formData.get("shipping_receipt");
  const shippingReceiptFile = receiptValue instanceof File ? receiptValue : null;

  return { payloadJson, shippingReceiptFile };
}

export async function parseJitSaleCreateRequest(
  request: Request
): Promise<JitSaleCreateRequestPayload> {
  const contentType = request.headers.get("content-type") ?? "";

  if (contentType.includes("multipart/form-data")) {
    const { payloadJson, shippingReceiptFile } = await parseMultipartPayload(request);
    const parsed = jitSaleCreateSchema.safeParse(payloadJson);
    if (!parsed.success) {
      throw createValidationError("Validasi gagal", parsed.error.flatten().fieldErrors);
    }
    return { payload: parsed.data, shippingReceiptFile };
  }

  const parsed = jitSaleCreateSchema.safeParse(await parseJsonPayload(request));
  if (!parsed.success) {
    throw createValidationError("Validasi gagal", parsed.error.flatten().fieldErrors);
  }
  return { payload: parsed.data, shippingReceiptFile: null };
}

export async function parseJitSaleCloseRequest(
  request: Request
): Promise<JitSaleCloseRequestPayload> {
  const contentType = request.headers.get("content-type") ?? "";

  if (contentType.includes("multipart/form-data")) {
    const { payloadJson, shippingReceiptFile } = await parseMultipartPayload(request);
    const parsed = jitSaleCloseSchema.safeParse(payloadJson);
    if (!parsed.success) {
      throw createValidationError("Validasi gagal", parsed.error.flatten().fieldErrors);
    }
    return { payload: parsed.data, shippingReceiptFile };
  }

  const parsed = jitSaleCloseSchema.safeParse(await parseJsonPayload(request));
  if (!parsed.success) {
    throw createValidationError("Validasi gagal", parsed.error.flatten().fieldErrors);
  }
  return { payload: parsed.data, shippingReceiptFile: null };
}

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