import { ethers } from "ethers";

/**
 * Parses a Web3 error and returns a user-friendly error message.
 * @param error - The error object or message to parse.
 * @returns A user-friendly error message.
 */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function parseWeb3Error(error: any): string {
  let errorMessage =
    typeof error === "string"
      ? error
      : error?.message || "An unknown error occurred";

  // attach contract's errors like "insufficient funds for gas * price + value"
  errorMessage += error?.data?.message || "";

  // User rejected the transaction
  if (
    errorMessage.match(/User denied transaction signature/i) ||
    errorMessage.match(/User rejected the request/i) ||
    errorMessage.match(/User rejected transaction/i)
  ) {
    return "Transaction was cancelled.";
  }

  // Insufficient funds
  if (errorMessage.includes("insufficient funds")) {
    return "Insufficient funds to complete the transaction.";
  }

  // Gas price too low
  if (errorMessage.includes("gas price too low")) {
    return "Gas price is too low. Please increase the gas price and try again.";
  }

  // Nonce too low
  if (errorMessage.includes("nonce too low")) {
    return "Transaction nonce is too low. Please reset your account in MetaMask and try again.";
  }

  // Contract execution error
  if (errorMessage.includes("execution reverted")) {
    const revertReason = errorMessage.match(/reason: (.+?)(?:, method|$)/)?.[1];
    return revertReason
      ? `Transaction failed: ${revertReason}`
      : "Transaction failed during contract execution.";
  }

  // Gas limit exceeded
  if (errorMessage.includes("exceeds block gas limit")) {
    return "Transaction exceeded gas limit. Please try again with a higher gas limit.";
  }

  // Network error
  if (
    errorMessage.includes("network error") ||
    errorMessage.includes("connection error")
  ) {
    return "Network error. Please check your internet connection and try again.";
  }

  // Metamask specific errors
  if (errorMessage.includes("MetaMask Tx Signature:")) {
    return (
      "MetaMask error: " +
      errorMessage.split("MetaMask Tx Signature:")[1].trim()
    );
  }

  // Ethers.js specific errors
  if (error.code) {
    switch (error.code) {
      case ethers.errors.INVALID_ARGUMENT:
        return "Invalid argument provided to the transaction.";
      case ethers.errors.MISSING_ARGUMENT:
        return "Missing required argument for the transaction.";
      case ethers.errors.UNEXPECTED_ARGUMENT:
        return "Unexpected argument provided to the transaction.";
      case ethers.errors.CALL_EXCEPTION:
        return "Contract call failed. The transaction might have been reverted.";
      case ethers.errors.INSUFFICIENT_FUNDS:
        return "Insufficient funds to complete the transaction.";
      case ethers.errors.NONCE_EXPIRED:
        return "Transaction nonce has expired. Please try again.";
      case ethers.errors.REPLACEMENT_UNDERPRICED:
        return "Replacement transaction underpriced. Please increase the gas price.";
      case ethers.errors.UNPREDICTABLE_GAS_LIMIT:
        return "Unable to estimate gas limit. The transaction might fail.";
      default:
        return "An error occurred: " + error.message;
    }
  }

  // If no specific error is caught, return a generic message
  return "An error occurred while processing the transaction. Please try again.";
}
