import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useState } from "react";
import { Avatar } from "../../components/ui/avatar";
import { Button } from "../../components/ui/button";
import { Input } from "../../components/ui/input";
import { Popover, PopoverContent, PopoverTrigger, } from "../../components/ui/popover";
import { cn } from "../../lib/utils";
import { Check, Clock, Loader2, Mail, Plus, Send, X } from "lucide-react";
import { useEditContext } from "../client/editContext";
import { PreconfiguredReviewerSelector } from "./PreconfiguredReviewerSelector";
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 ReviewersPanel({ assignments, onAddReviewer, onRemoveReviewer, onSendInvitations, loading, selectedReviewerId, onSelectReviewer, itemIds = [], language, }) {
    const editContext = useEditContext();
    const isLimitedPreviewUser = editContext?.user?.isLimitedPreviewUser ?? false;
    const currentUserEmail = editContext?.user?.email;
    const displayAssignments = isLimitedPreviewUser && currentUserEmail
        ? assignments.filter((assignment) => assignment.reviewerEmail.toLowerCase() ===
            currentUserEmail.toLowerCase())
        : assignments;
    const [isAddReviewerOpen, setIsAddReviewerOpen] = useState(false);
    const [newReviewer, setNewReviewer] = useState({
        name: "",
        email: "",
    });
    const [showErrors, setShowErrors] = useState(false);
    const [waiting, setWaiting] = useState(false);
    const [sendingInvitations, setSendingInvitations] = useState(new Set());
    const [invitationErrors, setInvitationErrors] = useState(new Map());
    const isValidEmail = (email) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
    const emailAlreadyExists = (email) => assignments.some((assignment) => assignment.reviewerEmail.toLowerCase() === email.toLowerCase());
    const handleAddReviewer = async () => {
        setShowErrors(true);
        if (!newReviewer.name ||
            !newReviewer.email ||
            !isValidEmail(newReviewer.email) ||
            emailAlreadyExists(newReviewer.email)) {
            return;
        }
        setWaiting(true);
        try {
            await onAddReviewer([newReviewer]);
            setNewReviewer({ name: "", email: "" });
            setIsAddReviewerOpen(false);
            setShowErrors(false);
        }
        finally {
            setWaiting(false);
        }
    };
    const handleSendInvitation = async (assignmentId) => {
        setSendingInvitations((current) => new Set(current).add(assignmentId));
        setInvitationErrors((current) => {
            const next = new Map(current);
            next.delete(assignmentId);
            return next;
        });
        try {
            await onSendInvitations([assignmentId]);
        }
        catch (error) {
            let message = error instanceof Error ? error.message : "Failed to send invitation";
            if (error && typeof error === "object" && "assignmentErrors" in error) {
                const assignmentErrors = error.assignmentErrors;
                message = assignmentErrors?.get(assignmentId) || message;
            }
            setInvitationErrors((current) => new Map(current).set(assignmentId, String(message)));
        }
        finally {
            setSendingInvitations((current) => {
                const next = new Set(current);
                next.delete(assignmentId);
                return next;
            });
        }
    };
    const getReviewerStatus = (assignment) => {
        const reviewedItems = new Set(assignment.decisions?.map((decision) => `${decision.itemId}:${decision.itemLanguage}`) ?? []);
        const reviewedCount = reviewedItems.size;
        const totalCount = itemIds.length;
        if (reviewedCount > 0) {
            const hasRejection = assignment.decisions?.some((decision) => decision.decision === "Rejected");
            const allApproved = reviewedCount === totalCount &&
                assignment.decisions?.every((decision) => decision.decision === "Approved");
            if (hasRejection) {
                return {
                    label: `${reviewedCount}/${totalCount}`,
                    className: "bg-feedback-red-light text-feedback-red",
                    icon: X,
                };
            }
            if (allApproved) {
                return {
                    label: `${reviewedCount}/${totalCount}`,
                    className: "bg-feedback-green-light text-feedback-green",
                    icon: Check,
                };
            }
            return {
                label: `${reviewedCount}/${totalCount}`,
                className: "bg-feedback-orange-light text-feedback-orange",
                icon: Clock,
            };
        }
        if (assignment.invitationSentDate) {
            return {
                label: "Invited",
                className: "bg-feedback-blue-light text-feedback-blue",
                icon: undefined,
            };
        }
        return {
            label: "Pending",
            className: "bg-neutral-grey-10 text-neutral-grey-50",
            icon: undefined,
        };
    };
    return (_jsxs("div", { className: "flex flex-col gap-2.5", "data-testid": "reviewers-panel", children: [!isLimitedPreviewUser && (_jsxs(Popover, { open: isAddReviewerOpen, onOpenChange: setIsAddReviewerOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", size: "lg", className: "h-10 w-full rounded-[4px] text-xs font-medium", "data-testid": "add-reviewer-button", children: ["Add reviewer", _jsx(Plus, { className: "h-5 w-5", strokeWidth: 1 })] }) }), _jsx(PopoverContent, { className: "m-2 w-[320px] p-3", align: "start", "data-testid": "add-reviewer-popover", children: _jsxs("div", { className: "flex flex-col gap-3 text-xs", children: [itemIds.length > 0 && language ? (_jsx(PreconfiguredReviewerSelector, { itemIds: itemIds, language: language, onReviewerSelected: async (reviewer) => {
                                        if (!emailAlreadyExists(reviewer.email)) {
                                            await onAddReviewer([reviewer]);
                                            setIsAddReviewerOpen(false);
                                        }
                                    }, existingReviewers: assignments.map((assignment) => ({
                                        name: assignment.reviewerName,
                                        email: assignment.reviewerEmail,
                                    })) })) : (_jsx("div", { className: "text-neutral-grey-50", children: "No predefined reviewers available" })), _jsxs("div", { className: "border-border-default border-t pt-3", children: [_jsx("div", { className: "text-neutral-grey-100 mb-2 font-medium", children: "New reviewer" }), _jsxs("div", { className: "space-y-2", children: [_jsx(Input, { id: "reviewer-name", value: newReviewer.name, onChange: (event) => setNewReviewer((current) => ({
                                                        ...current,
                                                        name: event.target.value,
                                                    })), placeholder: "Name", autoFocus: true }), showErrors && !newReviewer.name && (_jsx("div", { className: "text-feedback-red", children: "Name is required" })), _jsx(Input, { id: "reviewer-email", value: newReviewer.email, onChange: (event) => setNewReviewer((current) => ({
                                                        ...current,
                                                        email: event.target.value,
                                                    })), placeholder: "Email", type: "email" }), showErrors && !isValidEmail(newReviewer.email) && (_jsx("div", { className: "text-feedback-red", children: "Enter a valid email address" })), showErrors && emailAlreadyExists(newReviewer.email) && (_jsx("div", { className: "text-feedback-red", children: "This reviewer is already assigned" }))] })] }), _jsxs(Button, { onClick: handleAddReviewer, disabled: waiting, children: [waiting && (_jsx(Loader2, { strokeWidth: 1, className: "animate-spin" })), "Add reviewer"] })] }) })] })), displayAssignments.length === 0 ? (_jsx("div", { className: "text-neutral-grey-50 py-5 text-center text-xs", children: "No reviewers assigned" })) : (_jsx("div", { className: "space-y-1", children: displayAssignments.map((assignment) => {
                    const displayName = assignment.reviewerName || assignment.reviewerEmail || "Reviewer";
                    const status = getReviewerStatus(assignment);
                    const StatusIcon = status.icon;
                    const isSending = sendingInvitations.has(assignment.assignmentId);
                    const isCurrentUser = currentUserEmail?.toLowerCase() ===
                        assignment.reviewerEmail.toLowerCase();
                    const assignmentIndex = Math.max(assignments.findIndex((candidate) => candidate.assignmentId === assignment.assignmentId), 0);
                    return (_jsxs("div", { children: [_jsxs("div", { className: cn("group flex cursor-pointer items-center gap-2.5 rounded-lg px-0.5 py-1.5 transition-colors", selectedReviewerId === assignment.assignmentId
                                    ? "bg-feedback-blue-light"
                                    : "hover:bg-neutral-grey-5"), onClick: () => onSelectReviewer(selectedReviewerId === assignment.assignmentId
                                    ? null
                                    : assignment.assignmentId), title: assignment.reviewerEmail, "data-testid": `reviewer-row-${assignment.assignmentId}`, children: [_jsx(Avatar, { src: isCurrentUser ? editContext?.user?.avatarUrl : undefined, name: displayName, size: "md", fallbackClassName: getReviewerAvatarClassName(assignmentIndex % reviewerAvatarClasses.length) }), _jsx("span", { className: "text-neutral-grey-100 min-w-0 flex-1 truncate text-xs", children: displayName }), _jsxs("span", { className: cn("inline-flex items-center gap-1 rounded-[5px] px-2 py-1 text-[11px] leading-none font-medium", status.className), children: [StatusIcon && _jsx(StatusIcon, { className: "h-3 w-3" }), status.label] }), !isLimitedPreviewUser && (_jsxs("div", { className: cn("pointer-events-none flex shrink-0 items-center justify-end gap-0.5 opacity-0 transition-opacity group-focus-within:pointer-events-auto group-focus-within:opacity-100 group-hover:pointer-events-auto group-hover:opacity-100", "w-[58px]"), onClick: (event) => event.stopPropagation(), children: [!assignment.invitationSentDate && (_jsx(Button, { variant: "ghost", size: "iconXs", onClick: () => handleSendInvitation(assignment.assignmentId), disabled: loading || isSending, title: "Send invitation", children: isSending ? (_jsx(Loader2, { strokeWidth: 1, className: "animate-spin" })) : (_jsx(Send, { strokeWidth: 1 })) })), _jsx(Button, { variant: "ghost", size: "iconXs", onClick: () => onRemoveReviewer(assignment.assignmentId), disabled: loading, className: "hover:bg-feedback-red-light hover:text-feedback-red", title: "Remove reviewer", children: _jsx(X, { strokeWidth: 1 }) })] }))] }), invitationErrors.has(assignment.assignmentId) && (_jsxs("div", { className: "text-feedback-red px-10 text-[10px]", children: [_jsx(Mail, { strokeWidth: 1, className: "mr-1 inline h-3 w-3" }), invitationErrors.get(assignment.assignmentId)] }))] }, assignment.assignmentId));
                }) }))] }));
}
//# sourceMappingURL=ReviewersPanel.js.map