import { Web3Provider } from "@ethersproject/providers";
import BigNumber from "bignumber.js";
import { ERRORS } from "../helpers/constants";
import { QuoteLoader } from "../helpers/quote-loader";
import { toSuffixFormat } from "./configureFormats";

export function cutAddress(address: string, left: number = 4, right: number = 4): string {
  if (!address || address.length < 8) {
    return address;
  }

  return `${address.substring(0, left)}...${address.substring(address.length - right)}`;
}

export function tryParseJSON(str: string): any | null {
  try {
    return JSON.parse(str);
  } catch (e) {
    return null;
  }
}

export function renderTemplateString(template: string, values: {
  rate?: string,
  incomeApyRate?: string,
  coverage?: string,
  quote?: string,
  coverageTokenInfo?: {decimals: number, symbol: string},
  quoteTokenInfo?: {decimals: number, symbol: string},
  market?: {entityList: string[], marketId: string},
}): string {
  return template.replaceAll("{rate}", values.rate || "{}")
    .replaceAll("{netApyRate}", (+(values.incomeApyRate ?? 0) - +(values.rate ?? 0)).toFixed(2) || "{}")
    .replaceAll("{incomeApyRate}", (+(values.incomeApyRate ?? 0)).toFixed(2) || "{}")
    .replaceAll("{quote}", (values.quote && toSuffixFormat(new BigNumber(values.quote || "0"), 2)) || "{}")
    .replaceAll("{marketEntity}", values.market?.entityList.map(item => item.length > 16 ? `${item.substring(0, 16)}...` : item).join(" - ") || "{}")
    .replaceAll("{marketNo}", values.market?.marketId || "{}")
    .replaceAll("{quoteCurrency}", values.quoteTokenInfo?.symbol || "{}")
    .replaceAll("{coverage}", (values.coverage && values.coverageTokenInfo && toSuffixFormat(new BigNumber(values.coverage || "0").div(`1e${values.coverageTokenInfo?.decimals || 0}`), 2)) || "{}")
    .replaceAll("{coverageCurrency}", values.coverageTokenInfo?.symbol || "{}");
}

export async function getNetworkParams(provider: Web3Provider) {
  if (!provider || !provider.listAccounts) {
    return null;
  }

  const lib = provider;
  const account = (await lib.listAccounts())[0];
  const network = (await lib.getNetwork()).name;
  const chainId = (await lib.getNetwork()).chainId;

  return {account, network, lib, chainId};
}

export async function checkProviderState(provider: Web3Provider, quoteLoader: QuoteLoader): Promise<string | undefined> {
  if (!provider || !provider.provider) {
    return ERRORS.NO_WEB3;
  }

  const params = await getNetworkParams(provider);

  if (!params?.account) {
    return ERRORS.ACCOUNT_LOCKED;
  }

  if (quoteLoader.sdk.envConfig && params.chainId !== quoteLoader.sdk.envConfig?.chainId) {
    return ERRORS.WRONG_NETWORK;
  }

  return;
}

export function processErrorMessage(error: string): string {
  if (error.includes("ERROR::NOT_ALLOWED")) {
    return "Market is private. Only listed accounts can activate protection.";
  }

  if (error.includes("_IS_CLOSED")) {
    return "Market is locked, try again later.";
  }

  if (error.includes("User denied transaction signature") || error.includes("user rejected transaction")) {
    return "The operation was cancelled.";
  }

  if (error.includes("Wallet is locked. No accounts available.")) {
    return "Wallet is locked.";
  }

  if (error.includes("underlying network changed")) {
    return ERRORS.WRONG_NETWORK;
  }

  return "Blockchain error, try again later.";
}

export function getBuyPolicyUrl(baseUrl: string | undefined, marketId: string | undefined, fo?: string, referrer?: string): string {
  if (!baseUrl || !marketId) {
    return "";
  }

  return `${baseUrl}/protection?marketId=${marketId}${
    fo ? `&frontend=${fo}` : ""}${
    referrer ? `&referrer=${referrer}` : ""}`;
}

export function getPolicyDetailUrl(baseUrl: string | undefined, policyId: string | undefined): string {
  if (!baseUrl || !policyId) {
    return "";
  }

  return `${baseUrl}/portfolio?policyId=${policyId}`;
}

export function getMarketUrl(baseUrl: string | undefined, marketId: string | undefined): string {
  if (!baseUrl || !marketId) {
    return "";
  }

  return `${baseUrl}/market/${marketId}`;
}
