import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { diffWords, diffChars } from "diff";
function stripHtml(html) {
    const temp = document.createElement("div");
    temp.innerHTML = html;
    return temp.textContent || temp.innerText || "";
}
/**
 * Clips a long string by preserving the first and last `contextChars` characters,
 * inserting an ellipsis in between.
 */
function clipPartValue(value, contextChars) {
    const prefix = value.substring(0, contextChars);
    const suffix = value.substring(value.length - contextChars);
    return `${prefix}…${suffix}`;
}
export const DiffView = ({ oldText, newText, useWordDiff = true, ignoreFormatting = false, clipUnchanged = false, clipThreshold = 50, clipContext = 10, }) => {
    // Normalize text if styling should be ignored.
    const normalizedOldText = ignoreFormatting ? stripHtml(oldText) : oldText;
    const normalizedNewText = ignoreFormatting ? stripHtml(newText) : newText;
    // Choose diffing algorithm.
    const diff = useWordDiff
        ? diffWords(normalizedOldText, normalizedNewText)
        : diffChars(normalizedOldText, normalizedNewText);
    // Heuristic: if the diff results in just one removed and one added segment,
    // assume a full replacement and show both values in full.
    if (diff.length === 2 &&
        diff[0]?.removed &&
        diff[1]?.added &&
        diff[0]?.value.trim().length > 0 &&
        diff[1]?.value.trim().length > 0) {
        return (_jsxs("div", { className: "flex flex-col gap-4 font-mono text-xs [overflow-wrap:anywhere] break-words", children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsxs("div", { className: "text-feedback-red flex items-center gap-1.5 text-[10px] font-bold tracking-wider", children: [_jsx("span", { className: "bg-feedback-red h-1.5 w-1.5 rounded-full" }), "Removed"] }), _jsx("div", { className: "bg-feedback-red-light/50 text-feedback-red decoration-feedback-red/50 rounded-md p-2 line-through", children: normalizedOldText })] }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsxs("div", { className: "text-feedback-green flex items-center gap-1.5 text-[10px] font-bold tracking-wider", children: [_jsx("span", { className: "bg-feedback-green h-1.5 w-1.5 rounded-full" }), "Added"] }), _jsx("div", { className: "bg-feedback-green-light/50 text-feedback-green rounded-md p-2", children: normalizedNewText })] })] }));
    }
    return (_jsx("div", { className: "font-mono text-xs leading-relaxed [overflow-wrap:anywhere] break-words", children: diff.map((part, index) => {
            if (part.added) {
                return (_jsx("span", { className: "bg-feedback-green-light/50 text-feedback-green rounded-sm px-0.5", children: part.value }, index));
            }
            if (part.removed) {
                return (_jsx("span", { className: "bg-feedback-red-light/50 text-feedback-red decoration-feedback-red/50 rounded-sm px-0.5 line-through", children: part.value }, index));
            }
            // For unchanged segments, if clipping is enabled and the segment is too long,
            // show part of it before and after an ellipsis.
            let displayValue = part.value;
            if (clipUnchanged && part.value.length > clipThreshold) {
                displayValue = clipPartValue(part.value, clipContext);
            }
            return (_jsx("span", { className: "text-neutral-grey-50", children: displayValue }, index));
        }) }));
};
//# sourceMappingURL=DiffView.js.map