import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useEffect, useMemo, useState } from "react";
import { useEditContext } from "../client/editContext";
import { Comment as CommentComponent } from "./Comment";
import { SuggestedEditComponent } from "./SuggestedEdit";
import { SimpleToolbar } from "../ui/SimpleToolbar";
import { SimpleIconButton } from "../ui/SimpleIconButton";
import { Button } from "../../components/ui/button";
import { localStorageService } from "../services/localStorageService";
import { Popover, PopoverContent, PopoverTrigger, } from "../../components/ui/popover";
import { Tooltip, TooltipContent, TooltipTrigger, } from "../../components/ui/tooltip";
import { Plus, User, Calendar, FolderTree, ListChecks, } from "lucide-react";
import { ChevronDown, ChevronRight } from "lucide-react";
export function Comments() {
    const editContext = useEditContext();
    const [feedbackItems, setFeedbackItems] = useState([]);
    const [collapsedThreads, setCollapsedThreads] = useState({});
    // Sort state with localStorage persistence
    const [sortField, setSortField] = useState(() => localStorageService.getString("comments.sortField") || "date");
    const [sortDirection, setSortDirection] = useState(() => localStorageService.getString("comments.sortDirection") || "desc");
    // Filter states with localStorage persistence
    const [selectedPersonFilter, setSelectedPersonFilter] = useState(() => localStorageService.getItem("comments.personFilter") || []);
    const availableTags = editContext?.availableCommentTags || [];
    // Derive available authors from comments
    const availableAuthors = useMemo(() => {
        const authors = new Map();
        (editContext?.comments || []).forEach((c) => {
            if (c.author) {
                authors.set(c.author, c.authorDisplayName || c.author);
            }
        });
        return Array.from(authors.entries()).map(([id, name]) => ({ id, name }));
    }, [editContext?.comments]);
    const isSuggestedEdit = (item) => "oldValue" in item && "newValue" in item;
    const repliesByRootId = useMemo(() => {
        // Build lookup for comments by id
        const commentsOnly = feedbackItems.filter((x) => !isSuggestedEdit(x));
        const idToComment = new Map();
        commentsOnly.forEach((c) => idToComment.set(c.id, c));
        const getRootId = (c) => {
            let current = c;
            const seen = new Set();
            while (current && current.parentCommentId) {
                if (seen.has(current.id))
                    break;
                seen.add(current.id);
                const parent = idToComment.get(current.parentCommentId);
                if (!parent)
                    return current.parentCommentId; // parent not loaded; fallback
                current = parent;
            }
            return current?.id;
        };
        const map = new Map();
        commentsOnly.forEach((c) => {
            if (!c.parentCommentId)
                return;
            const rootId = getRootId(c);
            if (!rootId)
                return;
            const arr = map.get(rootId) || [];
            arr.push(c);
            map.set(rootId, arr);
        });
        map.forEach((replies, key) => {
            replies.sort((a, b) => new Date(a.created || "").getTime() - new Date(b.created || "").getTime());
            map.set(key, replies);
        });
        return map;
    }, [feedbackItems]);
    const topLevelFeedbackItems = useMemo(() => feedbackItems.filter((item) => isSuggestedEdit(item) || !item.parentCommentId), [feedbackItems]);
    // Toggle sort - if same field clicked, toggle direction; otherwise switch field
    const handleSort = (field) => {
        if (sortField === field) {
            setSortDirection((prev) => (prev === "asc" ? "desc" : "asc"));
        }
        else {
            setSortField(field);
            setSortDirection("desc");
        }
    };
    useEffect(() => {
        let cancelled = false;
        const load = async () => {
            // Base lists from context
            const mainComments = editContext?.comments || [];
            const suggestedEdits = editContext?.suggestedEdits || [];
            // Combine comments and suggestions
            let filtered = [...mainComments, ...suggestedEdits];
            // Filter resolved comments
            if (!editContext?.showResolvedComments) {
                filtered = filtered.filter((item) => !("isResolved" in item && item.isResolved));
            }
            // Filter by person (author)
            if (selectedPersonFilter.length > 0) {
                filtered = filtered.filter((item) => "author" in item &&
                    item.author &&
                    selectedPersonFilter.includes(item.author));
            }
            // Sort based on selected field and direction
            const multiplier = sortDirection === "asc" ? 1 : -1;
            filtered.sort((a, b) => {
                switch (sortField) {
                    case "date":
                        return (multiplier *
                            (new Date(a.created || "").getTime() -
                                new Date(b.created || "").getTime()));
                    case "structure":
                        // Sort by item path/position in site structure
                        const pathA = "itemName" in a ? a.itemName || "" : "";
                        const pathB = "itemName" in b ? b.itemName || "" : "";
                        return multiplier * pathA.localeCompare(pathB);
                    default:
                        return 0;
                }
            });
            if (!cancelled)
                setFeedbackItems(filtered);
        };
        load();
        return () => {
            cancelled = true;
        };
    }, [
        editContext,
        selectedPersonFilter,
        sortField,
        sortDirection,
    ]);
    // Persist sort states to localStorage
    useEffect(() => {
        localStorageService.setString("comments.sortField", sortField);
    }, [sortField]);
    useEffect(() => {
        localStorageService.setString("comments.sortDirection", sortDirection);
    }, [sortDirection]);
    // Persist filter states to localStorage
    useEffect(() => {
        localStorageService.setItem("comments.personFilter", selectedPersonFilter);
    }, [selectedPersonFilter]);
    return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsxs(SimpleToolbar, { children: [_jsx(SimpleIconButton, { id: "add-comment", icon: _jsx(Plus, { size: 16, strokeWidth: 1, className: "p-0.5" }), label: "Add Comment", onClick: () => {
                            editContext?.addComment();
                        } }), _jsxs("div", { className: "ml-auto flex items-center gap-1", children: [_jsx("span", { className: "text-xs text-gray-500", children: "Filter by:" }), _jsx(SimpleIconButton, { selected: !!editContext?.showResolvedComments, icon: _jsx(ListChecks, { size: 16, strokeWidth: 1, className: "p-0.5" }), label: editContext?.showResolvedComments
                                    ? "Hide Resolved Comments"
                                    : "Show Resolved Comments", onClick: () => {
                                    editContext?.setShowResolvedComments((x) => !x);
                                } }), _jsxs(Tooltip, { delayDuration: 500, children: [_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(TooltipTrigger, { asChild: true, children: _jsx(SimpleIconButton, { showTooltip: false, selected: selectedPersonFilter.length > 0, icon: _jsx(User, { size: 16, strokeWidth: 1, className: "p-0.5" }), label: selectedPersonFilter.length > 0
                                                            ? `People (${selectedPersonFilter.length})`
                                                            : "People", onClick: () => { } }) }) }), _jsxs(PopoverContent, { className: "w-72 p-3", align: "start", children: [_jsx("div", { className: "mb-2 text-xs text-gray-600", children: "Filter by person" }), availableAuthors.length > 0 ? (_jsx("div", { className: "flex flex-wrap gap-2", children: availableAuthors.map((author) => {
                                                            const isSelected = selectedPersonFilter.includes(author.id);
                                                            return (_jsx(Button, { type: "button", size: "sm", variant: isSelected ? "secondary" : "outline", className: "h-6 px-2 text-xs", onClick: () => {
                                                                    setSelectedPersonFilter((prev) => prev.includes(author.id)
                                                                        ? prev.filter((id) => id !== author.id)
                                                                        : [...prev, author.id]);
                                                                }, children: author.name }, author.id));
                                                        }) })) : (_jsx("div", { className: "text-xs text-gray-400", children: "No authors found" })), selectedPersonFilter.length > 0 && (_jsx("div", { className: "mt-3 text-right", children: _jsx(Button, { size: "sm", variant: "ghost", className: "h-6 px-2 text-xs", onClick: () => setSelectedPersonFilter([]), children: "Clear" }) }))] })] }), _jsx(TooltipContent, { children: "Filter by person" })] }), _jsx("div", { className: "mx-2 h-5 w-px bg-gray-300" }), _jsx("span", { className: "text-xs text-gray-500", children: "Sort by:" }), _jsx(SimpleIconButton, { selected: sortField === "structure", icon: _jsx(FolderTree, { size: 16, strokeWidth: 1, className: "p-0.5" }), label: `Structure ${sortField === "structure" ? (sortDirection === "asc" ? "↑" : "↓") : ""}`, onClick: () => handleSort("structure") }), _jsx(SimpleIconButton, { selected: sortField === "date", icon: _jsx(Calendar, { size: 16, strokeWidth: 1, className: "p-0.5" }), label: `Date ${sortField === "date" ? (sortDirection === "asc" ? "↑" : "↓") : ""}`, onClick: () => handleSort("date") })] })] }), _jsx("div", { className: "flex-1 overflow-auto", children: _jsx("div", { className: "h-fill-available p-4", children: topLevelFeedbackItems.map((item) => {
                        if (isSuggestedEdit(item)) {
                            return (_jsx(SuggestedEditComponent, { edit: item }, item.id));
                        }
                        const topLevelComment = item;
                        const replies = repliesByRootId.get(topLevelComment.id) || [];
                        const isCollapsed = !!collapsedThreads[topLevelComment.id];
                        return (_jsxs("div", { children: [_jsx(CommentComponent, { comment: topLevelComment, availableTags: availableTags, rootCommentId: topLevelComment.id }), replies.length > 0 && (_jsxs("div", { className: "ml-6 border-l-2 border-gray-200 pl-3", children: [_jsxs("button", { type: "button", className: "mb-2 flex items-center gap-1 text-left text-xs text-gray-600 hover:text-gray-800", onClick: () => setCollapsedThreads((prev) => ({
                                                ...prev,
                                                [topLevelComment.id]: !prev[topLevelComment.id],
                                            })), children: [isCollapsed ? (_jsx(ChevronRight, { size: 14, strokeWidth: 1 })) : (_jsx(ChevronDown, { size: 14, strokeWidth: 1 })), isCollapsed
                                                    ? `Show replies (${replies.length})`
                                                    : `Hide replies (${replies.length})`] }), !isCollapsed &&
                                            replies.map((reply) => (_jsx(CommentComponent, { comment: reply, availableTags: availableTags, rootCommentId: topLevelComment.id }, reply.id)))] }))] }, topLevelComment.id));
                    }) }) })] }));
}
//# sourceMappingURL=Comments.js.map