import * as stylex from "@stylexjs/stylex";
import { type PropsWithChildren, createElement, memo } from "react";

import ToggleSliderInput from "./ToggleSliderInput";
import { switchConfig } from "./ToggleSliderInput.vars.stylex";
import { a11y, interaction } from "./mixins";
import { color, fontSize, size, transition } from "./tokens.stylex";

// TODO: ASK-UX maybe something like this?
// https://alvarotrigo.com/blog/toggle-switch-css/

export interface ToggleSwitchProps {
	label: string;

	name?: string;
	disabled?: boolean;

	/** HTML title attribute */
	title?: string;

	/** Maximum two lines of text. */
	description?: string;

	/** `value` and `onChange` are optional because we want to be able to use the control in an uncontrolled manner as well (for example, in forms) */
	value?: boolean;
	onChange?: (value: boolean) => void;

	defaultChecked?: boolean;
}

const styles = stylex.create({
	wrapper: {
		color: color.white900,

		cursor: "pointer",

		display: "grid",
		gridTemplateColumns: "auto 1fr",
		alignItems: "center",
		gap: `0 ${switchConfig.labelGap}`,

		transition: `${transition.a11yOutline}`,
	},

	disabled: {
		cursor: "not-allowed",
		color: color.gray100,
	},

	label: {
		textAlign: "left",
	},

	description: {
		fontSize: fontSize.sub,
		whiteSpace: "pre-line",
		textAlign: "left",
		color: color.gray100,

		gridColumn: "2",
	},

	stack: {
		display: "flex",
		flexDirection: "column",
		gap: size.px4,
	},
});

export default memo(function ToggleSwitch(props: ToggleSwitchProps) {
	return (
		// biome-ignore lint/a11y/noLabelWithoutControl: <input> is inside ToggleSliderInput
		<label
			{...stylex.props(
				interaction.disableTapHighlight,
				a11y.defaultOutline,
				styles.wrapper,
				props.disabled && styles.disabled,
			)}
			aria-disabled={props.disabled}
		>
			<ToggleSliderInput {...props} />
			<span {...stylex.props(styles.label)}>{props.label}</span>

			{props.description && (
				<span {...stylex.props(styles.description)}>
					{props.description}
				</span>
			)}
		</label>
	);
});

export type ToggleSwitchStackProps = PropsWithChildren;
export const ToggleSwitchStack = memo(function ToggleSwitchStack({
	children,
}: ToggleSwitchStackProps) {
	return createElement("div", stylex.props(styles.stack), children);
});
