import { DomainServiceResolution as DomainDescriptor } from "@ledgerhq/domain-service/types";
import {
  signAddressResolution,
  signDomainResolution,
} from "@ledgerhq/domain-service/signers/index";
import { parse as parseTransaction } from "@ethersproject/transactions";

export type LedgerEthTransactionResolution = {
  // device serialized data that contains ERC20 data (hex format)
  erc20Tokens: Array<string>;
  // device serialized data that contains NFT data (hex format)
  nfts: Array<string>;
  // device serialized data that contains external plugin data (hex format)
  externalPlugin: Array<{ payload: string; signature: string }>;
  // device serialized data that contains plugin data (hex format)
  plugin: Array<string>;
  // device serialized data that contain trusted names data (hex format)
  domains: DomainDescriptor[];
};

export type LoadConfig = {
  // Backend service responsible for signed NFT APDUS
  nftExplorerBaseURL?: string | null;
  // example of payload https://cdn.live.ledger.com/plugins/ethereum/1.json
  // fetch against an api (base url is an api that hosts /plugins/ethereum/${chainId}.json )
  // set to null will disable it
  pluginBaseURL?: string | null;
  // provide manually some extra plugins to add for the resolution (e.g. for dev purpose)
  // object will be merged with the returned value of the Ledger cdn payload
  extraPlugins?: any | null;
  cryptoassetsBaseURL?: string | null;
  calServiceURL?: string | null;
  // Static ERC20 signatures fallback (base64 encoded blobs by chainId)
  // Can be provided from @ledgerhq/cryptoassets-evm-signatures/data/evm/index
  // Example: { 1: "base64blob...", 137: "base64blob..." }
  staticERC20Signatures?: Record<number, string> | null;
  // Static EIP712 signatures fallback (v1 format)
  // Can be provided from @ledgerhq/cryptoassets-evm-signatures/data/eip712
  // Example: { "1:0xcontract:hash": { fields: [...] }, ... }
  staticEIP712SignaturesV1?: Record<string, any> | null;
  // Static EIP712 signatures fallback (v2 format)
  // Can be provided from @ledgerhq/cryptoassets-evm-signatures/data/eip712_v2
  // Example: { "1:0xcontract:hash": { fields: [...] }, ... }
  staticEIP712SignaturesV2?: Record<string, any> | null;
};

/**
 * Allows to configure precisely what the service need to resolve.
 * for instance you can set nft:true if you need clear signing on NFTs. If you set it and it is not a NFT transaction, it should still work but will do a useless service resolution.
 */
export type ResolutionConfig = {
  // NFT resolution service
  nft?: boolean;
  // external plugins resolution service (e.G. LIDO)
  externalPlugins?: boolean;
  // ERC20 resolution service (to clear sign erc20 transfers & other actions)
  erc20?: boolean;
  // List of trusted names (ENS for now) to clear sign
  domains?: DomainDescriptor[];
  // activate uniswap v3 plugin resolution
  uniswapV3?: boolean;
};

export type LedgerEthTransactionService = {
  resolveTransaction: (
    rawTxHex: string,
    loadConfig: LoadConfig,
    resolutionConfig: ResolutionConfig,
    parseTx?: typeof parseTransaction,
    additionalErc20SignaturesConfig?: {
      additionalErc20SignaturesBlob: string;
      contractAddressToResolve: string;
    } | null,
  ) => Promise<LedgerEthTransactionResolution>;
  signDomainResolution: typeof signDomainResolution;
  signAddressResolution: typeof signAddressResolution;
  parseTransaction: typeof parseTransaction;
};
