interface UploadResponsePayload {
  code?: unknown;
  error?: unknown;
  errorCode?: unknown;
  message?: unknown;
  msg?: unknown;
}

interface ResolveUploadResponseOptions {
  fallbackMessage: string;
  responseText: string;
  status: number;
  statusText?: string;
}

interface UploadResponseResult {
  message?: string;
  success: boolean;
}

function resolveMessage(
  payload: undefined | UploadResponsePayload,
  statusText: string | undefined,
  fallbackMessage: string,
) {
  const message =
    payload?.message ?? payload?.error ?? payload?.msg ?? statusText;
  return typeof message === 'string' && message.trim()
    ? message.trim()
    : fallbackMessage;
}

export function resolveDocumentUploadResponse({
  fallbackMessage,
  responseText,
  status,
  statusText,
}: ResolveUploadResponseOptions): UploadResponseResult {
  const isHttpSuccess = status >= 200 && status < 300;
  const normalizedBody = responseText.replace(/^\uFEFF/, '').trim();
  let payload: undefined | UploadResponsePayload;

  if (normalizedBody) {
    try {
      payload = JSON.parse(normalizedBody) as UploadResponsePayload;
    } catch {
      return {
        message: fallbackMessage,
        success: false,
      };
    }
  }

  if (!isHttpSuccess) {
    return {
      message: resolveMessage(payload, statusText, fallbackMessage),
      success: false,
    };
  }

  if (status === 204) {
    return { success: true };
  }

  const rawErrorCode = payload?.errorCode ?? payload?.code;
  const errorCode = Number(rawErrorCode);
  if (!Number.isFinite(errorCode) || errorCode !== 0) {
    return {
      message: resolveMessage(payload, statusText, fallbackMessage),
      success: false,
    };
  }

  return { success: true };
}
