import useOpenable from "@Front/Hooks/useOpenable";
import { ChevronDownIcon } from "@heroicons/react/24/outline";
import classNames from "classnames";
import { useCallback, useEffect, useState } from "react";

import Typography, { ETypo, ETypoColor } from "../Typography";
import classes from "./classes.module.scss";
import DropdownMenu from "./DropdownMenu";
import { IOption } from "./DropdownMenu/DropdownOption";

type IProps = {
	options: IOption[];
	label?: string;
	placeholder?: string;
	disabled?: boolean;
	onSelect?: (option: IOption) => void;
	selectedOption?: IOption | null;
};

export default function Dropdown(props: IProps) {
	const { options, placeholder, disabled, onSelect, selectedOption: selectedOptionProps, label } = props;
	const [selectedOption, setSelectedOption] = useState<IOption | null>(selectedOptionProps ?? null);
	const openable = useOpenable({ defaultOpen: false });

	useEffect(() => {
		setSelectedOption(selectedOptionProps ?? null);
	}, [selectedOptionProps]);

	const handleOnSelect = useCallback(
		(newOption: IOption, _options: IOption[]) => {
			setSelectedOption(newOption);
			onSelect?.(newOption);
		},
		[onSelect],
	);

	return (
		<DropdownMenu
			options={options}
			openable={openable}
			onSelect={handleOnSelect}
			selectedOptions={selectedOption ? [selectedOption] : []}>
			<div className={classes["root"]}>
				{label && (
					<Typography className={classes["label"]} typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.CONTRAST_DEFAULT}>
						{label}
					</Typography>
				)}
				<div
					className={classNames([
						classes["container"],
						openable.isOpen && classes["open"],
						disabled && classes["disabled"],
						!!selectedOption && classes["active"],
					])}
					onClick={openable.toggle}>
					<div className={classes["content"]}>
						<Typography
							className={classes["value"]}
							typo={!!selectedOption ? ETypo.TEXT_MD_SEMIBOLD : ETypo.TEXT_MD_REGULAR}
							color={!!selectedOption ? ETypoColor.DROPDOWN_CONTRAST_ACTIVE : ETypoColor.DROPDOWN_CONTRAST_DEFAULT}>
							{getLabel(selectedOption) ?? placeholder}
						</Typography>
						<ChevronDownIcon />
					</div>
				</div>
			</div>
		</DropdownMenu>
	);
}

export function getLabel(option: IOption | null): string | null {
	if (!option) return null;
	if (typeof option.label === "string") {
		return option.label;
	}
	return `${option.label.text} ${option.label.subtext}`;
}
