import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { CalendarClock, CalendarOff, X } from "lucide-react";
import { useEditContext } from "../client/editContext";
import { Dialog, DialogContent } from "../../components/ui/dialog";
import { Button } from "../../components/ui/button";
import { Input } from "../../components/ui/input";
import { Switch } from "../../components/ui/switch";
import { Badge } from "../../components/ui/badge";
import { StyledDialogTitle } from "../../components/ui/styled-dialog-title";
import DialogButtons from "./DialogButtons";
import { LoadingState } from "./LoadingState";
import { getLanguagesAndVersions } from "../services/contentService";
import { cn } from "../../lib/utils";
const TIMELINE_DAY_MS = 24 * 60 * 60 * 1000;
const MIN_TIMELINE_ZOOM_DAYS = 7;
const DEFAULT_TIMELINE_ZOOM_DAYS = 180;
const MAX_TIMELINE_ZOOM_DAYS = 3650;
const TIMELINE_ZOOM_PRESETS = [
    { label: "2W", days: 14 },
    { label: "1M", days: 30 },
    { label: "5M", days: 150 },
    { label: "1Y", days: 365 },
    { label: "2Y", days: 730 },
    { label: "5Y", days: 1825 },
    { label: "10Y", days: 3650 },
];
const CHART_PAD_X = 8;
const CHART_BAR_Y = 6;
const CHART_BAR_HEIGHT = 14;
const CHART_AXIS_Y = 44;
const CHART_HEIGHT = 64;
function parseSitecoreDate(rawValue) {
    const value = rawValue?.trim();
    if (!value)
        return undefined;
    if (value.match(/^\d{8}T\d{6}Z$/)) {
        const standardISO = value.replace(/(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})Z/, "$1-$2-$3T$4:$5:$6Z");
        const date = new Date(standardISO);
        return isNaN(date.getTime()) ? undefined : date;
    }
    const fallback = new Date(value);
    return isNaN(fallback.getTime()) ? undefined : fallback;
}
function toDateTimeLocalValue(date) {
    if (!date)
        return "";
    const local = new Date(date.getTime() - date.getTimezoneOffset() * 60000);
    return local.toISOString().slice(0, 16);
}
function fromDateTimeLocalValue(value) {
    if (!value)
        return undefined;
    const date = new Date(value);
    return isNaN(date.getTime()) ? undefined : date;
}
function formatDateToCompactISO(date) {
    if (!date)
        return "";
    const year = date.getUTCFullYear().toString();
    const month = (date.getUTCMonth() + 1).toString().padStart(2, "0");
    const day = date.getUTCDate().toString().padStart(2, "0");
    const hours = date.getUTCHours().toString().padStart(2, "0");
    const minutes = date.getUTCMinutes().toString().padStart(2, "0");
    const seconds = date.getUTCSeconds().toString().padStart(2, "0");
    return `${year}${month}${day}T${hours}${minutes}${seconds}Z`;
}
function toTimestamp(value) {
    const date = fromDateTimeLocalValue(value);
    return date ? date.getTime() : undefined;
}
function timestampFromUnknown(value) {
    if (!value)
        return undefined;
    const date = value instanceof Date ? value : new Date(value);
    const timestamp = date.getTime();
    return isNaN(timestamp) ? undefined : timestamp;
}
function updateLabel(value) {
    const timestamp = timestampFromUnknown(value);
    return timestamp !== undefined ? new Date(timestamp).toLocaleString() : "-";
}
function formatTimelineRangeLabel(start, end, includeTime) {
    const options = includeTime
        ? {
            year: "numeric",
            month: "2-digit",
            day: "2-digit",
            hour: "2-digit",
            minute: "2-digit",
        }
        : {
            year: "numeric",
            month: "2-digit",
            day: "2-digit",
        };
    const formatter = new Intl.DateTimeFormat(undefined, options);
    return `${formatter.format(new Date(start))} - ${formatter.format(new Date(end))}`;
}
function getVersionColor(index) {
    const palette = [
        "var(--color-component-suggestions)",
        "var(--color-feedback-blue)",
        "var(--color-component-shared)",
        "var(--color-highlight-100)",
        "var(--color-feedback-green)",
        "var(--color-feedback-orange)",
        "var(--color-component-layout)",
        "var(--color-feedback-red)",
    ];
    return palette[index % palette.length];
}
function getUserInitials(name) {
    const cleaned = name.split("\\").pop()?.trim() ?? "";
    if (!cleaned)
        return "?";
    const parts = cleaned.split(/[\s._-]+/).filter(Boolean);
    const initials = parts.length >= 2 ? `${parts[0][0]}${parts[1][0]}` : cleaned.slice(0, 1);
    return initials.toUpperCase();
}
function pushTimestamp(timestamps, timestamp) {
    if (timestamp !== undefined && Number.isFinite(timestamp)) {
        timestamps.push(timestamp);
    }
}
function getItemStartTimestamp(versionRows) {
    const createdTimestamps = versionRows
        .map((row) => row.createdTs)
        .filter((timestamp) => timestamp !== undefined && Number.isFinite(timestamp));
    return createdTimestamps.length ? Math.min(...createdTimestamps) : undefined;
}
function getRelevantTimelineTimestamps(itemState, versionRows) {
    const timestamps = [];
    pushTimestamp(timestamps, getItemStartTimestamp(versionRows));
    pushTimestamp(timestamps, toTimestamp(itemState.itemPublishFrom));
    pushTimestamp(timestamps, toTimestamp(itemState.itemUnpublishAt));
    versionRows.forEach((row) => {
        pushTimestamp(timestamps, row.createdTs);
        pushTimestamp(timestamps, toTimestamp(row.versionValidFrom));
        pushTimestamp(timestamps, toTimestamp(row.versionValidTo));
    });
    return timestamps;
}
function getInitialTimelineViewport(itemState, versionRows) {
    const now = Date.now();
    const timestamps = getRelevantTimelineTimestamps(itemState, versionRows);
    timestamps.push(now);
    const minTimestamp = Math.min(...timestamps);
    const maxTimestamp = Math.max(...timestamps);
    const spanDays = Math.ceil((maxTimestamp - minTimestamp) / TIMELINE_DAY_MS);
    const zoomDays = Math.max(DEFAULT_TIMELINE_ZOOM_DAYS, Math.min(MAX_TIMELINE_ZOOM_DAYS, Math.ceil(spanDays * 1.2) + 14));
    return {
        centerTs: (minTimestamp + maxTimestamp) / 2,
        zoomDays,
    };
}
function DateTimeField({ icon: Icon, value, onChange, disabled, dimmed, invalid, testId, }) {
    const inputRef = useRef(null);
    return (_jsxs("div", { className: cn("group/field relative transition-opacity", dimmed && !invalid && "opacity-50"), children: [_jsx("button", { type: "button", tabIndex: -1, disabled: disabled, className: "text-muted-foreground hover:text-foreground absolute top-1/2 left-2 z-10 -translate-y-1/2 disabled:pointer-events-none", onClick: () => {
                    try {
                        inputRef.current?.showPicker();
                    }
                    catch {
                        inputRef.current?.focus();
                    }
                }, children: _jsx(Icon, { className: "h-3.5 w-3.5" }) }), _jsx(Input, { "data-testid": testId, ref: inputRef, type: "datetime-local", className: cn("h-8 bg-white pr-6 pl-7 text-xs [&::-webkit-calendar-picker-indicator]:hidden", dimmed && "bg-neutral-grey-5", invalid && "border-feedback-red focus-visible:border-feedback-red"), value: value, disabled: disabled, onChange: (event) => onChange(event.target.value) }), value && !disabled && (_jsx("button", { type: "button", tabIndex: -1, className: "text-muted-foreground hover:text-foreground absolute top-1/2 right-1.5 -translate-y-1/2 opacity-0 transition-opacity group-hover/field:opacity-100", onClick: () => onChange(""), children: _jsx(X, { strokeWidth: 1, className: "h-3 w-3" }) }))] }));
}
function UserCell({ name }) {
    if (!name) {
        return _jsx("span", { className: "text-muted-foreground text-xs", children: "—" });
    }
    return (_jsxs("span", { className: "flex items-center justify-end gap-2", children: [_jsx("span", { className: "text-foreground truncate text-xs", children: name }), _jsx("span", { className: "bg-neutral-grey-50 flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-[10px] font-medium text-white", children: getUserInitials(name) })] }));
}
function TableColumns() {
    return (_jsxs("colgroup", { children: [_jsx("col", { style: { width: 88 } }), _jsx("col", { style: { width: 104 } }), _jsx("col", {}), _jsx("col", {}), _jsx("col", { style: { width: 176 } }), _jsx("col", { style: { width: 160 } })] }));
}
export function PublishRestrictionsDialog({ item, onClose, }) {
    const editContext = useEditContext();
    const editContextRef = useRef(editContext);
    editContextRef.current = editContext;
    const { id: itemId, language: itemLanguage, version: itemVersion, database: itemDatabase, } = item.descriptor;
    const [isLoading, setIsLoading] = useState(true);
    const [isSaving, setIsSaving] = useState(false);
    const [initialItemState, setInitialItemState] = useState({
        itemPublishable: true,
        itemPublishFrom: "",
        itemUnpublishAt: "",
    });
    const [itemState, setItemState] = useState({
        itemPublishable: true,
        itemPublishFrom: "",
        itemUnpublishAt: "",
    });
    const [initialVersionRows, setInitialVersionRows] = useState([]);
    const [versionRows, setVersionRows] = useState([]);
    const [zoomDays, setZoomDays] = useState(DEFAULT_TIMELINE_ZOOM_DAYS);
    const [centerTs, setCenterTs] = useState(() => Date.now());
    const chartContainerRef = useRef(null);
    const [chartWidth, setChartWidth] = useState(900);
    const [chartHover, setChartHover] = useState(null);
    const dragStateRef = useRef(null);
    const [isDraggingChart, setIsDraggingChart] = useState(false);
    useEffect(() => {
        let cancelled = false;
        async function loadData() {
            setIsLoading(true);
            const result = await getLanguagesAndVersions({
                id: itemId,
                language: itemLanguage,
                version: itemVersion,
                database: itemDatabase,
            }, {
                includePublishingRestrictions: true,
            });
            if (cancelled)
                return;
            if (result.type !== "success" || !result.data) {
                editContextRef.current?.showToast?.("Failed to load publishing restrictions.");
                setIsLoading(false);
                return;
            }
            const itemRestrictions = result.data.itemPublishingRestrictions;
            const nextItemState = {
                itemPublishable: !(itemRestrictions?.neverPublish ?? false),
                itemPublishFrom: toDateTimeLocalValue(parseSitecoreDate(itemRestrictions?.publish)),
                itemUnpublishAt: toDateTimeLocalValue(parseSitecoreDate(itemRestrictions?.unpublish)),
                neverPublishFieldId: itemRestrictions?.neverPublishFieldId,
                publishFieldId: itemRestrictions?.publishFieldId,
                unpublishFieldId: itemRestrictions?.unpublishFieldId,
            };
            const rows = (result.data.versions || [])
                .map((v) => ({
                version: v.version,
                createdTs: timestampFromUnknown(v.created) ?? timestampFromUnknown(v.updated),
                updatedLabel: updateLabel(v.updated),
                updatedBy: v.updatedBy || "",
                versionPublishable: !(v.publishingRestrictions?.hideVersion ?? false),
                versionValidFrom: toDateTimeLocalValue(parseSitecoreDate(v.publishingRestrictions?.validFrom)),
                versionValidTo: toDateTimeLocalValue(parseSitecoreDate(v.publishingRestrictions?.validTo)),
                hideVersionFieldId: v.publishingRestrictions?.hideVersionFieldId,
                validFromFieldId: v.publishingRestrictions?.validFromFieldId,
                validToFieldId: v.publishingRestrictions?.validToFieldId,
            }))
                .sort((a, b) => b.version - a.version);
            setInitialItemState(nextItemState);
            setItemState(nextItemState);
            setInitialVersionRows(rows);
            setVersionRows(rows);
            const initialTimelineViewport = getInitialTimelineViewport(nextItemState, rows);
            setCenterTs(initialTimelineViewport.centerTs);
            setZoomDays(initialTimelineViewport.zoomDays);
            setIsLoading(false);
        }
        loadData();
        return () => {
            cancelled = true;
        };
    }, [itemDatabase, itemId, itemLanguage, itemVersion]);
    useEffect(() => {
        const resize = () => {
            if (!chartContainerRef.current)
                return;
            setChartWidth(Math.max(600, chartContainerRef.current.clientWidth));
        };
        resize();
        window.addEventListener("resize", resize);
        return () => window.removeEventListener("resize", resize);
    }, [isLoading]);
    useEffect(() => {
        const chartEl = chartContainerRef.current;
        if (!chartEl)
            return;
        const handleWheel = (event) => {
            if (!event.altKey)
                return;
            event.preventDefault();
            setZoomDays((prev) => {
                const next = event.deltaY > 0 ? prev * 1.15 : prev * 0.85;
                return Math.max(MIN_TIMELINE_ZOOM_DAYS, Math.min(MAX_TIMELINE_ZOOM_DAYS, Math.round(next)));
            });
        };
        chartEl.addEventListener("wheel", handleWheel, { passive: false });
        return () => {
            chartEl.removeEventListener("wheel", handleWheel);
        };
    }, [isLoading]);
    const itemWindowInvalid = useMemo(() => {
        const from = fromDateTimeLocalValue(itemState.itemPublishFrom);
        const to = fromDateTimeLocalValue(itemState.itemUnpublishAt);
        return !!from && !!to && from.getTime() > to.getTime();
    }, [itemState.itemPublishFrom, itemState.itemUnpublishAt]);
    const versionWindowInvalidCount = useMemo(() => {
        return versionRows.filter((row) => {
            const from = fromDateTimeLocalValue(row.versionValidFrom);
            const to = fromDateTimeLocalValue(row.versionValidTo);
            return !!from && !!to && from.getTime() > to.getTime();
        }).length;
    }, [versionRows]);
    const hasItemChanges = useMemo(() => JSON.stringify(itemState) !== JSON.stringify(initialItemState), [initialItemState, itemState]);
    const hasVersionChanges = useMemo(() => JSON.stringify(versionRows) !== JSON.stringify(initialVersionRows), [initialVersionRows, versionRows]);
    const hasChanges = hasItemChanges || hasVersionChanges;
    const itemStartTs = useMemo(() => getItemStartTimestamp(versionRows), [versionRows]);
    const evaluateActiveVersionAt = useCallback((timestamp) => {
        if (itemStartTs !== undefined && timestamp < itemStartTs)
            return 0;
        if (!itemState.itemPublishable)
            return 0;
        const itemFromTs = toTimestamp(itemState.itemPublishFrom);
        const itemToTs = toTimestamp(itemState.itemUnpublishAt);
        if (itemFromTs && timestamp < itemFromTs)
            return 0;
        if (itemToTs && timestamp > itemToTs)
            return 0;
        const activeVersions = versionRows
            .filter((row) => {
            if (!row.versionPublishable)
                return false;
            const fromTs = toTimestamp(row.versionValidFrom);
            const toTs = toTimestamp(row.versionValidTo);
            if (fromTs && timestamp < fromTs)
                return false;
            if (toTs && timestamp > toTs)
                return false;
            return true;
        })
            .map((x) => x.version)
            .sort((a, b) => b - a);
        return activeVersions[0] || 0;
    }, [
        itemStartTs,
        itemState.itemPublishFrom,
        itemState.itemPublishable,
        itemState.itemUnpublishAt,
        versionRows,
    ]);
    const effectiveNowVersion = useMemo(() => evaluateActiveVersionAt(Date.now()), [evaluateActiveVersionAt]);
    const effectiveStatus = useMemo(() => {
        if (!itemState.itemPublishable) {
            return {
                label: "Blocked by item",
                variant: "destructive",
                className: undefined,
            };
        }
        if (effectiveNowVersion === 0) {
            return {
                label: "No publishable version",
                variant: "secondary",
                className: undefined,
            };
        }
        return {
            label: `Will publish v${effectiveNowVersion}`,
            variant: "default",
            className: "bg-feedback-green-light text-feedback-green",
        };
    }, [effectiveNowVersion, itemState.itemPublishable]);
    const timelineModel = useMemo(() => {
        const viewSpanMs = zoomDays * TIMELINE_DAY_MS;
        const viewStart = centerTs - viewSpanMs / 2;
        const viewEnd = centerTs + viewSpanMs / 2;
        const boundaries = new Set([viewStart, viewEnd]);
        const pushIfInView = (value) => {
            const ts = toTimestamp(value);
            if (ts && ts >= viewStart && ts <= viewEnd)
                boundaries.add(ts);
        };
        if (itemStartTs !== undefined &&
            itemStartTs >= viewStart &&
            itemStartTs <= viewEnd) {
            boundaries.add(itemStartTs);
        }
        pushIfInView(itemState.itemPublishFrom);
        pushIfInView(itemState.itemUnpublishAt);
        versionRows.forEach((row) => {
            pushIfInView(row.versionValidFrom);
            pushIfInView(row.versionValidTo);
        });
        const points = Array.from(boundaries).sort((a, b) => a - b);
        const segments = [];
        for (let i = 0; i < points.length - 1; i++) {
            const start = points[i];
            const end = points[i + 1];
            if (end <= start)
                continue;
            const midpoint = start + (end - start) / 2;
            const effectiveVersion = evaluateActiveVersionAt(midpoint);
            const previous = segments[segments.length - 1];
            if (previous &&
                previous.effectiveVersion === effectiveVersion &&
                previous.end === start) {
                previous.end = end;
            }
            else {
                segments.push({ start, end, effectiveVersion });
            }
        }
        const versions = [...versionRows].sort((a, b) => b.version - a.version);
        return {
            viewStart,
            viewEnd,
            versions,
            segments,
        };
    }, [
        centerTs,
        evaluateActiveVersionAt,
        itemStartTs,
        itemState,
        versionRows,
        zoomDays,
    ]);
    const versionColorByNumber = useMemo(() => {
        const map = new Map();
        timelineModel.versions.forEach((row, index) => {
            map.set(row.version, getVersionColor(index));
        });
        return map;
    }, [timelineModel.versions]);
    const save = async () => {
        if (!editContext)
            return;
        const updates = [];
        if (itemState.itemPublishable !== initialItemState.itemPublishable) {
            if (itemState.neverPublishFieldId) {
                updates.push({
                    itemVersion: item.descriptor.version,
                    fieldId: itemState.neverPublishFieldId,
                    rawValue: itemState.itemPublishable ? "0" : "1",
                });
            }
        }
        if (itemState.itemPublishFrom !== initialItemState.itemPublishFrom) {
            if (itemState.publishFieldId) {
                updates.push({
                    itemVersion: item.descriptor.version,
                    fieldId: itemState.publishFieldId,
                    rawValue: formatDateToCompactISO(fromDateTimeLocalValue(itemState.itemPublishFrom)),
                });
            }
        }
        if (itemState.itemUnpublishAt !== initialItemState.itemUnpublishAt) {
            if (itemState.unpublishFieldId) {
                updates.push({
                    itemVersion: item.descriptor.version,
                    fieldId: itemState.unpublishFieldId,
                    rawValue: formatDateToCompactISO(fromDateTimeLocalValue(itemState.itemUnpublishAt)),
                });
            }
        }
        for (const row of versionRows) {
            const initial = initialVersionRows.find((x) => x.version === row.version);
            if (!initial)
                continue;
            if (row.versionPublishable !== initial.versionPublishable &&
                row.hideVersionFieldId) {
                updates.push({
                    itemVersion: row.version,
                    fieldId: row.hideVersionFieldId,
                    rawValue: row.versionPublishable ? "0" : "1",
                });
            }
            if (row.versionValidFrom !== initial.versionValidFrom &&
                row.validFromFieldId) {
                updates.push({
                    itemVersion: row.version,
                    fieldId: row.validFromFieldId,
                    rawValue: formatDateToCompactISO(fromDateTimeLocalValue(row.versionValidFrom)),
                });
            }
            if (row.versionValidTo !== initial.versionValidTo && row.validToFieldId) {
                updates.push({
                    itemVersion: row.version,
                    fieldId: row.validToFieldId,
                    rawValue: formatDateToCompactISO(fromDateTimeLocalValue(row.versionValidTo)),
                });
            }
        }
        if (updates.length === 0) {
            onClose(null);
            return;
        }
        setIsSaving(true);
        try {
            for (const update of updates) {
                await editContext.operations.editField({
                    field: {
                        item: {
                            id: item.id,
                            language: item.language,
                            version: update.itemVersion,
                            database: item.database,
                        },
                        fieldId: update.fieldId,
                    },
                    rawValue: update.rawValue,
                    value: update.rawValue,
                    refresh: "none",
                });
            }
            editContext.requestRefresh("immediate");
            await editContext.loadItemVersions();
            editContext.showToast?.("Publish restrictions updated.");
            onClose("saved");
        }
        catch {
            editContext.showToast?.("Failed to update publish restrictions.");
        }
        finally {
            setIsSaving(false);
        }
    };
    if (!editContext)
        return null;
    const isSaveDisabled = isLoading ||
        isSaving ||
        !hasChanges ||
        itemWindowInvalid ||
        versionWindowInvalidCount > 0 ||
        !item.canWriteItem ||
        !item.canWriteLanguage;
    const spanMs = zoomDays * TIMELINE_DAY_MS;
    const includeTimeInTooltips = zoomDays <= 31;
    const chartInnerWidth = chartWidth - CHART_PAD_X * 2;
    const timestampToChartX = (timestamp) => CHART_PAD_X +
        ((timestamp - timelineModel.viewStart) /
            (timelineModel.viewEnd - timelineModel.viewStart)) *
            chartInnerWidth;
    const chartXToTimestamp = (x) => timelineModel.viewStart +
        ((x - CHART_PAD_X) / chartInnerWidth) *
            (timelineModel.viewEnd - timelineModel.viewStart);
    const hoveredSegment = chartHover
        ? timelineModel.segments.find((segment) => chartHover.ts >= segment.start && chartHover.ts <= segment.end)
        : undefined;
    const handleChartPointerDown = (event) => {
        event.currentTarget.setPointerCapture(event.pointerId);
        dragStateRef.current = { startX: event.clientX, startCenter: centerTs };
        setIsDraggingChart(true);
    };
    const handleChartPointerMove = (event) => {
        const rect = event.currentTarget.getBoundingClientRect();
        const localX = event.clientX - rect.left;
        const dragState = dragStateRef.current;
        if (dragState) {
            const deltaX = event.clientX - dragState.startX;
            setCenterTs(dragState.startCenter - deltaX * (spanMs / chartInnerWidth));
            setChartHover(null);
            return;
        }
        const clampedX = Math.max(CHART_PAD_X, Math.min(chartWidth - CHART_PAD_X, localX));
        setChartHover({ x: clampedX, ts: chartXToTimestamp(clampedX) });
    };
    const handleChartPointerUp = (event) => {
        if (event.currentTarget.hasPointerCapture(event.pointerId)) {
            event.currentTarget.releasePointerCapture(event.pointerId);
        }
        dragStateRef.current = null;
        setIsDraggingChart(false);
    };
    const renderRestrictionCells = (options) => (_jsxs(_Fragment, { children: [_jsx("td", { className: "px-4 py-2.5", children: _jsx(Switch, { "data-testid": `${options.testIdPrefix}-publishable`, checked: options.publishable, disabled: options.publishableDisabled, onCheckedChange: (checked) => options.onPublishableChange(Boolean(checked)) }) }), _jsx("td", { className: "py-2.5 pl-4", children: _jsx(DateTimeField, { testId: `${options.testIdPrefix}-from`, icon: CalendarClock, value: options.from, disabled: options.fromDisabled, dimmed: !options.publishable, onChange: options.onFromChange }) }), _jsxs("td", { className: "relative py-2.5 pr-4 pl-6", children: [_jsx("span", { className: "text-muted-foreground absolute top-1/2 left-1.5 -translate-y-1/2 text-xs", children: "–" }), _jsx(DateTimeField, { testId: `${options.testIdPrefix}-to`, icon: CalendarOff, value: options.to, disabled: options.toDisabled, dimmed: !options.publishable, invalid: options.invalid, onChange: options.onToChange })] })] }));
    return (_jsx(Dialog, { open: true, onOpenChange: (open) => {
            if (!open)
                onClose(null);
        }, children: _jsxs(DialogContent, { "data-testid": "publish-restrictions-dialog", className: "flex max-w-5xl flex-col overflow-hidden border-none p-0 shadow-2xl", style: { maxHeight: "90vh" }, showCloseButton: true, children: [_jsx(StyledDialogTitle, { icon: _jsx(CalendarClock, { strokeWidth: 1 }), title: "Publish Restrictions", subtitle: item.displayName || item.name, trailing: !isLoading && (_jsx(Badge, { "data-testid": "publish-restrictions-effective-status", variant: effectiveStatus.variant, className: effectiveStatus.className, children: effectiveStatus.label })) }), isLoading ? (_jsx(LoadingState, { message: "Loading restrictions...", className: "py-20" })) : (_jsx("div", { className: "flex min-h-0 flex-1 flex-col overflow-y-auto", children: _jsxs("div", { className: "space-y-6 px-6 pt-2 pb-5", children: [_jsxs("section", { children: [_jsxs("div", { className: "mb-3", children: [_jsx("h3", { className: "text-base font-medium", children: "Item restrictions" }), _jsx("span", { className: "text-muted-foreground text-xs", children: "Applies to all versions" })] }), _jsxs("div", { className: "flex flex-wrap items-end gap-x-8 gap-y-3", children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Publishable" }), _jsx("div", { className: "flex h-8 items-center", children: _jsx(Switch, { "data-testid": "publish-restrictions-item-publishable", checked: itemState.itemPublishable, disabled: !itemState.neverPublishFieldId, onCheckedChange: (checked) => setItemState((prev) => ({
                                                                ...prev,
                                                                itemPublishable: Boolean(checked),
                                                            })) }) })] }), _jsxs("div", { className: "flex items-end gap-2", children: [_jsxs("div", { className: "flex w-44 flex-col gap-1", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Publish from" }), _jsx(DateTimeField, { testId: "publish-restrictions-item-from", icon: CalendarClock, value: itemState.itemPublishFrom, disabled: !itemState.publishFieldId, dimmed: !itemState.itemPublishable, onChange: (value) => setItemState((prev) => ({
                                                                    ...prev,
                                                                    itemPublishFrom: value,
                                                                })) })] }), _jsx("span", { className: "text-muted-foreground pb-2 text-xs", children: "–" }), _jsxs("div", { className: "flex w-44 flex-col gap-1", children: [_jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Unpublish at" }), _jsx(DateTimeField, { testId: "publish-restrictions-item-to", icon: CalendarOff, value: itemState.itemUnpublishAt, disabled: !itemState.unpublishFieldId, dimmed: !itemState.itemPublishable, invalid: itemWindowInvalid, onChange: (value) => setItemState((prev) => ({
                                                                    ...prev,
                                                                    itemUnpublishAt: value,
                                                                })) })] })] })] }), itemWindowInvalid && (_jsx("div", { className: "text-feedback-red mt-2 text-xs font-medium", children: "Unpublish date must be after publish date." }))] }), _jsxs("section", { children: [_jsxs("div", { className: "mb-3", children: [_jsx("h3", { className: "text-base font-medium", children: "Version restrictions" }), _jsx("span", { className: "text-muted-foreground text-xs", children: "Applies to individual versions" })] }), _jsx("div", { className: "overflow-hidden rounded-xl border", children: _jsx("div", { className: "max-h-[300px] overflow-y-auto", children: _jsxs("table", { className: "w-full table-fixed text-sm", children: [_jsx(TableColumns, {}), _jsx("thead", { className: "sticky top-0 z-10 border-b bg-white/95 backdrop-blur-sm", children: _jsxs("tr", { className: "text-muted-foreground text-left text-xs font-medium", children: [_jsx("th", { className: "px-4 py-2.5 font-medium", children: "Version" }), _jsx("th", { className: "px-4 py-2.5 font-medium", children: "Publishable" }), _jsx("th", { className: "py-2.5 pl-4 font-medium", children: "Valid from" }), _jsx("th", { className: "py-2.5 pl-6 font-medium", children: "Valid to" }), _jsx("th", { className: "px-4 py-2.5 font-medium", children: "Updated" }), _jsx("th", { className: "px-4 py-2.5 text-right font-medium", children: "By" })] }) }), _jsx("tbody", { className: "divide-y", children: versionRows.map((row) => {
                                                            const invalidWindow = !!toTimestamp(row.versionValidFrom) &&
                                                                !!toTimestamp(row.versionValidTo) &&
                                                                toTimestamp(row.versionValidFrom) >
                                                                    toTimestamp(row.versionValidTo);
                                                            const isEffective = row.version === effectiveNowVersion;
                                                            const versionColor = versionColorByNumber.get(row.version);
                                                            return (_jsxs("tr", { "data-testid": `publish-restrictions-version-${row.version}`, className: cn("bg-white align-middle transition-colors", invalidWindow && "bg-feedback-red-light/40"), children: [_jsx("td", { className: "px-4 py-2.5 whitespace-nowrap", children: _jsxs("span", { className: "bg-neutral-grey-5 inline-flex h-6 min-w-9 items-center justify-center rounded-md px-1.5 text-xs font-medium tabular-nums", style: isEffective && versionColor
                                                                                ? {
                                                                                    backgroundColor: `color-mix(in srgb, ${versionColor} 18%, white)`,
                                                                                    color: `color-mix(in srgb, ${versionColor} 85%, black)`,
                                                                                }
                                                                                : undefined, title: isEffective
                                                                                ? "Currently effective version"
                                                                                : undefined, children: ["V", row.version] }) }), renderRestrictionCells({
                                                                        publishable: row.versionPublishable,
                                                                        publishableDisabled: !row.hideVersionFieldId,
                                                                        onPublishableChange: (checked) => setVersionRows((prev) => prev.map((x) => x.version === row.version
                                                                            ? { ...x, versionPublishable: checked }
                                                                            : x)),
                                                                        from: row.versionValidFrom,
                                                                        fromDisabled: !row.validFromFieldId,
                                                                        onFromChange: (value) => setVersionRows((prev) => prev.map((x) => x.version === row.version
                                                                            ? { ...x, versionValidFrom: value }
                                                                            : x)),
                                                                        to: row.versionValidTo,
                                                                        toDisabled: !row.validToFieldId,
                                                                        onToChange: (value) => setVersionRows((prev) => prev.map((x) => x.version === row.version
                                                                            ? { ...x, versionValidTo: value }
                                                                            : x)),
                                                                        invalid: invalidWindow,
                                                                        testIdPrefix: `publish-restrictions-version-${row.version}`,
                                                                    }), _jsx("td", { className: "text-muted-foreground px-4 py-2.5 text-xs whitespace-nowrap", children: row.updatedLabel }), _jsx("td", { className: "px-4 py-2.5", children: _jsx(UserCell, { name: row.updatedBy }) })] }, row.version));
                                                        }) })] }) }) }), versionWindowInvalidCount > 0 && (_jsxs("div", { className: "text-feedback-red mt-2 text-xs font-medium", children: [versionWindowInvalidCount, " version(s) have invalid date ranges."] }))] }), _jsxs("section", { children: [_jsxs("div", { className: "mb-1 flex items-center justify-between", children: [_jsx("h3", { className: "text-foreground text-base font-medium", children: "Timeline" }), _jsx("div", { className: "flex items-center gap-1", children: TIMELINE_ZOOM_PRESETS.map((preset) => (_jsx("button", { type: "button", className: cn("border-b-2 px-2 pt-1 pb-1.5 text-xs transition-colors", zoomDays === preset.days
                                                        ? "border-neutral-grey-100 text-foreground font-medium"
                                                        : "text-muted-foreground hover:text-foreground border-transparent"), onClick: () => setZoomDays(preset.days), children: preset.label }, preset.label))) })] }), _jsxs("div", { ref: chartContainerRef, className: cn("relative touch-none pt-9 select-none", isDraggingChart ? "cursor-grabbing" : "cursor-grab"), onPointerDown: handleChartPointerDown, onPointerMove: handleChartPointerMove, onPointerUp: handleChartPointerUp, onPointerLeave: () => setChartHover(null), children: [chartHover && hoveredSegment && (_jsxs("div", { className: "pointer-events-none absolute top-0 z-10 -translate-x-1/2 rounded-lg border bg-white px-3 py-1 text-xs whitespace-nowrap shadow-md", style: {
                                                    left: Math.max(100, Math.min(chartWidth - 100, chartHover.x)),
                                                }, children: [_jsx("span", { className: "font-medium", children: hoveredSegment.effectiveVersion
                                                            ? `V${hoveredSegment.effectiveVersion}`
                                                            : "Not published" }), _jsxs("span", { className: "text-muted-foreground", children: [" / ", formatTimelineRangeLabel(hoveredSegment.start, hoveredSegment.end, includeTimeInTooltips)] })] })), _jsxs("svg", { width: chartWidth, height: CHART_HEIGHT, children: [timelineModel.segments.map((segment, index) => {
                                                        if (!segment.effectiveVersion)
                                                            return null;
                                                        const x1 = timestampToChartX(segment.start);
                                                        const x2 = timestampToChartX(segment.end);
                                                        const fillColor = versionColorByNumber.get(segment.effectiveVersion) ??
                                                            "var(--color-feedback-blue)";
                                                        return (_jsx("rect", { x: x1 + 1, y: CHART_BAR_Y, width: Math.max(0, x2 - x1 - 2), height: CHART_BAR_HEIGHT, fill: fillColor, opacity: hoveredSegment === segment ? 1 : 0.85, rx: 4 }, `segment-${index}`));
                                                    }), _jsx("line", { x1: CHART_PAD_X, y1: CHART_AXIS_Y, x2: chartWidth - CHART_PAD_X, y2: CHART_AXIS_Y, stroke: "var(--color-neutral-grey-10)" }), [
                                                        CHART_PAD_X,
                                                        chartWidth / 2,
                                                        chartWidth - CHART_PAD_X,
                                                    ].map((tickX) => (_jsx("line", { x1: tickX, y1: CHART_AXIS_Y - 4, x2: tickX, y2: CHART_AXIS_Y, stroke: "var(--color-neutral-grey-15)" }, `tick-${tickX}`))), chartHover && (_jsxs("g", { children: [_jsx("line", { x1: chartHover.x, y1: 0, x2: chartHover.x, y2: CHART_AXIS_Y, stroke: "var(--color-neutral-grey-50)", strokeDasharray: "2 3" }), _jsx("circle", { cx: chartHover.x, cy: CHART_AXIS_Y, r: 3.5, fill: (hoveredSegment?.effectiveVersion
                                                                    ? versionColorByNumber.get(hoveredSegment.effectiveVersion)
                                                                    : undefined) ?? "var(--color-neutral-grey-50)" })] })), _jsx("text", { x: CHART_PAD_X, y: CHART_AXIS_Y + 16, fontSize: 11, fill: "var(--color-neutral-grey-50)", children: new Date(timelineModel.viewStart).toLocaleDateString() }), _jsx("text", { x: chartWidth / 2, y: CHART_AXIS_Y + 16, fontSize: 11, fill: "var(--color-neutral-grey-50)", textAnchor: "middle", children: new Date(centerTs).toLocaleDateString() }), _jsx("text", { x: chartWidth - CHART_PAD_X, y: CHART_AXIS_Y + 16, fontSize: 11, fill: "var(--color-neutral-grey-50)", textAnchor: "end", children: new Date(timelineModel.viewEnd).toLocaleDateString() })] })] }), _jsx("div", { className: "text-muted-foreground mt-1 text-right text-[10px]", children: "Drag to pan \u00B7 Alt+scroll to zoom" })] })] }) })), _jsxs(DialogButtons, { children: [_jsx(Button, { variant: "outline", size: "sm", onClick: () => onClose(null), children: "Cancel" }), _jsx(Button, { "data-testid": "publish-restrictions-save", size: "sm", onClick: save, disabled: isSaveDisabled, children: isSaving ? "Saving..." : "Save" })] })] }) }));
}
//# sourceMappingURL=PublishRestrictionsDialog.js.map