import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { CompareIcon } from "../../ui/Icons";
import { useEditContext } from "../../client/editContext";
import { SimpleIconButton } from "../../ui/SimpleIconButton";
import { Map, Layers, FileDiff, RotateCcw, ZoomIn, ZoomOut, } from "lucide-react";
import { Separator } from "../Separator";
import { useEffect, useState } from "react";
import { DEVICE_CHANGE_EVENT } from "../../page-viewer/pageViewContext";
import { DeviceSwitchToolbar } from "./DeviceSwitchToolbar";
import { EditControls, SuggestionsModeControl } from "./EditControls";
import { Select } from "../../../components/ui/select";
import { cn } from "../../../lib/utils";
const ZOOM_MIN = 0.25;
const ZOOM_MAX = 2;
const ZOOM_STEP = 0.25;
const ZOOM_PRESETS = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
const ZOOM_EXPANDED_WIDTH_CLASS = "w-[202px]";
function clampZoom(value) {
    return Math.min(ZOOM_MAX, Math.max(ZOOM_MIN, value));
}
function zoomValue(value) {
    return value.toFixed(2);
}
function zoomLabel(value) {
    return `${Math.round(value * 100)}%`;
}
function ZoomControls() {
    const editContext = useEditContext();
    const [showExpandedControls, setShowExpandedControls] = useState(false);
    const pageViewContext = !editContext || editContext.isMobile
        ? null
        : editContext.getActiveSlotContext()?.primaryPageViewContext;
    const zoom = pageViewContext?.zoom ?? 1;
    const activeZoomValue = zoomValue(zoom);
    const isDefaultZoom = Math.abs(zoom - 1) <= 0.001;
    const showZoomTools = showExpandedControls || !isDefaultZoom;
    useEffect(() => {
        if (!isDefaultZoom && pageViewContext?.device) {
            setShowExpandedControls(true);
        }
    }, [isDefaultZoom, pageViewContext?.device]);
    if (!editContext || editContext.isMobile)
        return null;
    if (!pageViewContext || !pageViewContext.device)
        return null;
    const presetOptions = ZOOM_PRESETS.map((value) => ({
        label: zoomLabel(value),
        value: zoomValue(value),
    }));
    const hasPreset = ZOOM_PRESETS.some((value) => zoomValue(value) === activeZoomValue);
    const options = hasPreset
        ? presetOptions
        : [
            ...presetOptions,
            {
                label: zoomLabel(zoom),
                value: activeZoomValue,
            },
        ];
    const setActiveSlotZoom = (value) => {
        setShowExpandedControls(true);
        const currentPageViewContext = editContext.getActiveSlotContext()?.primaryPageViewContext ??
            pageViewContext;
        currentPageViewContext.setZoom(value);
    };
    const resetZoom = () => {
        const currentPageViewContext = editContext.getActiveSlotContext()?.primaryPageViewContext ??
            pageViewContext;
        currentPageViewContext.setZoom(1);
        setShowExpandedControls(false);
    };
    return (_jsxs("div", { className: cn("relative flex h-8 shrink-0 items-center overflow-hidden transition-[width] duration-200 ease-out motion-reduce:transition-none", showZoomTools ? ZOOM_EXPANDED_WIDTH_CLASS : "w-8"), children: [_jsxs("div", { "aria-hidden": !showZoomTools, className: cn("flex items-center gap-0.5 transition-[opacity,transform] duration-150 ease-out motion-reduce:translate-x-0 motion-reduce:transition-none", showZoomTools
                    ? "translate-x-0 opacity-100 delay-75"
                    : "-translate-x-1 opacity-0"), children: [_jsx(Separator, { size: "large" }), _jsxs("div", { className: "flex items-center gap-0.5", children: [_jsx(SimpleIconButton, { icon: _jsx(ZoomOut, { className: "h-5 w-5 p-0.5", strokeWidth: 1 }), label: "Zoom out", className: "h-7 w-7 p-0.5", "data-testid": showZoomTools ? "zoom-out-button" : undefined, disabled: !showZoomTools || zoom <= ZOOM_MIN, tabIndex: showZoomTools ? undefined : -1, onClick: () => setActiveSlotZoom((value) => clampZoom(value - ZOOM_STEP)) }), _jsx(Select, { className: "h-7 w-[78px] border-transparent! bg-transparent! px-1.5 shadow-none! hover:border-transparent! hover:bg-neutral-grey-5! hover:shadow-none!", options: options, value: activeZoomValue, onValueChange: (value) => setActiveSlotZoom(Number(value)), placeholder: zoomLabel(zoom), size: "xs", disabled: !showZoomTools, "data-testid": showZoomTools ? "zoom-select" : undefined }), _jsx(SimpleIconButton, { icon: _jsx(ZoomIn, { className: "h-5 w-5 p-0.5", strokeWidth: 1 }), label: "Zoom in", className: "h-7 w-7 p-0.5", "data-testid": showZoomTools ? "zoom-in-button" : undefined, disabled: !showZoomTools || zoom >= ZOOM_MAX, tabIndex: showZoomTools ? undefined : -1, onClick: () => setActiveSlotZoom((value) => clampZoom(value + ZOOM_STEP)) }), _jsx(SimpleIconButton, { icon: _jsx(RotateCcw, { className: "h-5 w-5 p-0.5", strokeWidth: 1 }), label: "Reset zoom", className: "h-7 w-7 p-0.5", "data-testid": showZoomTools ? "zoom-reset-button" : undefined, disabled: !showZoomTools, tabIndex: showZoomTools ? undefined : -1, onClick: resetZoom })] }), _jsx(Separator, { size: "large" })] }), _jsx("div", { "aria-hidden": showZoomTools, className: cn("absolute inset-0 transition-opacity duration-150 ease-out motion-reduce:transition-none", showZoomTools
                    ? "pointer-events-none opacity-0"
                    : "opacity-100 delay-75"), children: _jsxs("div", { className: "relative h-8 w-8", children: [_jsx(Select, { className: "h-8 w-8 border-transparent! bg-transparent! px-0 shadow-none! hover:border-transparent! hover:bg-neutral-grey-5! hover:shadow-none! focus-visible:border-transparent! aria-expanded:border-transparent! [&>span]:sr-only [&>svg]:hidden", options: options, value: activeZoomValue, onValueChange: (value) => setActiveSlotZoom(Number(value)), placeholder: zoomLabel(zoom), size: "xs", disabled: showZoomTools, "data-testid": !showZoomTools ? "zoom-select" : undefined }), _jsx(ZoomIn, { className: "text-neutral-grey-100 pointer-events-none absolute top-1/2 left-1/2 h-4 w-4 -translate-x-1/2 -translate-y-1/2", strokeWidth: 1 })] }) })] }));
}
export function ViewportControls() {
    const editContext = useEditContext();
    // Counter to force re-renders when device changes.
    // The pageViewContext uses a stable ref pattern, so reading pageViewContext.device
    // won't trigger re-renders when device state changes. We listen to a custom event
    // dispatched by setDevice and increment this counter to force re-render.
    const [, setDeviceChangeCounter] = useState(0);
    useEffect(() => {
        const handler = () => {
            setDeviceChangeCounter((x) => x + 1);
        };
        window.addEventListener(DEVICE_CHANGE_EVENT, handler);
        return () => window.removeEventListener(DEVICE_CHANGE_EVENT, handler);
    }, []);
    if (!editContext || editContext.isMobile)
        return null;
    const activeSlotContext = editContext.getActiveSlotContext();
    const pageViewContext = activeSlotContext?.primaryPageViewContext;
    if (!pageViewContext)
        return null;
    const device = pageViewContext.device;
    const hasLayout = activeSlotContext.item?.hasLayout ??
        editContext.item?.hasLayout ??
        pageViewContext.page?.item?.hasLayout ??
        false;
    const canToggleDiffHighlighting = hasLayout && !!device;
    const showZoomControls = hasLayout && !!device;
    return (_jsxs(_Fragment, { children: [hasLayout && (_jsxs(_Fragment, { children: [_jsx(DeviceSwitchToolbar, {}), showZoomControls && _jsx(ZoomControls, {}), _jsx(EditControls, { hideSuggestions: true }), _jsx(Separator, { size: "large" })] })), !editContext.isMobile && (_jsx(SimpleIconButton, { icon: _jsx(CompareIcon, { className: "h-6 w-6 p-1" }), label: "Compare", size: "large", "data-testid": "compare-mode-button", className: activeSlotContext?.compareMode
                    ? "text-neutral-grey-50"
                    : "hover:text-neutral-grey-50", selected: activeSlotContext?.compareMode, onClick: () => {
                    activeSlotContext.setCompareMode(!activeSlotContext.compareMode);
                } })), hasLayout && _jsx(SuggestionsModeControl, { leadingSeparator: true }), activeSlotContext.compareMode && (_jsx(SimpleIconButton, { icon: _jsx(FileDiff, { className: "h-6 w-6 p-1", strokeWidth: 1 }), label: "Highlight changes", size: "large", "data-testid": "toggle-version-diff-highlighting-button", selected: editContext.showVersionDiffHighlighting, disabled: !canToggleDiffHighlighting, onClick: () => {
                    if (!canToggleDiffHighlighting)
                        return;
                    editContext.setShowVersionDiffHighlighting(!editContext.showVersionDiffHighlighting);
                } }))] }));
}
export function ViewPanelControls() {
    const editContext = useEditContext();
    if (!editContext || editContext.isMobile)
        return null;
    const activeSlotContext = editContext.getActiveSlotContext();
    const pageViewContext = activeSlotContext?.primaryPageViewContext;
    if (!pageViewContext)
        return null;
    const hasLayout = activeSlotContext.item?.hasLayout ??
        editContext.item?.hasLayout ??
        pageViewContext.page?.item?.hasLayout ??
        false;
    const minimapEnabledInSettings = editContext.parheliaSettings?.showMinimap !== false;
    const canToggleComponentNavigator = hasLayout;
    return (_jsxs(_Fragment, { children: [minimapEnabledInSettings && (_jsx(SimpleIconButton, { icon: _jsx(Map, { className: "h-6 w-6 p-1", strokeWidth: 1 }), label: "Show minimap", size: "large", "data-testid": "toggle-minimap-button", selected: editContext.showMinimap, onClick: () => editContext.setShowMinimap(!editContext.showMinimap) })), canToggleComponentNavigator && (_jsx(SimpleIconButton, { icon: _jsx(Layers, { className: "h-6 w-6 p-1", strokeWidth: 1 }), label: "Component Navigator", size: "large", "data-testid": "component-navigator-button", selected: editContext.showComponentNavigator, onClick: () => editContext.setShowComponentNavigator(!editContext.showComponentNavigator) }))] }));
}
//# sourceMappingURL=ViewportControls.js.map