import { useTargetNetwork } from "./useTargetNetwork"
import { Abi, ExtractAbiEventNames } from "abitype"
import { Log } from "viem"
import { useWatchContractEvent as useWagmiWatchContractEvent } from "wagmi"
import {
  addIndexedArgsToEvent,
  useDeployedContractInfo,
} from "~~/hooks/xchange-create"
import {
  ContractAbi,
  ContractName,
  UseEventConfig,
} from "~~/utils/xchange/contract"

/**
 * Wrapper around wagmi's useEventSubscriber hook which automatically loads (by name) the contract ABI and
 * address from the contracts present in deployedContracts.ts & externalContracts.ts
 * @param config - The config settings
 * @param config.contractName - deployed contract name
 * @param config.eventName - name of the event to listen for
 * @param config.onLogs - the callback that receives events.
 */
export const useWatchContractEvent = <
  TContractName extends ContractName,
  TEventName extends ExtractAbiEventNames<ContractAbi<TContractName>>,
>({
  contractName,
  eventName,
  onLogs,
}: UseEventConfig<TContractName, TEventName>) => {
  const { data: deployedContractData } = useDeployedContractInfo(contractName)
  const { targetNetwork } = useTargetNetwork()

  const addIndexedArgsToLogs = (logs: Log[]) => logs.map(addIndexedArgsToEvent)
  const listenerWithIndexedArgs = (logs: Log[]) =>
    onLogs(addIndexedArgsToLogs(logs) as Parameters<typeof onLogs>[0])

  return useWagmiWatchContractEvent({
    address: deployedContractData?.address,
    abi: deployedContractData?.abi as Abi,
    chainId: targetNetwork.id,
    onLogs: listenerWithIndexedArgs,
    eventName,
  })
}
