import type { Token } from "@/types/index";
import { Button } from "@components/common/Button";
import { ModalHeader } from "@components/common/ModalHeader";
import { PercentageBar } from "@components/common/PercentageBar";
import { SlideInPanel } from "@components/common/SlideInPanel";
import { TokenChip } from "@components/common/TokenChip";
import { setMultiTokenData } from "@store/multiTokenModalSlice";
import { addOutputToken, setOutputTokenRatios } from "@store/quoteParamSlice";
import type { ReduxStateType } from "@store/types";
import { toFixedSafe } from "@utils/toFixedSafe";
import { type MutableRefObject, useEffect, useRef, useState } from "react";
import { useDispatch, useSelector } from "react-redux";

const percentageOptions = [5, 10, 25, 50, 75];

export const MultiTokenModal = () => {
	const dispatch = useDispatch();
	const { isVisible, data } = useSelector(
		(state: ReduxStateType) => state.multiTokenAmount,
	);
	const [percent, setPercent] = useState<number>(5);
	const [inputWidth, setInputWidth] = useState<number>(30);

	/** @todo change this later */
	const dummyElementRef = useRef() as MutableRefObject<HTMLDivElement>;

	useEffect(() => {
		if (percent && isVisible) {
			setInputWidth(dummyElementRef?.current?.clientWidth);
		}
	}, [dummyElementRef, percent, isVisible]);

	function closePanel() {
		dispatch(setMultiTokenData({ isVisible: false, data: null }));
	}

	function addMultiToken(token: Token, ratio: number) {
		const ratioTwo = toFixedSafe(ratio / 100);
		const ratioOne = toFixedSafe(1 - ratioTwo);

		if (!data?.isSource) {
			// setting output
			dispatch(addOutputToken({ id: 1, token }));
			// setting ratio
			dispatch(setOutputTokenRatios([ratioOne, ratioTwo]));
			// closing modal
			dispatch(setMultiTokenData({ isVisible: false, data: null }));
		}
	}

	const inputStyle =
		"bn-text-primary bn-text-[36px] bn-font-medium bn-bg-transparent bn-border-0 bn-p-0";

	function onChange(e: React.ChangeEvent<HTMLInputElement>) {
		let _value = e.currentTarget.valueAsNumber;
		if (_value > 99) _value = 99;
		if (_value < 1) _value = 1;

		setPercent(Math.floor(_value));
	}

	if (!data) return null; // @note: this will result in abrupt closing of the modal
	return (
		<SlideInPanel
			isVisible={isVisible}
			closePanel={closePanel}
			cardClasses="bn-h-full"
		>
			<ModalHeader label="Enter Token Amount" closeModal={closePanel} />

			<div className="bn-p-4 bn-flex bn-flex-col bn-items-center bn-w-full bn-h-full bn-justify-center">
				<TokenChip token={data.defaultToken} onClick={() => {}} active big />

				<div className="bn-my-5 bn-flex bn-flex-col bn-justify-center">
					<div className="bn-aeonik-font bn-leading-[41px] bn-flex bn-items-center bn-justify-center bn-relative">
						<input
							placeholder="0.0"
							value={percent}
							onChange={onChange}
							type="number"
							inputMode="numeric"
							className={inputStyle}
							min={1}
							max={99}
							maxLength={2}
							// biome-ignore format:
							style={{ width: `${inputWidth}px` }}
							step={1}
						/>
						<span className="bn-text-primary bn-text-[36px] bn-font-medium">%</span>

						{/* dummy element */}
						<div
							className={inputStyle}
							style={{ visibility: "hidden", position: "absolute" }}
							ref={dummyElementRef}
						>
							{percent}
						</div>
					</div>
					<p className="bn-text-secondary bn-text-sm bn-font-medium bn-text-center bn-mt-1">
						of expected output
					</p>
				</div>

				<div className="bn-space-x-2 bn-w-full bn-flex bn-max-w-[420px] bn-mb-8">
					{percentageOptions.map((item) => (
						<PercentButton
							label={item.toString()}
							key={item}
							onClick={() => setPercent(item)}
							active={item === percent}
						/>
					))}
				</div>

				<PercentageBar
					ratio={[toFixedSafe(1 - percent / 100), toFixedSafe(percent / 100)]}
					endpoints={[
						{
							token: data.otherTokens[0],
							amount: "",
							chainId: 0,
							valueInUsd: 0,
							priceInUsd: 0,
						},
						{
							token: data.defaultToken,
							amount: "",
							chainId: 0,
							valueInUsd: 0,
							priceInUsd: 0,
						},
					]}
					showHeading
				/>

				<Button
					label="Add Token"
					onClick={() => addMultiToken(data.defaultToken, percent)}
					classNames="bn-mt-8"
				/>
			</div>
		</SlideInPanel>
	);
};

const PercentButton = ({
	label,
	onClick,
	active = false,
}: {
	label: string;
	onClick: () => void;
	active?: boolean;
}) => {
	// biome-ignore format:
	const style = `bn-rounded-full bn-font-medium bn-aeonik-font bn-text-base bn-p-2.5 bn-border-none bn-cursor-pointer bn-flex-1 hover:bn-bg-layer-3 ${active ? 'bn-bg-accent-1 bn-text-accent-1' : 'bn-bg-layer-2  bn-text-primary'}`
	return (
		<button type="button" className={style} onClick={onClick}>
			{label}%
		</button>
	);
};
