import { config } from 'config/general';
import { getContent } from './helper';

/**
 * Get validation info from error code
 */
export const getValidationInfo = (validationError: string, byDefault?: string, replace?: any): string | {} => {
  let error;
  const validationPath = config.validationPath || config.pathToValidationInCMS;

  if (byDefault && !validationPath) {
    error = byDefault;
  } else {
    error = {
      error: `${validationPath}.${validationError}`,
      default: byDefault,
    };
  }

  if (replace) {
    return {
      replace,
      error: error?.error || error,
      default: byDefault,
    };
  }

  return error;
};

/**
 * Get error code from error object data
 * @param {object} data - error object
 */
export const extractErrorCode = (data): string => {
  if (data) {
    // extract code
    let error =
      data[config.errorFirebaseCodeLabel] ||
      data[config.errorCodeLabel] ||
      // fallback key for code
      data.code;

    if (!error && typeof data === 'string') error = data;

    return error;
  }
  return '';
};

/**
 * Get error message from error object data
 * @param {object} data - error object
 */
const extractErrorMessage = (data): string => {
  if (data) {
    // extract message or code
    let error =
      data[config.errorMessageLabel] ||
      // fallback keys for message
      data.message ||
      data.error_message;

    if (!error && typeof data === 'string') error = data;

    return error;
  }
  return '';
};

/**
 * @param {object} data - Api data
 */
export const extractErrorData = (data): any => {
  if (data) {
    // extract list
    let errorData = data[config.errorListLabel] || data[config.defaultErrorsPath] || data.errors || data;

    // if array of errors, return the list
    if (Array.isArray(errorData)) {
      return errorData;
    }
    // extract firebase error
    errorData = errorData[config.firebaseErrorLabel] || errorData;
    return errorData;
  }
  return null;
};

/**
 * Get error title from errorData
 * @param {object} errorData - Error data
 */
export const getErrorTitle = (errorData, lg) => {
  if (errorData?.translations?.subject) {
    return errorData.translations?.subject[lg] || '';
  }
  return '';
};

/**
 * Get error message from errorData, app content, language and a fallback
 * @param {object} errorData - Error data
 */
export const getErrorMessage = (errorData, contentObj, lg, defaultError) => {
  // 1. translation error message
  if (errorData?.translations?.body && errorData.translations?.body[lg]) {
    return errorData.translations?.body[lg];
  }

  // 2. Extract code from errorData
  const code = extractErrorCode(errorData);

  let message;

  if (code) {
    // try to get error in the content
    if (config.errorsPathCode) {
      // Used only when you want to recover the error, no '.' between path & code to be able to put at least one non-numeric character in content label
      message = getContent(contentObj, `${config.errorsPathCode}${code}`, lg);
    }
    if (!message) message = getContent(contentObj, `${config.errorsPath}.${code}`, lg);
  }
  // 3. Extract error message from errorData
  if (!message) {
    message = extractErrorMessage(errorData);
    // if the message is in fact the code (fallback to message)
    message = getContent(contentObj, `${config.errorsPath}.${message}`, lg) || message;
  }
  if (!message) return defaultError;

  return message;
};

export const handleApolloError = error => {
  const { networkError, graphQLErrors } = error;

  const constructedErrors = [];

  if (networkError && networkError.result) {
    const {
      // statusCode,
      result: { errors },
    } = networkError;

    if (Array.isArray(errors)) {
      errors.forEach(r => {
        constructedErrors.push({
          code: r.code,
          message: r.message,
          translations: r.translations,
        });
      });
    }
  }

  if (graphQLErrors) {
    if (Array.isArray(graphQLErrors)) {
      graphQLErrors.forEach(r => {
        constructedErrors.push({
          code: r.code,
          message: r.message,
          translations: r.translations,
        });
      });
    }
  }

  console.log('constructedErrors', constructedErrors);

  return { errors: constructedErrors };
};
