import { useEffect, useState } from "react";
import { type Address, erc20Abi } from "viem";
import { useAccount, useBalance, useReadContract } from "wagmi";

import type { Token } from "@providers/ConfigProvider";
import { NATIVE_TOKEN_ADDRESS } from "@utils/constants";

type TokenBalance = {
	balance: string | bigint;
	isLoading: boolean;
};

const defaultValues = {
	balance: "0",
	isLoading: false,
};

const REFETCH_INTERVAL = 60000;

export const useTokenBalance = ({
	token,
	shouldFetch = true,
}: { token: Token; shouldFetch?: boolean }) => {
	const { address } = useAccount();
	const [value, setValue] = useState<TokenBalance>(defaultValues);

	const chainId = token?.chainId;
	// biome-ignore format:
	const tokenAddress = token?.address.toLowerCase() as `0x${string}`
	const isNativeToken = tokenAddress === NATIVE_TOKEN_ADDRESS;

	const {
		data: tokenBalance,
		isLoading,
		isFetching,
	} = useReadContract({
		abi: erc20Abi,
		chainId,
		address: tokenAddress,
		functionName: "balanceOf",
		args: [address as Address],
		query: {
			refetchInterval: REFETCH_INTERVAL,
			enabled: Boolean(!isNativeToken && token && address && shouldFetch),
		},
	});

	const {
		data: nativeTokenBalance,
		isLoading: isNativeBalanceLoading,
		isFetching: isNativeBalanceFetching,
	} = useBalance({
		address,
		chainId,
		query: {
			refetchInterval: REFETCH_INTERVAL,
			enabled: Boolean(isNativeToken && token && address),
		},
	});

	// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
	useEffect(() => {
		const getBal = () => {
			if (!address || tokenBalance?.toString() === "0") return "0";
			return (
				tokenBalance || nativeTokenBalance?.value?.toString() || token?.balance || "0"
			);
		};
		setValue({
			balance: getBal(),
			isLoading:
				isLoading || isNativeBalanceLoading || isFetching || isNativeBalanceFetching,
		});
	}, [
		tokenBalance,
		isLoading,
		nativeTokenBalance,
		isNativeBalanceLoading,
		isFetching,
		isNativeBalanceFetching,
		address,
	]);

	return value;
};
