export * from "./contracts";
export * from "./numbers";
export * from "./parseWeb3Error";
export * from "./strings";

import { Chain } from "@src/models";
import { format } from "date-fns";
import { ethers } from "ethers";

// eslint-disable-next-line
export const replaceNull = (values: any[], newValue: any) => {
  const modifiedValues = [...values];
  for (let i = 0; i < modifiedValues.length; i++) {
    if (Array.isArray(modifiedValues[i])) {
      modifiedValues[i] = replaceNull(modifiedValues[i], newValue);
    } else {
      if (modifiedValues[i] === null) {
        modifiedValues[i] = newValue;
      }
    }
  }
  return modifiedValues;
};

export const deepMergeObjects = (
  // eslint-disable-next-line
  obj1: Record<string, any>,
  // eslint-disable-next-line
  obj2: Record<string, any>,
) => {
  for (const key in obj2) {
    if (Object.prototype.hasOwnProperty.call(obj2, key)) {
      if (
        Object.prototype.hasOwnProperty.call(obj1, key) &&
        typeof obj1[key] === "object" &&
        typeof obj2[key] === "object"
      ) {
        deepMergeObjects(obj1[key], obj2[key]);
      } else {
        obj1[key] = obj2[key];
      }
    }
  }
  return { ...obj1 };
};

// eslint-disable-next-line
export const chunkArray = (array: any[], chunkSize: number): any[][] => {
  // eslint-disable-next-line
  const result: any[][] = [];
  for (let i = 0; i < array.length; i += chunkSize) {
    result.push(array.slice(i, i + chunkSize));
  }
  return result;
};

export const getDate = (blockTimestamp: number) => {
  const date = new Date(blockTimestamp * 1000);
  return format(date, "d MMM yyyy HH:mm:ss");
};

export const isServer = typeof window === "undefined";

// Helper function to validate and resolve token addresses
export const resolveTokenAddress = (
  tokenAddressOrId: string | undefined,
  chainId: string | undefined,
  chains: Chain[],
): string | undefined => {
  if (!tokenAddressOrId || ethers.utils.isAddress(tokenAddressOrId)) {
    return tokenAddressOrId;
  }
  // try to find the token by the tokenId
  return chains
    .find((chain) => chain.chainId === chainId)
    ?.tokens.find((token) => token.tokenId === tokenAddressOrId)
    ?.address?.toLowerCase();
};

export const sortChains = (chains: Chain[], disabledChainIds: string[]) =>
  [...chains]

    .map((chain) => ({
      ...chain,
      disabled: disabledChainIds.includes(chain.chainId),
    }))
    .sort((a, b) => {
      if (a.disabled === b.disabled) return 0;
      return a.disabled ? 1 : -1;
    });
