import { useEffect, useState } from "react";
import { isAddress } from "viem";
import { normalize } from "viem/ens";
import { useAccount, useBytecode, useEnsAddress } from "wagmi";

import { isValidENS } from "@utils/isValidENS";

export interface Validity {
	isValid: boolean;
	isContract: boolean;
	isSender: boolean;
	isChecking: boolean;
}

// biome-ignore format:
type Address = `0x${string}`;

/**
 * Checks the validity of ENS or Account Address
 */
export const useValidateAddress = ({
	value,
	toChainId,
}: {
	value: string;
	toChainId?: number;
}) => {
	const [state, setState] = useState<Validity>({
		isValid: true,
		isContract: false,
		isSender: false,
		isChecking: false,
	});
	const [address, setAddress] = useState<string>();

	const { address: senderAddress } = useAccount();

	// getting ensAddress if value is in valid ens format
	const { data: ensAddress, isPending } = useEnsAddress({
		name: isValidENS(value) ? normalize(value) : "",
		chainId: toChainId,
		query: {
			enabled: isValidENS(value) && Boolean(toChainId),
		},
	});

	useEffect(() => {
		if (!isValidENS(value) || !isPending) setAddress(ensAddress || value);
	}, [ensAddress, value, isPending]);

	const result = useBytecode({
		address: address as Address,
		chainId: toChainId,
	});

	// @note: code can be improved, low impact
	// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
	useEffect(() => {
		const _isAddress = address ? isAddress(address.toLowerCase()) : false;

		setState({
			isValid: _isAddress,
			isContract: Boolean(result?.data),
			isSender: senderAddress?.toLowerCase() === address?.toLowerCase(),
			isChecking: isValidENS(value) ? isPending : false,
		});
	}, [address, isPending]);

	return { state, address };
};
