import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useMemo, useState } from "react";
import { Avatar } from "../../components/ui/avatar";
import { Button } from "../../components/ui/button";
import { Popover, PopoverContent, PopoverTrigger, } from "../../components/ui/popover";
import { Select } from "../../components/ui/select";
import { cn } from "../../lib/utils";
import { Check, Loader2, Plus, X } from "lucide-react";
import { useEditContext } from "../client/editContext";
import { ItemTreeSelector } from "./ItemTreeSelector";
const reviewerAvatarClasses = [
    "bg-feedback-blue text-white",
    "bg-feedback-orange text-white",
    "bg-highlight-100 text-white",
    "bg-feedback-green text-white",
    "bg-feedback-red text-white",
];
function getReviewerAvatarClassName(index) {
    return reviewerAvatarClasses[index];
}
export function ReviewItemsPanel({ review, items, assignments, onMakeDecision, loading, onSetFinalDecision, onAddPages, allReviewersResponded, selectedReviewerId, onSelectReviewer, currentUserEmail, requiredApprovals = 1, }) {
    const editContext = useEditContext();
    const isLimitedPreviewUser = editContext?.user?.isLimitedPreviewUser ?? false;
    const [filter, setFilter] = useState("all");
    const [isAddPopoverOpen, setIsAddPopoverOpen] = useState(false);
    const [selectedItems, setSelectedItems] = useState([]);
    const approvalThreshold = Math.max(requiredApprovals, 1);
    const displayAssignments = useMemo(() => {
        let filtered = assignments;
        if (isLimitedPreviewUser && currentUserEmail) {
            filtered = filtered.filter((assignment) => assignment.reviewerEmail.toLowerCase() ===
                currentUserEmail.toLowerCase());
        }
        if (selectedReviewerId) {
            filtered = filtered.filter((assignment) => assignment.assignmentId === selectedReviewerId);
        }
        return filtered;
    }, [assignments, currentUserEmail, isLimitedPreviewUser, selectedReviewerId]);
    const userAssignment = assignments.find((assignment) => currentUserEmail &&
        assignment.reviewerEmail.toLowerCase() === currentUserEmail.toLowerCase());
    const getDecision = (assignment, item) => assignment.decisions?.find((decision) => decision.itemId === item.itemId &&
        decision.itemLanguage === item.language);
    const getApprovalCount = (item) => assignments.filter((assignment) => getDecision(assignment, item)?.decision === "Approved").length;
    const getItemStatus = (item) => {
        const approvalCount = getApprovalCount(item);
        const rejectionCount = assignments.filter((assignment) => getDecision(assignment, item)?.decision === "Rejected").length;
        const pendingCount = assignments.length - approvalCount - rejectionCount;
        if (approvalCount >= approvalThreshold)
            return "approved";
        if (approvalCount + pendingCount < approvalThreshold)
            return "rejected";
        return "pending";
    };
    const filteredItems = items.filter((item) => filter === "all" || getItemStatus(item) === filter);
    const handleAddSelectedPages = async () => {
        if (selectedItems.length === 0)
            return;
        await onAddPages(selectedItems.map((descriptor) => ({
            descriptor,
            includeSubitems: false,
        })));
        setSelectedItems([]);
        setIsAddPopoverOpen(false);
    };
    const handleMakeDecision = async (assignment, item, decision) => {
        let itemVersion;
        const currentItem = editContext?.currentItemDescriptor;
        if (currentItem?.id === item.itemId &&
            (currentItem.language === item.language || item.language === "*") &&
            currentItem.version !== 0) {
            itemVersion = currentItem.version;
        }
        await onMakeDecision(assignment.assignmentId, item.itemId, item.language, itemVersion, decision);
    };
    const handleLoadItem = (item) => {
        editContext?.loadItem?.({
            id: item.itemId,
            language: item.language === "*"
                ? editContext.currentItemDescriptor?.language || "en"
                : item.language,
            version: 0,
        });
    };
    return (_jsxs("div", { className: "flex flex-col gap-2.5", "data-testid": "review-items-panel", children: [!isLimitedPreviewUser && (_jsx("div", { className: "flex items-center gap-2", children: _jsxs(Popover, { open: isAddPopoverOpen, onOpenChange: setIsAddPopoverOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", size: "lg", className: "h-10 flex-1 rounded-[4px] text-xs font-medium focus-visible:ring-0", "data-testid": "add-pages-button", children: ["Add item to be reviewed", _jsx(Plus, { className: "h-5 w-5", strokeWidth: 1 })] }) }), _jsx(PopoverContent, { className: "m-2 w-[min(600px,calc(100vw-32px))] p-0", align: "start", "data-testid": "page-selector-popover", children: _jsxs("div", { className: "flex flex-col gap-2 p-3", children: [_jsx("div", { className: "text-sm font-medium", children: "Select pages" }), _jsx(ItemTreeSelector, { selectedItems: selectedItems, onItemsChange: setSelectedItems, language: review.language, height: "350px" }), _jsxs("div", { className: "border-border-default flex justify-end gap-2 border-t pt-2", children: [_jsx(Button, { variant: "outline", size: "sm", onClick: () => {
                                                    setSelectedItems([]);
                                                    setIsAddPopoverOpen(false);
                                                }, children: "Cancel" }), _jsxs(Button, { size: "sm", onClick: handleAddSelectedPages, disabled: selectedItems.length === 0 || loading, children: [_jsx(Plus, { strokeWidth: 1 }), "Add ", selectedItems.length || "", " item", selectedItems.length === 1 ? "" : "s"] })] })] }) })] }) })), _jsxs("div", { className: "grid grid-cols-2 gap-2", children: [_jsx(Select, { value: filter, onValueChange: (value) => setFilter(value), options: [
                            { value: "all", label: "All status" },
                            { value: "pending", label: "In progress" },
                            { value: "approved", label: "Approved" },
                            { value: "rejected", label: "Rejected" },
                        ], className: "h-8 rounded-lg px-3", "data-testid": "review-items-status-filter" }), _jsx(Select, { value: selectedReviewerId || "all", onValueChange: (value) => onSelectReviewer(value === "all" ? null : value), options: [
                            { value: "all", label: "All reviewers" },
                            ...assignments.map((assignment) => ({
                                value: assignment.assignmentId,
                                label: assignment.reviewerName || assignment.reviewerEmail,
                            })),
                        ], className: "h-8 rounded-lg px-3", disabled: isLimitedPreviewUser, "data-testid": "review-items-reviewer-filter" })] }), allReviewersResponded &&
                !review.finalDecision &&
                !isLimitedPreviewUser && (_jsxs("div", { className: "bg-neutral-grey-5 flex items-center justify-between gap-2 rounded-lg p-2", children: [_jsx("span", { className: "text-neutral-grey-50 text-[11px]", children: "All reviewers responded" }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsxs(Button, { variant: "ghost", size: "xs", className: "text-feedback-green hover:bg-feedback-green-light", onClick: () => onSetFinalDecision("Approved"), children: [_jsx(Check, { strokeWidth: 1 }), " Approve"] }), _jsxs(Button, { variant: "ghost", size: "xs", className: "text-feedback-red hover:bg-feedback-red-light", onClick: () => onSetFinalDecision("Rejected"), children: [_jsx(X, { strokeWidth: 1 }), " Reject"] })] })] })), filteredItems.length === 0 ? (_jsx("div", { className: "text-neutral-grey-50 py-5 text-center text-xs", children: "No review items match these filters" })) : (_jsx("div", { className: "divide-border-default divide-y", children: filteredItems.map((item) => {
                    const approvalCount = getApprovalCount(item);
                    const status = getItemStatus(item);
                    const itemKey = `${item.itemId}:${item.language}`;
                    const itemMissing = !item.name && !item.path;
                    const isCurrentItem = editContext?.currentItemDescriptor?.id === item.itemId &&
                        (item.language === "*" ||
                            editContext.currentItemDescriptor.language === item.language);
                    const commentCount = item.commentsCount ?? 0;
                    const suggestionCount = item.suggestionsCount ?? 0;
                    const assignmentsWithDecisions = displayAssignments.filter((assignment) => !!getDecision(assignment, item));
                    const visibleAssignments = assignmentsWithDecisions.slice(0, 3);
                    const remainingAssignments = Math.max(assignmentsWithDecisions.length - visibleAssignments.length, 0);
                    const currentUserDecision = userAssignment
                        ? getDecision(userAssignment, item)
                        : undefined;
                    return (_jsxs("div", { className: cn("group flex items-center gap-2 px-2 py-3 transition-colors", itemMissing
                            ? "cursor-not-allowed"
                            : "hover:bg-neutral-grey-5 cursor-pointer", isCurrentItem && "bg-neutral-grey-5"), onClick: () => {
                            if (!itemMissing)
                                handleLoadItem(item);
                        }, "aria-disabled": itemMissing, title: itemMissing ? "This item no longer exists" : undefined, "data-testid": `review-item-row-${item.itemId}-${item.language}`, children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "text-neutral-grey-100 truncate text-xs font-medium", children: [item.name || item.path || item.itemId, " (", item.language, ")"] }), itemMissing ? (_jsx("div", { className: "text-feedback-red mt-0.5 text-xs", children: "Item no longer exists" })) : (_jsxs("div", { className: cn("mt-0.5 text-xs", status === "approved"
                                            ? "text-feedback-green"
                                            : status === "rejected"
                                                ? "text-feedback-red"
                                                : "text-neutral-grey-50"), children: [approvalCount, "/", approvalThreshold, " approvals", item.includeSubitems && " · includes subitems"] }))] }), _jsxs("div", { className: "flex shrink-0 flex-col items-end gap-1", children: [_jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex -space-x-1.5", children: visibleAssignments.map((assignment) => {
                                                    const decision = getDecision(assignment, item);
                                                    const displayName = assignment.reviewerName ||
                                                        assignment.reviewerEmail ||
                                                        "Reviewer";
                                                    const assignmentIndex = Math.max(assignments.findIndex((candidate) => candidate.assignmentId ===
                                                        assignment.assignmentId), 0);
                                                    return (_jsxs("div", { className: "relative", title: `${displayName}: ${decision?.decision || "Pending"}`, children: [_jsx(Avatar, { name: displayName, fallbackClassName: getReviewerAvatarClassName(assignmentIndex % reviewerAvatarClasses.length), bordered: true, className: "size-7 text-[10px]" }), decision && (_jsx("span", { className: cn("absolute -right-0.5 -bottom-0.5 grid size-3.5 place-items-center rounded-full border border-white text-white", decision.decision === "Approved"
                                                                    ? "bg-feedback-green"
                                                                    : "bg-feedback-red"), children: decision.decision === "Approved" ? (_jsx(Check, { className: "size-2.5", strokeWidth: 1 })) : (_jsx(X, { className: "size-2.5", strokeWidth: 1 })) }))] }, assignment.assignmentId));
                                                }) }), remainingAssignments > 0 && (_jsxs("span", { className: "text-neutral-grey-50 ml-1 text-[10px]", children: ["+", remainingAssignments] }))] }), (commentCount > 0 || suggestionCount > 0) && (_jsxs("div", { className: "text-neutral-grey-50 flex items-center gap-2 text-[11px]", children: [commentCount > 0 && (_jsxs("span", { children: [commentCount, " comment", commentCount === 1 ? "" : "s"] })), commentCount > 0 && suggestionCount > 0 && (_jsx("span", { className: "bg-neutral-grey-50 size-1 shrink-0 rounded-full", "aria-hidden": "true", "data-testid": "feedback-count-divider" })), suggestionCount > 0 && (_jsxs("span", { children: [suggestionCount, " suggestion", suggestionCount === 1 ? "" : "s"] }))] })), userAssignment && (_jsxs("div", { className: "flex items-center gap-1", onClick: (event) => event.stopPropagation(), children: [_jsx(Button, { variant: "ghost", size: "iconXs", className: cn("border-border-default bg-neutral-grey-5 text-neutral-grey-100 hover:bg-neutral-grey-10 hover:text-neutral-grey-100 border", currentUserDecision?.decision === "Approved" &&
                                                    "border-feedback-green bg-feedback-green-light text-feedback-green hover:bg-feedback-green-light hover:text-feedback-green"), onClick: () => handleMakeDecision(userAssignment, item, "Approved"), disabled: loading, title: "Approve this item", children: _jsx(Check, { strokeWidth: 1 }) }), _jsx(Button, { variant: "ghost", size: "iconXs", className: cn("border-border-default bg-neutral-grey-5 text-neutral-grey-100 hover:bg-neutral-grey-10 hover:text-neutral-grey-100 border", currentUserDecision?.decision === "Rejected" &&
                                                    "border-feedback-red bg-feedback-red-light text-feedback-red hover:bg-feedback-red-light hover:text-feedback-red"), onClick: () => handleMakeDecision(userAssignment, item, "Rejected"), disabled: loading, title: "Reject this item", children: _jsx(X, { strokeWidth: 1 }) })] }))] })] }, itemKey));
                }) })), loading && (_jsxs("div", { className: "text-neutral-grey-50 flex items-center justify-center gap-2 py-2 text-[11px]", children: [_jsx(Loader2, { strokeWidth: 1, className: "h-3.5 w-3.5 animate-spin" }), "Updating review"] }))] }));
}
//# sourceMappingURL=ReviewItemsPanel.js.map