import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useMemo, useState } from "react";
import { Bell, BellOff, ClipboardCheck, FileText, FolderTree, Globe, Loader2, Sparkles, } from "lucide-react";
import { DeleteIcon } from "../../../components/ui/delete-icon";
import { Badge } from "../../../components/ui/badge";
import { SettingsPanelLayout } from "../SettingsPanelLayout";
import { Button } from "../../../components/ui/button";
import { SettingsCard as Card } from "../SettingsCard";
import { LoadingState } from "../../ui/LoadingState";
import { Tooltip, TooltipContent, TooltipTrigger, } from "../../../components/ui/tooltip";
import { cn } from "../../../lib/utils";
import { useNotificationSubscriptions } from "../../notifications/useNotificationSubscriptions";
import { getEventTypeLabel } from "../../notifications/watchEventOptions";
import { ParheliaAgentIcon } from "../../ui/Icons";
const GROUPS = [
    {
        key: "item",
        title: "Items",
        icon: _jsx(FileText, { strokeWidth: 1, className: "h-5 w-5" }),
        targetTypes: ["item"],
    },
    {
        key: "project",
        title: "Projects",
        icon: _jsx(Sparkles, { strokeWidth: 1, className: "h-5 w-5" }),
        targetTypes: ["project"],
    },
    {
        key: "review",
        title: "Reviews",
        icon: _jsx(ClipboardCheck, { strokeWidth: 1, className: "h-5 w-5" }),
        targetTypes: ["review"],
    },
    {
        key: "agent-run",
        title: "Agent chats",
        icon: _jsx(ParheliaAgentIcon, { size: 20, strokeWidth: 1 }),
        targetTypes: ["agent-run"],
    },
];
function groupSubscriptions(subscriptions) {
    const buckets = new Map();
    const knownTypes = new Set(GROUPS.flatMap((g) => g.targetTypes));
    const others = [];
    for (const subscription of subscriptions) {
        const type = (subscription.targetType ?? "").toLowerCase();
        if (knownTypes.has(type)) {
            const list = buckets.get(type) ?? [];
            list.push(subscription);
            buckets.set(type, list);
        }
        else {
            others.push(subscription);
        }
    }
    const sortedGroups = GROUPS.map((group) => ({
        config: group,
        items: group.targetTypes.flatMap((type) => buckets.get(type) ?? []),
    })).filter((group) => group.items.length > 0);
    if (others.length > 0) {
        sortedGroups.push({
            config: {
                key: "other",
                title: "Other",
                icon: _jsx(Bell, { strokeWidth: 1, className: "h-5 w-5" }),
                targetTypes: [],
            },
            items: others,
        });
    }
    return sortedGroups;
}
const TARGET_TYPE_LABELS = {
    item: "Item",
    project: "Project",
    review: "Review",
    "agent-run": "Agent run",
};
function formatTargetTypeLabel(targetType) {
    const key = (targetType ?? "").toLowerCase();
    if (TARGET_TYPE_LABELS[key])
        return TARGET_TYPE_LABELS[key];
    if (!key)
        return "";
    return key.charAt(0).toUpperCase() + key.slice(1);
}
function getSubscriptionDisplayName(subscription) {
    const targetLabel = formatTargetTypeLabel(subscription.targetType);
    const fallback = `${targetLabel} ${subscription.targetId}`.trim();
    const displayName = subscription.displayName?.trim();
    if (!displayName)
        return fallback;
    // Older servers returned generated fallback names with the target ID cut to
    // eight characters. Reconstruct those names so mixed-version deployments do
    // not keep showing a clipped title after the client has been updated.
    const shortenedFallback = `${targetLabel} ${subscription.targetId.slice(0, 8)}…`.trim();
    return displayName === shortenedFallback ? fallback : displayName;
}
function SubscriptionRow({ subscription, }) {
    const { muteTarget, unmuteTarget, unsubscribeFromTarget } = useNotificationSubscriptions();
    const [pending, setPending] = useState(null);
    const targetType = (subscription.targetType ?? "").toLowerCase();
    const displayName = getSubscriptionDisplayName(subscription);
    const subtitle = subscription.path ?? null;
    const deleted = subscription.exists === false;
    const eventTypes = Array.isArray(subscription.eventTypes)
        ? subscription.eventTypes
        : [];
    const handleMuteToggle = async () => {
        if (pending)
            return;
        setPending("mute");
        try {
            if (subscription.isMuted) {
                await unmuteTarget({
                    targetType: subscription.targetType,
                    targetId: subscription.targetId,
                });
            }
            else {
                await muteTarget({
                    targetType: subscription.targetType,
                    targetId: subscription.targetId,
                });
            }
        }
        finally {
            setPending(null);
        }
    };
    const handleUnsubscribe = async () => {
        if (pending)
            return;
        setPending("unsubscribe");
        try {
            await unsubscribeFromTarget({
                targetType: subscription.targetType,
                targetId: subscription.targetId,
            });
        }
        finally {
            setPending(null);
        }
    };
    return (_jsxs("div", { className: "group border-border-default hover:bg-neutral-grey-5 flex items-start justify-between gap-4 border-b py-3 transition-colors last:border-b-0", "data-testid": `notification-subscription-${targetType}-${subscription.targetId}`, children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: cn("truncate text-sm font-medium", deleted
                                    ? "text-neutral-grey-50 line-through"
                                    : "text-neutral-grey-100"), title: displayName, children: displayName }), subscription.isAuto && (_jsx(Badge, { variant: "secondary", size: "sm", className: "shrink-0", children: "Auto" })), subscription.isMuted && (_jsx(Badge, { variant: "outline", size: "sm", className: "border-feedback-orange text-feedback-orange shrink-0", children: "Muted" })), subscription.includeDescendants && (_jsxs(Badge, { variant: "outline", size: "sm", className: "shrink-0 gap-1", children: [_jsx(FolderTree, { strokeWidth: 1, className: "size-3" }), "Subtree"] })), subscription.language && (_jsxs(Badge, { variant: "outline", size: "sm", className: "shrink-0 gap-1", children: [_jsx(Globe, { strokeWidth: 1, className: "size-3" }), subscription.language.toUpperCase()] }))] }), subtitle && (_jsx("div", { className: "text-neutral-grey-50 mt-0.5 truncate text-xs", title: subtitle, children: subtitle })), eventTypes.length > 0 && (_jsx("div", { className: "mt-1.5 flex flex-wrap gap-1", children: eventTypes.map((eventType) => (_jsx(Badge, { variant: "secondary", size: "sm", className: "font-normal", children: getEventTypeLabel(eventType) }, eventType))) }))] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1 opacity-0 transition-opacity group-focus-within:opacity-100 group-hover:opacity-100", children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "iconSm", onClick: () => void handleMuteToggle(), disabled: pending !== null, "aria-label": subscription.isMuted ? "Unmute" : "Mute", "data-testid": `notification-subscription-${targetType}-${subscription.targetId}-mute`, children: pending === "mute" ? (_jsx(Loader2, { strokeWidth: 1, className: "size-4 animate-spin" })) : subscription.isMuted ? (_jsx(BellOff, { strokeWidth: 1, className: "size-4" })) : (_jsx(Bell, { strokeWidth: 1, className: "size-4" })) }) }), _jsx(TooltipContent, { children: subscription.isMuted ? "Unmute" : "Mute" })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "iconSm", className: "text-neutral-grey-50 hover:bg-neutral-grey-5 hover:text-neutral-grey-50", onClick: () => void handleUnsubscribe(), disabled: pending !== null, "aria-label": "Unsubscribe", "data-testid": `notification-subscription-${targetType}-${subscription.targetId}-unsubscribe`, children: pending === "unsubscribe" ? (_jsx(Loader2, { strokeWidth: 1, className: "size-4 animate-spin" })) : (_jsx(DeleteIcon, { size: "lg" })) }) }), _jsx(TooltipContent, { children: "Unsubscribe" })] })] })] }));
}
export function NotificationSubscriptionsPanel() {
    const { subscriptions, initialized, refreshing } = useNotificationSubscriptions();
    const groups = useMemo(() => groupSubscriptions(subscriptions), [subscriptions]);
    const isLoading = !initialized && refreshing;
    const isEmpty = initialized && subscriptions.length === 0;
    return (_jsx(SettingsPanelLayout, { testId: "notification-subscriptions-panel", children: isLoading ? (_jsx(LoadingState, { variant: "inline", message: "Loading subscriptions...", className: "justify-center py-12", spinnerClassName: "text-neutral-grey-50" })) : isEmpty ? (_jsx(Card, { icon: _jsx(Bell, { strokeWidth: 1, className: "h-5 w-5" }), title: "No subscriptions yet", description: "You're not watching anything right now.", children: _jsx("p", { className: "text-neutral-grey-50 py-2 text-sm", children: "Use the watch button on items, projects, reviews, or agent runs to subscribe to notifications. They'll show up here so you can mute or unsubscribe at any time." }) })) : (_jsx("div", { className: "space-y-4", children: groups.map((group) => {
                return (_jsx(Card, { icon: group.config.icon, title: group.config.title, description: `${group.items.length} subscription${group.items.length === 1 ? "" : "s"}`, children: _jsx("div", { className: "divide-y-0", children: group.items.map((subscription) => (_jsx(SubscriptionRow, { subscription: subscription }, subscription.id))) }) }, group.config.key));
            }) })) }));
}
export default NotificationSubscriptionsPanel;
//# sourceMappingURL=NotificationSubscriptionsPanel.js.map