import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { getFieldHistory } from "../editor/services/editService";
import { useEffect, useState } from "react";
import { useEditContext } from "./client/editContext";
import { formatDate } from "./utils";
import { SimpleTable } from "./ui/SimpleTable";
import { Brush, GalleryVertical, History, Undo2, User, Layers, ArrowRight, } from "lucide-react";
import { Checkbox } from "../components/ui/checkbox";
import { CloseButton } from "../components/ui/close-button";
import { cn } from "../lib/utils";
import { DiffView } from "./reviews/DiffView";
import { Tooltip, TooltipContent, TooltipTrigger, } from "../components/ui/tooltip";
import { getFieldTypeConfiguration } from "./fieldTypeConfiguration";
function isTextLikeFieldType(type) {
    const normalizedType = type.toLowerCase();
    return (normalizedType === "raw" ||
        normalizedType === "single-line text" ||
        normalizedType === "multi-line text" ||
        normalizedType === "memo" ||
        normalizedType === "rich text");
}
function fieldHistoryEntriesEqual(a, b) {
    return (a.date === b.date &&
        a.version === b.version &&
        a.rawValue === b.rawValue &&
        a.user === b.user &&
        a.agentId === b.agentId &&
        a.isBaseline === b.isBaseline &&
        a.ai === b.ai &&
        a.undone === b.undone);
}
function isCurrentHistoryEntry(item, fieldHistory) {
    if (item.isBaseline) {
        return false;
    }
    const latestEntry = fieldHistory.find((entry) => !entry.isBaseline) ?? fieldHistory[0];
    return latestEntry ? fieldHistoryEntriesEqual(item, latestEntry) : false;
}
function areAdjacentInItemHistory(newerEntry, olderEntry) {
    if (newerEntry.itemHistoryIndex == null ||
        olderEntry.itemHistoryIndex == null) {
        return false;
    }
    return olderEntry.itemHistoryIndex === newerEntry.itemHistoryIndex + 1;
}
export function FieldHistory({ field, onRevert, onClose, configuration, showRawValue: initialShowRawValue, }) {
    const [fieldHistory, setFieldHistory] = useState([]);
    const [selectedEntry, setSelectedEntry] = useState();
    const [showRawValue, setShowRawValue] = useState(initialShowRawValue);
    const [viewMode, setViewMode] = useState("plain");
    const [ignoreFormatting, setIgnoreFormatting] = useState(false);
    const [clipUnchanged, setClipUnchanged] = useState(true);
    const editContext = useEditContext();
    if (!editContext) {
        return null;
    }
    useEffect(() => {
        getFieldHistory(field.descriptor.item, field.id).then((result) => {
            const items = result.data ?? [];
            // Collapse rapid successive edits (e.g. typing) into a single row for stability.
            const sorted = [...items].sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
            const collapsed = [];
            const WINDOW_MS = 60_000;
            for (const entry of sorted) {
                const last = collapsed[collapsed.length - 1];
                if (!last) {
                    collapsed.push(entry);
                    continue;
                }
                const sameUser = last.user === entry.user &&
                    last.agentId === entry.agentId &&
                    last.isBaseline === entry.isBaseline &&
                    last.ai === entry.ai &&
                    last.version === entry.version &&
                    last.undone === entry.undone;
                const closeInTime = Math.abs(new Date(last.date).getTime() - new Date(entry.date).getTime()) < WINDOW_MS;
                const adjacentInItemHistory = areAdjacentInItemHistory(last, entry);
                if (sameUser && closeInTime && adjacentInItemHistory) {
                    continue;
                }
                collapsed.push(entry);
            }
            setFieldHistory(collapsed);
            setSelectedEntry(collapsed[0]);
        });
    }, [field]);
    const effectiveFieldType = showRawValue ? "raw" : field.type;
    const isTextLike = isTextLikeFieldType(effectiveFieldType);
    const getHistoryEntryUserLabel = (entry) => {
        if (entry.isBaseline) {
            return "Previous value";
        }
        if (entry.agentId) {
            return entry.agentId;
        }
        return entry.user;
    };
    const renderFieldEditor = () => {
        if (!selectedEntry)
            return null;
        const previewKey = `${selectedEntry.date}:${selectedEntry.version}:${selectedEntry.isBaseline ? "baseline" : "entry"}`;
        const displayField = {
            ...field,
            value: selectedEntry.value,
            rawValue: selectedEntry.rawValue,
            isHistoric: true,
        };
        const fieldType = showRawValue ? "raw" : field.type;
        const typeConfig = getFieldTypeConfiguration(configuration, fieldType) ??
            configuration.fieldTypes["single-line text"];
        if (!typeConfig)
            return null;
        const currentRaw = field.rawValue ?? "";
        const historicRaw = selectedEntry.rawValue ?? "";
        return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsxs("div", { className: "mb-3 flex shrink-0 items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "bg-neutral-grey-10/60 rounded-md p-1.5", children: _jsx(History, { strokeWidth: 1, size: 14, className: "text-neutral-grey-100" }) }), _jsx("span", { className: "text-neutral-grey-100 text-xs font-medium", children: "Historic Value Preview" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [isTextLike && (_jsxs("div", { className: "bg-neutral-grey-5 flex items-center rounded-lg p-0.5", children: [_jsx("button", { onClick: () => setViewMode("plain"), className: cn("badge-pad rounded-md text-[10px] font-medium transition-all", viewMode === "plain"
                                                ? "text-neutral-grey-100 bg-white shadow-sm"
                                                : "text-neutral-grey-50 hover:text-neutral-grey-100"), children: "Plain" }), _jsx("button", { onClick: () => setViewMode("diff"), className: cn("badge-pad rounded-md text-[10px] font-medium transition-all", viewMode === "diff"
                                                ? "text-neutral-grey-100 bg-white shadow-sm"
                                                : "text-neutral-grey-50 hover:text-neutral-grey-100"), children: "Diff" })] })), _jsxs("div", { className: "ml-1 flex items-center gap-1.5 border-l pl-3", children: [_jsx(Checkbox, { id: "show-raw", className: "border-border-default data-[state=checked]:border-neutral-grey-100 data-[state=checked]:bg-neutral-grey-100 size-3.5 data-[state=checked]:text-white", checked: showRawValue, onCheckedChange: (checked) => setShowRawValue(!!checked) }), _jsx("label", { htmlFor: "show-raw", className: "text-neutral-grey-50 hover:text-neutral-grey-100 cursor-pointer text-[10px] font-medium select-none", children: "Raw" })] })] })] }), _jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: viewMode === "diff" && isTextLike ? (_jsxs("div", { className: "flex h-full flex-col gap-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { onClick: () => setIgnoreFormatting((prev) => !prev), className: cn("rounded-md border p-1.5 transition-all", ignoreFormatting
                                                        ? "border-neutral-grey-100/20 bg-neutral-grey-10/60 text-neutral-grey-100"
                                                        : "border-border-default text-neutral-grey-50 hover:border-border-default hover:text-neutral-grey-50 bg-white"), children: _jsx(Brush, { size: 14, strokeWidth: 1 }) }) }), _jsx(TooltipContent, { children: "Ignore Formatting" })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { onClick: () => setClipUnchanged((prev) => !prev), className: cn("rounded-md border p-1.5 transition-all", clipUnchanged
                                                        ? "border-neutral-grey-100/20 bg-neutral-grey-10/60 text-neutral-grey-100"
                                                        : "border-border-default text-neutral-grey-50 hover:border-border-default hover:text-neutral-grey-50 bg-white"), children: _jsx(GalleryVertical, { size: 14, strokeWidth: 1 }) }) }), _jsx(TooltipContent, { children: "Clip Unchanged" })] })] }), _jsxs("div", { className: "border-border-default bg-neutral-grey-5/50 min-h-0 flex-1 overflow-auto rounded-xl border p-4", children: [_jsxs("div", { className: "mb-3 flex items-center gap-2", children: [_jsx("span", { className: "text-neutral-grey-50 text-[10px] font-bold tracking-wider", children: "Current" }), _jsx(ArrowRight, { strokeWidth: 1, size: 10, className: "text-neutral-grey-50" }), _jsx("span", { className: "text-neutral-grey-100 text-[10px] font-bold tracking-wider", children: "Historic snapshot" })] }), _jsx("div", { className: "font-mono text-xs leading-relaxed", children: _jsx(DiffView, { oldText: currentRaw, newText: historicRaw, ignoreFormatting: ignoreFormatting, clipUnchanged: clipUnchanged, clipThreshold: 50, clipContext: 10 }) })] })] })) : (_jsx("div", { className: "border-border-default min-h-0 flex-1 overflow-auto rounded-xl border bg-white p-4 shadow-sm", children: _jsx(typeConfig.editor, { field: displayField, readOnly: true, isFocusedField: false, updateFieldValue: () => { }, tabIndex: undefined }, previewKey) })) })] }));
    };
    if (fieldHistory.length === 0)
        return (_jsx("div", { "data-testid": "field-history", className: "bg-neutral-grey-5/30 border-border-default flex h-[500px] items-center justify-center rounded-xl border border-dashed", children: _jsxs("div", { className: "flex flex-col items-center gap-2", children: [_jsx(History, { strokeWidth: 1, size: 32, className: "text-neutral-grey-50" }), _jsx("div", { className: "text-neutral-grey-50 text-sm font-medium", children: "No history available" })] }) }));
    return (_jsxs("div", { "data-testid": "field-history", className: "flex h-[600px] flex-col bg-white", children: [_jsxs("div", { className: "border-border-default flex shrink-0 items-center justify-between border-b px-4 py-3", children: [_jsxs("div", { className: "flex items-center gap-2.5", children: [_jsx("div", { className: "bg-neutral-grey-100 shadow-neutral-grey-100/10 rounded-lg p-1.5 shadow-sm", children: _jsx(History, { strokeWidth: 1, size: 16, className: "text-white" }) }), _jsxs("div", { children: [_jsx("h3", { className: "text-neutral-grey-100 mb-1 text-sm leading-none font-bold", children: "Field History" }), _jsx("p", { className: "text-neutral-grey-50 text-[10px] font-medium", children: field.displayName || field.name || "Unknown Field" })] })] }), onClose && _jsx(CloseButton, { onClick: onClose })] }), _jsxs("div", { className: "flex min-h-0 flex-1", children: [_jsx("div", { className: "border-border-default flex w-[45%] min-w-0 flex-col border-r", children: _jsx("div", { className: "min-h-0 flex-1 overflow-auto", children: _jsx(SimpleTable, { items: fieldHistory, onRowClick: ({ item }) => setSelectedEntry(item), "data-testid": "field-history-table", rowClassName: (x) => cn("group transition-colors", x.undone ? "opacity-40" : "", selectedEntry && fieldHistoryEntriesEqual(x, selectedEntry)
                                    ? "bg-neutral-grey-10/60"
                                    : "hover:bg-neutral-grey-5/80"), columns: [
                                    {
                                        header: (_jsx("span", { className: "text-neutral-grey-50 px-2 text-[10px] font-bold tracking-wider", children: "Entry" })),
                                        body: (x) => (_jsxs("div", { className: "badge-pad flex flex-col gap-1", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "text-neutral-grey-100 text-xs font-medium", children: formatDate(new Date(x.date)) }), isCurrentHistoryEntry(x, fieldHistory) && (_jsx("span", { className: "badge-pad-sm bg-feedback-green-light text-feedback-green rounded-full text-[9px] font-bold", children: "Current" }))] }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("div", { className: "text-neutral-grey-50 flex items-center gap-1 text-[10px]", children: [_jsx(User, { strokeWidth: 1, size: 10, className: "text-neutral-grey-50" }), _jsx("span", { children: getHistoryEntryUserLabel(x) })] }), _jsxs("div", { className: "text-neutral-grey-50 flex items-center gap-1 text-[10px]", children: [_jsx(Layers, { strokeWidth: 1, size: 10, className: "text-neutral-grey-50" }), _jsxs("span", { children: ["v", x.version] })] })] })] })),
                                    },
                                    {
                                        header: (_jsx("span", { className: "text-neutral-grey-50 block text-center text-[10px] font-bold tracking-wider", children: "Action" })),
                                        className: "w-16 text-center",
                                        body: (x) => !isCurrentHistoryEntry(x, fieldHistory) && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-label": "Revert", onClick: async (ev) => {
                                                            ev.stopPropagation();
                                                            await editContext.operations.editField({
                                                                field: field.descriptor,
                                                                rawValue: x.rawValue,
                                                                refresh: "immediate",
                                                            });
                                                            onRevert?.();
                                                        }, className: "text-neutral-grey-50 hover:bg-neutral-grey-5 hover:text-neutral-grey-100 rounded-full p-2 transition-all", children: _jsx(Undo2, { strokeWidth: 1, size: 16 }) }) }), _jsx(TooltipContent, { children: "Revert to this version" })] })),
                                    },
                                ] }) }) }), _jsx("div", { className: "bg-neutral-grey-5/30 flex min-w-0 flex-1 flex-col p-4", children: renderFieldEditor() })] })] }));
}
//# sourceMappingURL=FieldHistory.js.map