import { useEffect, useMemo, useState } from "react";
import { useDispatch } from "react-redux";
import { useSendTransaction } from "wagmi";

import { Button } from "@components/common/Button";
import {
	RequestStatusEnum,
	type StatusEndPoint,
} from "@hooks/apis/useRequestStatus";
import { useToast } from "@providers/ToastProvider";
import { ScreenTab, setScreenTab } from "@store/globalSlice";
import { setInflightData } from "@store/inflightSlice";
import { NATIVE_TOKEN_ADDRESS } from "@utils/constants";
import { getCommonErrors } from "@utils/getCommonErrors";
import type { FormattedQuoteData } from "@utils/getQuoteData";
import { isWrapUnwrapCase } from "@utils/isWrapUnwrapCase";
import type { QueryStatus } from "./SignOrder";

export const SendNativeTransaction = ({
	quoteData,
}: { quoteData: FormattedQuoteData }) => {
	const [status, setStatus] = useState<QueryStatus>("idle");
	const { sendTransaction, isSuccess, error } = useSendTransaction();
	const { showToast } = useToast();
	const dispatch = useDispatch();

	const {
		txData,
		input,
		output,
		requestHash,
		requestType,
		primaryInput,
		primaryOutput,
	} = quoteData;

	const isNativeToken = useMemo(
		() => primaryInput?.token?.address?.toLowerCase() === NATIVE_TOKEN_ADDRESS,
		[primaryInput],
	);

	function getButtonLabel() {
		if (status === "awaiting_wallet_confirmation") return "Confirm in wallet";
		if (status === "loading") return "Swapping";

		if (isWrapUnwrapCase(quoteData)) {
			if (isNativeToken) return "Wrap";
			return "Unwrap";
		}

		return "Swap";
	}

	function loadingState() {
		return status === "awaiting_wallet_confirmation" || status === "loading";
	}

	const initiateTransaction = () => {
		setStatus("awaiting_wallet_confirmation");
		sendTransaction(txData || {});
	};

	// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
	useEffect(() => {
		if (isSuccess && dispatch) {
			setStatus("idle");

			if (isWrapUnwrapCase(quoteData)) {
				const srcTokenSymbol = primaryInput?.token?.symbol;
				const destTokenSymbol = primaryOutput?.token?.symbol;
				const _label = isNativeToken ? "Wrapping Successful" : "Unwrapping Successful";
				// biome-ignore format:
				const _subtext = isNativeToken ? `Wrapped ${srcTokenSymbol} to ${destTokenSymbol}` : `Unwrapped ${srcTokenSymbol} to ${destTokenSymbol}`

				showToast(_label, _subtext);

				dispatch(setScreenTab(ScreenTab.HOME));
			} else {
				// to pre populate the inflight screen
				const _initialData = {
					input: input as StatusEndPoint[],
					output: output.map((item) => ({
						...item,
						minAmountOut: item.slippageAdjustedAmount,
					})) as StatusEndPoint[],
					requestHash: requestHash,
					statusId: RequestStatusEnum.PENDING,
				};

				dispatch(
					setInflightData({
						requestHash: requestHash,
						data: _initialData,
						requestType: requestType,
					}),
				);
				dispatch(setScreenTab(ScreenTab.INFLIGHT));
			}
		}
	}, [isSuccess, dispatch]);

	// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
	useEffect(() => {
		if (error?.name) {
			console.log("Error: ", error);
			setStatus("error");
			const { name, shortMessage } = getCommonErrors(error);
			showToast(name, shortMessage, "error");
		}
	}, [error]);

	return (
		<Button
			label={getButtonLabel()}
			disabled={loadingState()}
			isLoading={loadingState()}
			onClick={initiateTransaction}
		/>
	);
};
