import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { Check, ChevronDown, Eye, Flag, FolderTree, X } from "lucide-react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { Button } from "../../components/ui/button";
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "../../components/ui/dropdown-menu";
import { Tooltip, TooltipContent, TooltipTrigger, } from "../../components/ui/tooltip";
import { cn } from "../../lib/utils";
import { useEditContext } from "../client/editContext";
import { getDefaultNotificationEventTypes } from "../services/notificationService";
import { subscribeToNotificationTarget, unmuteNotificationTarget, unsubscribeFromNotificationTarget, useNotificationSubscriptions, } from "./useNotificationSubscriptions";
import { getWatchEventOptions, } from "./watchEventOptions";
function orderEventTypes(eventTypes, targetType) {
    const eventOrder = getWatchEventOptions(targetType).map((option) => option.eventType);
    return [...eventTypes].sort((left, right) => {
        const leftIndex = eventOrder.indexOf(left);
        const rightIndex = eventOrder.indexOf(right);
        const normalizedLeft = leftIndex === -1 ? Number.MAX_SAFE_INTEGER : leftIndex;
        const normalizedRight = rightIndex === -1 ? Number.MAX_SAFE_INTEGER : rightIndex;
        return normalizedLeft - normalizedRight || left.localeCompare(right);
    });
}
export function WatchButton(props) {
    const { targetType, targetId, className } = props;
    const editContext = useEditContext();
    const [loading, setLoading] = useState(false);
    const [currentLanguageOnly, setCurrentLanguageOnly] = useState(false);
    const defaultEventTypes = useMemo(() => getDefaultNotificationEventTypes(targetType), [targetType]);
    const [selectedEventTypes, setSelectedEventTypes] = useState(() => getDefaultNotificationEventTypes(props.targetType));
    const { subscriptions } = useNotificationSubscriptions();
    const current = useMemo(() => {
        return subscriptions.find((s) => s.targetType.toLowerCase() === targetType && s.targetId === targetId);
    }, [subscriptions, targetType, targetId]);
    const isWatching = Boolean(current && !current.isMuted);
    const isSubtree = Boolean(current?.includeDescendants);
    const disabled = loading || !targetId;
    const currentEventTypes = current?.eventTypes?.length && Array.isArray(current.eventTypes)
        ? current.eventTypes
        : defaultEventTypes;
    const currentLanguage = targetType === "item"
        ? editContext?.currentItemDescriptor?.language
        : undefined;
    const languageOnlyLabel = current?.language && current?.language !== currentLanguage
        ? `Current language only (${current.language})`
        : "Current language only";
    const watchEventOptions = useMemo(() => getWatchEventOptions(targetType), [targetType]);
    useEffect(() => {
        setCurrentLanguageOnly(Boolean(current?.language));
    }, [current?.language]);
    useEffect(() => {
        setSelectedEventTypes(orderEventTypes(currentEventTypes, targetType));
    }, [current?.eventTypes, currentEventTypes, targetType]);
    const doSubscribe = useCallback(async (descendants, options) => {
        if (disabled)
            return;
        setLoading(true);
        try {
            const eventTypes = orderEventTypes(options?.eventTypes ?? selectedEventTypes, targetType);
            const applyCurrentLanguageOnly = options?.currentLanguageOnly ?? currentLanguageOnly;
            await subscribeToNotificationTarget({
                targetType,
                targetId,
                includeDescendants: targetType === "item" ? descendants : false,
                language: targetType === "item" && applyCurrentLanguageOnly
                    ? currentLanguage
                    : undefined,
                eventTypes,
            });
        }
        finally {
            setLoading(false);
        }
    }, [
        currentLanguage,
        currentLanguageOnly,
        disabled,
        selectedEventTypes,
        targetId,
        targetType,
    ]);
    const doUnsubscribe = useCallback(async () => {
        if (disabled)
            return;
        setLoading(true);
        try {
            await unsubscribeFromNotificationTarget({ targetType, targetId });
        }
        finally {
            setLoading(false);
        }
    }, [disabled, targetId, targetType]);
    const doUnmute = useCallback(async () => {
        if (disabled)
            return;
        setLoading(true);
        try {
            await unmuteNotificationTarget({ targetType, targetId });
        }
        finally {
            setLoading(false);
        }
    }, [disabled, targetId, targetType]);
    // Three-state toggle: subscribe when not subscribed, unmute when subscribed
    // but muted, otherwise unsubscribe. The middle branch matters most for
    // `review` / `agent-run` targets, which fall through to the single-button
    // render path below and have no dropdown escape hatch — without it,
    // clicking a muted subscription would silently delete it.
    const toggleSimple = useCallback(async () => {
        if (disabled)
            return;
        if (!current) {
            await doSubscribe(false);
        }
        else if (current.isMuted) {
            await doUnmute();
        }
        else {
            await doUnsubscribe();
        }
    }, [current, disabled, doSubscribe, doUnmute, doUnsubscribe]);
    const iconCls = "size-3.5";
    const stateIcon = isSubtree ? (_jsx(FolderTree, { className: iconCls })) : (_jsx(Eye, { className: iconCls }));
    const toggleTooltip = isWatching
        ? isSubtree
            ? "Watching subtree (click to unwatch)"
            : "Watching (click to unwatch)"
        : "Watch";
    const menuTooltip = "Watch options";
    const activeButtonClass = isWatching
        ? "bg-highlight-10 text-accent-foreground hover:bg-highlight-10/90"
        : undefined;
    const toggleEventType = useCallback((eventType) => {
        const nextEventTypes = (() => {
            if (selectedEventTypes.includes(eventType)) {
                if (selectedEventTypes.length === 1)
                    return selectedEventTypes;
                return selectedEventTypes.filter((value) => value !== eventType);
            }
            return orderEventTypes([...selectedEventTypes, eventType], targetType);
        })();
        setSelectedEventTypes(nextEventTypes);
        if (isWatching) {
            void doSubscribe(isSubtree, { eventTypes: nextEventTypes });
        }
    }, [doSubscribe, isSubtree, isWatching, selectedEventTypes, targetType]);
    const toggleCurrentLanguageOnly = useCallback(() => {
        const nextCurrentLanguageOnly = !currentLanguageOnly;
        setCurrentLanguageOnly(nextCurrentLanguageOnly);
        if (isWatching) {
            void doSubscribe(isSubtree, {
                currentLanguageOnly: nextCurrentLanguageOnly,
            });
        }
    }, [currentLanguageOnly, doSubscribe, isSubtree, isWatching]);
    if (targetType === "item" || targetType === "project") {
        const watchActionLabel = targetType === "item" ? "Watch item" : "Watch project";
        const watchActionTestId = targetType === "item"
            ? `watch-button-${targetType}-${targetId}-watch-item`
            : `watch-button-${targetType}-${targetId}-watch-project`;
        return (_jsxs("div", { id: "watch-button-controls", className: cn("inline-flex items-center", className), "data-testid": targetType === "item"
                ? `watch-button-${targetType}-${targetId}`
                : undefined, children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "iconSm", className: cn("rounded-r-none border-r-0", activeButtonClass), disabled: disabled, onClick: () => void toggleSimple(), id: "watch-button-toggle", "data-testid": targetType === "item"
                                    ? `watch-button-${targetType}-${targetId}-toggle`
                                    : `watch-button-${targetType}-${targetId}`, "aria-label": toggleTooltip, children: stateIcon }) }), _jsx(TooltipContent, { children: toggleTooltip })] }), _jsxs(DropdownMenu, { children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "iconSm", className: cn("w-5 min-w-0 rounded-l-none px-0", activeButtonClass), disabled: disabled, id: "watch-button-menu-trigger", "data-testid": `watch-button-${targetType}-${targetId}-menu-trigger`, "aria-label": menuTooltip, children: _jsx(ChevronDown, { className: "size-3" }) }) }) }), _jsx(TooltipContent, { children: menuTooltip })] }), _jsxs(DropdownMenuContent, { align: "end", className: "min-w-[160px]", children: [_jsxs(DropdownMenuItem, { onClick: () => void doSubscribe(false), "data-testid": watchActionTestId, className: cn("gap-2", isWatching &&
                                        !isSubtree &&
                                        "bg-highlight-10 text-accent-foreground hover:bg-highlight-10/90"), children: [_jsx(Eye, { className: "size-3.5" }), watchActionLabel, isWatching && !isSubtree && (_jsx(Check, { className: "text-feedback-green ml-auto size-3.5" }))] }), targetType === "item" && (_jsxs(_Fragment, { children: [_jsxs(DropdownMenuItem, { onClick: () => void doSubscribe(true), "data-testid": `watch-button-${targetType}-${targetId}-watch-subtree`, className: cn("gap-2", isWatching &&
                                                isSubtree &&
                                                "bg-highlight-10 text-accent-foreground hover:bg-highlight-10/90"), children: [_jsx(FolderTree, { className: "size-3.5" }), "Watch subtree", isWatching && isSubtree && (_jsx(Check, { className: "text-feedback-green ml-auto size-3.5" }))] }), _jsxs(DropdownMenuItem, { disabled: !currentLanguage, onClick: () => toggleCurrentLanguageOnly(), onSelect: (event) => event.preventDefault(), "data-testid": `watch-button-${targetType}-${targetId}-current-language-only`, className: cn("gap-2 text-xs", currentLanguageOnly &&
                                                "bg-highlight-10 text-accent-foreground hover:bg-highlight-10/90"), children: [_jsx(Flag, { className: "size-3.5" }), languageOnlyLabel, currentLanguageOnly && (_jsx(Check, { className: "text-feedback-green ml-auto size-3.5" }))] })] })), _jsx(DropdownMenuSeparator, {}), watchEventOptions.map((option) => {
                                    const selected = selectedEventTypes.includes(option.eventType);
                                    const Icon = option.icon;
                                    return (_jsxs(DropdownMenuItem, { onClick: () => toggleEventType(option.eventType), onSelect: (event) => event.preventDefault(), "data-testid": `watch-button-${targetType}-${targetId}-event-${option.eventType}`, className: cn("gap-2 text-xs", selected &&
                                            "bg-highlight-10 text-accent-foreground hover:bg-highlight-10/90"), children: [_jsx(Icon, { className: "size-3.5" }), option.label, selected && (_jsx(Check, { className: "text-feedback-green ml-auto size-3.5" }))] }, option.eventType));
                                }), isWatching && (_jsxs(_Fragment, { children: [_jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuItem, { onClick: () => void doUnsubscribe(), className: "gap-2", variant: "destructive", "data-testid": `watch-button-${targetType}-${targetId}-unwatch`, children: [_jsx(X, { className: "size-3.5" }), "Unwatch"] })] }))] })] })] }));
    }
    return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "iconSm", className: cn(className, activeButtonClass), disabled: disabled, onClick: () => void toggleSimple(), "data-testid": `watch-button-${targetType}-${targetId}`, "aria-label": toggleTooltip, children: stateIcon }) }), _jsx(TooltipContent, { children: toggleTooltip })] }));
}
//# sourceMappingURL=WatchButton.js.map