import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useEffect, useMemo, useRef, useState } from "react";
import { ChevronDown, ChevronUp, Loader2, Share2, UserRound, Users as UsersIcon, X, } from "lucide-react";
import { toast } from "sonner";
import { Button } from "../../components/ui/button";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "../../components/ui/command";
import { Popover, PopoverContent, PopoverTrigger, } from "../../components/ui/popover";
import { Select } from "../../components/ui/select";
import { addAgentMember, getAgentMembers, removeAgentMember, searchAgentPrincipals, } from "../services/agentService";
const ACCESS_LEVEL_OPTIONS = [
    { value: "View", label: "View" },
    { value: "FullAccess", label: "Full access" },
];
const MIN_QUERY_LENGTH = 2;
export function AgentSharingSection({ agentId, canManage }) {
    const [members, setMembers] = useState(null);
    const [loadError, setLoadError] = useState(null);
    const [pendingAccessLevel, setPendingAccessLevel] = useState("View");
    const [pendingPrincipal, setPendingPrincipal] = useState(null);
    const [adding, setAdding] = useState(false);
    const [expanded, setExpanded] = useState(false);
    useEffect(() => {
        let cancelled = false;
        setMembers(null);
        setLoadError(null);
        getAgentMembers(agentId)
            .then((result) => {
            if (!cancelled)
                setMembers(result);
        })
            .catch((err) => {
            if (!cancelled) {
                setLoadError(err instanceof Error ? err.message : "Failed to load");
                setMembers([]);
            }
        });
        return () => {
            cancelled = true;
        };
    }, [agentId]);
    const handleAdd = async () => {
        if (!pendingPrincipal || adding)
            return;
        const optimistic = {
            memberId: `temp-${Date.now()}`,
            agentId,
            principalType: pendingPrincipal.principalType,
            principalIdentifier: pendingPrincipal.identifier,
            displayName: pendingPrincipal.displayName,
            accessLevel: pendingAccessLevel,
        };
        setAdding(true);
        setMembers((prev) => [...(prev ?? []), optimistic]);
        try {
            const created = await addAgentMember(agentId, pendingPrincipal.principalType, pendingPrincipal.identifier, pendingAccessLevel);
            setMembers((prev) => (prev ?? []).map((m) => (m.memberId === optimistic.memberId ? created : m)));
            setPendingPrincipal(null);
        }
        catch (err) {
            setMembers((prev) => (prev ?? []).filter((m) => m.memberId !== optimistic.memberId));
            toast.error(err instanceof Error ? err.message : "Failed to add member");
        }
        finally {
            setAdding(false);
        }
    };
    const handleRemove = async (memberId) => {
        const previous = members ?? [];
        setMembers(previous.filter((m) => m.memberId !== memberId));
        try {
            await removeAgentMember(memberId);
        }
        catch (err) {
            setMembers(previous);
            toast.error(err instanceof Error ? err.message : "Failed to remove member");
        }
    };
    return (_jsxs("div", { className: "min-w-0", children: [_jsxs("button", { type: "button", onClick: () => setExpanded((open) => !open), className: "mb-0.5 flex w-full items-center justify-between rounded px-0.5 py-0.5 text-left text-[11px] font-medium text-gray-700 hover:bg-gray-100/80", "aria-expanded": expanded, "data-testid": "agent-sharing-section-toggle", children: [_jsxs("span", { className: "flex min-w-0 items-center gap-1", children: [_jsx(Share2, { className: "h-3 w-3 shrink-0", strokeWidth: 1 }), _jsx("span", { className: "truncate", children: `Shared with (${members?.length ?? 0})` })] }), expanded ? (_jsx(ChevronUp, { className: "h-3 w-3 shrink-0 text-gray-400", strokeWidth: 1.5 })) : (_jsx(ChevronDown, { className: "h-3 w-3 shrink-0 text-gray-400", strokeWidth: 1.5 }))] }), expanded ? (members === null ? (_jsxs("div", { className: "flex items-center gap-1 px-1 text-[10px] text-gray-500", children: [_jsx(Loader2, { className: "h-3 w-3 animate-spin" }), "Loading members..."] })) : (_jsxs(_Fragment, { children: [loadError ? (_jsx("div", { className: "mb-1 px-1 text-[10px] text-red-600", children: loadError })) : null, members.length === 0 ? (_jsx("div", { className: "px-1 text-[10px] text-gray-500", children: canManage
                            ? "Only you can access this agent."
                            : "Not shared with anyone explicitly." })) : (_jsx("div", { className: "space-y-1", children: members.map((m) => (_jsx(MemberRow, { member: m, canManage: canManage, onRemove: () => handleRemove(m.memberId) }, m.memberId))) })), canManage && (_jsxs("div", { className: "mt-2 grid w-full min-w-0 grid-cols-[minmax(0,1fr)_5.5rem_auto] items-center gap-1", children: [_jsx(PrincipalPicker, { value: pendingPrincipal, onChange: setPendingPrincipal, disabled: adding }), _jsx("div", { className: "min-w-0", children: _jsx(Select, { size: "xs", className: "h-6 w-full rounded border px-1.5 text-[11px] text-gray-500", value: pendingAccessLevel, options: ACCESS_LEVEL_OPTIONS.map((o) => ({
                                        value: o.value,
                                        label: o.label,
                                    })), onValueChange: (v) => setPendingAccessLevel(v) }) }), _jsx(Button, { size: "xs", variant: "outline", className: "h-6 min-w-9 shrink-0 px-2 text-[10px]", disabled: !pendingPrincipal || adding, onClick: () => void handleAdd(), "data-testid": "agent-sharing-add-button", children: adding ? (_jsx(Loader2, { className: "h-3 w-3 animate-spin" })) : ("Add") })] }))] }))) : null] }));
}
function MemberRow({ member, canManage, onRemove, }) {
    const Icon = member.principalType === "Role" ? UsersIcon : UserRound;
    return (_jsxs("div", { className: "flex items-center gap-1 rounded px-1 py-0.5 text-[11px] text-gray-700 hover:bg-gray-50", children: [_jsx(Icon, { className: "h-3 w-3 shrink-0 opacity-70", strokeWidth: 1.5 }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "truncate", children: member.displayName || member.principalIdentifier }), _jsx("div", { className: "truncate text-[9px] text-gray-400", children: member.principalIdentifier })] }), _jsx("span", { className: "shrink-0 rounded bg-gray-100 px-1 py-0.5 text-[9px] text-gray-600", children: member.accessLevel === "FullAccess" ? "Full" : "View" }), canManage && (_jsx("button", { type: "button", className: "ml-1 rounded p-0.5 text-gray-400 hover:bg-gray-200 hover:text-gray-700", onClick: onRemove, "aria-label": `Remove ${member.displayName || member.principalIdentifier}`, "data-testid": `agent-sharing-remove-${member.memberId}`, children: _jsx(X, { className: "h-3 w-3", strokeWidth: 1.5 }) }))] }));
}
function PrincipalPicker({ value, onChange, disabled, }) {
    const [open, setOpen] = useState(false);
    const [query, setQuery] = useState("");
    const [loading, setLoading] = useState(false);
    const [results, setResults] = useState([]);
    const triggerRef = useRef(null);
    const [portalContainer, setPortalContainer] = useState(null);
    useEffect(() => {
        if (!open)
            return;
        const trimmed = query.trim();
        if (trimmed.length < MIN_QUERY_LENGTH) {
            setResults([]);
            return;
        }
        let cancelled = false;
        const handle = window.setTimeout(async () => {
            setLoading(true);
            try {
                const next = await searchAgentPrincipals(trimmed, "all", 20);
                if (!cancelled)
                    setResults(next);
            }
            catch {
                if (!cancelled)
                    setResults([]);
            }
            finally {
                if (!cancelled)
                    setLoading(false);
            }
        }, 250);
        return () => {
            cancelled = true;
            window.clearTimeout(handle);
        };
    }, [open, query]);
    const grouped = useMemo(() => {
        const users = results.filter((r) => r.principalType === "User");
        const roles = results.filter((r) => r.principalType === "Role");
        return { users, roles };
    }, [results]);
    const buttonLabel = value
        ? `${value.displayName} (${value.principalType === "Role" ? "Role" : "User"})`
        : "Select user or role";
    const canSearch = query.trim().length >= MIN_QUERY_LENGTH;
    return (_jsxs(Popover, { open: open, onOpenChange: (next) => {
            if (next && triggerRef.current) {
                const dialogContent = triggerRef.current.closest('[data-slot="dialog-content"]');
                setPortalContainer(dialogContent);
            }
            setOpen(next);
        }, enableIframeClickDetection: false, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { ref: triggerRef, size: "xs", variant: "outline", className: "h-6 w-full min-w-0 justify-start rounded border px-1.5 text-[11px] text-gray-600", disabled: disabled, "data-testid": "agent-sharing-principal-picker", children: [_jsx(UserRound, { className: "mr-1 h-3 w-3 opacity-70", strokeWidth: 1.5 }), _jsx("span", { className: "min-w-0 flex-1 truncate text-left", children: buttonLabel }), _jsx(ChevronDown, { className: "ml-auto h-3 w-3 opacity-60" })] }) }), _jsx(PopoverContent, { className: "w-[300px] p-0", align: "start", container: portalContainer, onMouseDown: (e) => e.stopPropagation(), onClick: (e) => e.stopPropagation(), children: _jsxs(Command, { shouldFilter: false, children: [_jsx(CommandInput, { value: query, onValueChange: setQuery, placeholder: "Search users or roles...", className: "h-8 text-xs", autoFocus: true }), _jsxs(CommandList, { className: "max-h-64", children: [!canSearch && (_jsx(CommandGroup, { children: _jsxs(CommandItem, { disabled: true, className: "text-muted-foreground", children: ["Type at least ", MIN_QUERY_LENGTH, " characters"] }) })), canSearch && loading && (_jsx(CommandGroup, { children: _jsxs(CommandItem, { disabled: true, children: [_jsx(Loader2, { className: "h-3 w-3 animate-spin" }), _jsx("span", { children: "Searching..." })] }) })), canSearch && !loading && grouped.users.length > 0 && (_jsx(CommandGroup, { heading: "Users", children: grouped.users.map((u) => (_jsxs(CommandItem, { value: `user-${u.identifier}`, onSelect: () => {
                                            onChange(u);
                                            setOpen(false);
                                        }, children: [_jsx(UserRound, { className: "h-3 w-3", strokeWidth: 1.5 }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "truncate", children: u.displayName }), _jsxs("div", { className: "truncate text-[10px] text-muted-foreground", children: [u.identifier, u.email ? ` • ${u.email}` : ""] })] })] }, `user-${u.identifier}`))) })), canSearch && !loading && grouped.roles.length > 0 && (_jsx(CommandGroup, { heading: "Roles", children: grouped.roles.map((r) => (_jsxs(CommandItem, { value: `role-${r.identifier}`, onSelect: () => {
                                            onChange(r);
                                            setOpen(false);
                                        }, children: [_jsx(UsersIcon, { className: "h-3 w-3", strokeWidth: 1.5 }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "truncate", children: r.displayName }), _jsx("div", { className: "truncate text-[10px] text-muted-foreground", children: r.identifier })] })] }, `role-${r.identifier}`))) })), canSearch && !loading && results.length === 0 ? (_jsx(CommandEmpty, { children: "No matches" })) : null] })] }) })] }));
}
//# sourceMappingURL=AgentSharingSection.js.map