import { assignInlineVars } from "@vanilla-extract/dynamic";
import { useMemo } from "react";
import { useWritingMode } from "../../hook/useWritingMode";
import { cx } from "../../utils";
import { Dialog } from "../dialog";
import * as styles from "./drawer.css";
/**
 * A sliding panel component that appears from the edge of the screen.
 *
 * @remarks
 * The `Drawer` component is built on top of the {@link Dialog} component. It automatically
 * calculates its entrance and exit animations based on its `variant` and the current
 * document writing mode provided by {@link useWritingMode}.
 *
 * @param props - The properties for the drawer.
 * @returns A React component representing the drawer.
 *
 * @example
 * ### Basic Usage
 * ```tsx
 * <Drawer open={isOpen} onClose={() => setIsOpen(false)}>
 *   <p>This is a drawer</p>
 * </Drawer>
 * ```
 *
 * @example
 * ### Right-side Drawer (inline-end)
 * ```tsx
 * <Drawer
 *   variant="inlineEnd"
 *   size="400px"
 *   open={isOpen}
 *   onClose={() => setIsOpen(false)}
 * >
 *   <p>A wider drawer on the right</p>
 * </Drawer>
 * ```
 *
 * @example
 * ### Top Drawer (block-start)
 * ```tsx
 * <Drawer
 *   variant="blockStart"
 *   size="20vh"
 *   open={isOpen}
 *   onClose={() => setIsOpen(false)}
 * >
 *   <p>A drawer sliding down from the top</p>
 * </Drawer>
 * ```
 */
export function Drawer({ size, variant = "inlineStart", ...props }) {
    let { writingMode, direction } = useWritingMode();
    /**
     * Calculates the CSS transform for the closed state based on logical placement.
     *
     * @remarks
     * This logic ensures that the drawer slides out in the correct direction regardless
     * of the writing mode (horizontal vs vertical) and text direction (LTR vs RTL).
     */
    let transform = useMemo(() => {
        let isHorizontal = writingMode === "horizontal-tb";
        let isLtr = direction === "ltr";
        switch (variant) {
            case "inlineStart":
                if (isHorizontal) {
                    return `translateX(calc(${styles.drawerSize} * ${isLtr ? -1 : 1}))`;
                }
                return `translateY(calc(${styles.drawerSize} * -1))`;
            case "inlineEnd":
                if (isHorizontal) {
                    return `translateX(calc(${styles.drawerSize} * ${isLtr ? 1 : -1}))`;
                }
                return `translateY(${styles.drawerSize})`;
            case "blockStart":
                if (isHorizontal) {
                    return `translateY(calc(${styles.drawerSize} * -1))`;
                }
                return writingMode === "vertical-lr"
                    ? `translateX(calc(${styles.drawerSize} * -1))`
                    : `translateX(${styles.drawerSize})`;
            case "blockEnd":
                if (isHorizontal) {
                    return `translateY(${styles.drawerSize})`;
                }
                return writingMode === "vertical-lr"
                    ? `translateX(${styles.drawerSize})`
                    : `translateX(calc(${styles.drawerSize} * -1))`;
            default:
                return "translate(0)";
        }
    }, [writingMode, direction, variant]);
    let enterAnimation = props.enterAnimation ??
        `${styles.slideIn} 0.3s forwards ${styles.easingFunction}`;
    let exitAnimation = props.exitAnimation ??
        `${styles.slideOut} 0.3s forwards ${styles.easingFunction}`;
    return (<Dialog {...props} className={cx(styles.drawer, styles.drawerVariants[variant], props.className)} style={assignInlineVars({
            [styles.drawerSize]: size ? `${size}` : null,
            [styles.drawerClosedTransform]: transform,
        })} enterAnimation={enterAnimation} exitAnimation={exitAnimation}/>);
}
