import { useDebounce } from "@uidotdev/usehooks";
import { isValidENS } from "@utils/isValidENS.ts";
import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { usePasteFromClipboard } from "../hooks/usePasteFromClipboard";
import { useTheme } from "../hooks/useTheme";
import {
	type Validity,
	useValidateAddress,
} from "../hooks/useValidateAddress.ts";
import { toggleRecipientModal } from "../store/globalSlice";
import { setReceiverAddress, setReceiverENS } from "../store/quoteParamSlice";
import type { ReduxStateType } from "../store/types";
import { getBorderRadius } from "../utils/getBorderRadius";
import { Button } from "./common/Button.tsx";
import { MIcon } from "./common/MIcon.tsx";
import { ModalHeader } from "./common/ModalHeader.tsx";
import { SlideInPanel } from "./common/SlideInPanel.tsx";
import { SquaredCheckbox } from "./common/SquaredCheckbox.tsx";

// @fixme: color tokens
// @todo: need to make recipient address mandatory for smart wallets

export const RecipientAddressModal = () => {
	const dispatch = useDispatch();
	const theme = useTheme();
	const isOpen = useSelector(
		(state: ReduxStateType) => state.global.showRecipientModal,
	);
	const toChainId = useSelector(
		(state: ReduxStateType) => state.quoteParams.toChainId,
	);
	const receiver = useSelector(
		(state: ReduxStateType) => state.quoteParams.receiver,
	);

	const [value, setValue] = useState<string>("");
	const [disclaimer, setDisclaimer] = useState<boolean>(false);

	const { state: copiedAddress, pasteFromClipboard } = usePasteFromClipboard();
	const debouncedAddress = useDebounce(value, 300);

	const { state: addressStatus, address } = useValidateAddress({
		value: debouncedAddress,
		toChainId: toChainId ?? undefined,
	});

	function closePanel() {
		dispatch(toggleRecipientModal(false));
	}

	function dispatchRecipientAddress() {
		dispatch(setReceiverAddress(address));

		if (address && isValidENS(value)) {
			dispatch(setReceiverENS(value));
		} else {
			dispatch(setReceiverENS(null));
		}
		closePanel();
	}

	function removeRecipientAddress() {
		setValue("");
		setDisclaimer(false);
		dispatch(setReceiverAddress(""));
		closePanel();
	}

	useEffect(() => {
		setValue(copiedAddress);
	}, [copiedAddress]);

	useEffect(() => {
		setValue("");
	}, []);

	const HelperButton = () => {
		if (!receiver) {
			if (address)
				return (
					<button
						className="bn-h-6 bn-w-6 bn-border-0 bn-flex bn-items-center bn-justify-center bn-cursor-pointer bn-text-primary bn-bg-transparent"
						type="button"
						onClick={() => setValue("")}
					>
						<MIcon name="backspace" />
					</button>
				);

			return <PasteButton onClick={pasteFromClipboard} />;
		}
	};

	const modalTitle = receiver
		? "Edit Recipient Address"
		: "Add Recipient Address";

	return (
		<SlideInPanel isVisible={isOpen} closePanel={closePanel}>
			<ModalHeader label={modalTitle} closeModal={closePanel} />

			<div className="bn-p-4 bn-border-0 bn-border-b bn-border-solid bn-border-b-primary">
				<div
					className="bn-h-[52px] bn-border bn-border-solid bn-border-primary bn-pl-4 bn-pr-2.5 bn-relative bn-flex bn-items-center bn-justify-between"
					style={{ borderRadius: getBorderRadius(theme.borderRadius, 8) }}
				>
					<input
						className="bn-bg-transparent bn-text-sm bn-font-medium bn-text-primary bn-h-full bn-w-full bn-border-0 bn-mr-3 bn-overflow-ellipsis"
						value={value}
						onChange={(e) => setValue(e.target.value)}
						placeholder="Add destination address here"
						spellCheck={false}
						id="bn-receiver-address"
						disabled={!!receiver}
					/>

					<HelperButton />
				</div>

				{address && <ValidationBox status={addressStatus} />}
			</div>

			{receiver ? (
				<div className="bn-p-4">
					<Button
						onClick={removeRecipientAddress}
						label="Remove Recipient Address"
						classNames="bn-bg-fail"
					/>
				</div>
			) : (
				<div className="bn-p-4">
					<div className="bn-flex bn-items-center bn-mb-4">
						<SquaredCheckbox
							id="recipient-address-checkbox"
							active={disclaimer}
							setActive={setDisclaimer}
						/>
						<p className="bn-ml-1.5 bn-text-secondary bn-font-normal bn-text-sm">
							The address is correct and not an exchange wallet. Tokens sent to the wrong
							address can't be retrieved
						</p>
					</div>

					<Button
						onClick={dispatchRecipientAddress}
						label="Confirm Recipient Address"
						disabled={
							!address || !disclaimer || !addressStatus.isValid || addressStatus.isSender
						}
					/>
				</div>
			)}
		</SlideInPanel>
	);
};

const ValidationBox = ({ status }: { status: Validity }) => {
	const getMsg = () => {
		if (status.isContract) return "Smart contract";
		if (status.isSender)
			return "Recipient address cannot be same as connected wallet";
		if (!status.isValid) return "Invalid wallet address";
	};

	// biome-ignore format:
	const style = `bn-pl-1 bn-text-sm bn-font-normal bn-mt-2 ${status.isContract ? 'bn-text-accent' : 'bn-text-fail'}`

	if (!getMsg()) return null;
	return <p className={style}>{getMsg()}</p>;
};

const PasteButton = ({ onClick }: { onClick: () => void }) => {
	const theme = useTheme();
	return (
		<button
			type="button"
			className="bn-px-4 bn-py-1.5 bn-text-accent bn-text-sm bn-font-medium bn-bg-accent bn-border-0 bn-cursor-pointer"
			style={{ borderRadius: getBorderRadius(theme.borderRadius, 8) }}
			onClick={onClick}
		>
			Paste
		</button>
	);
};
