import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useEffect, useMemo, useState } from "react";
import { Loader2, Check } from "lucide-react";
import { Tooltip, TooltipContent, TooltipTrigger, } from "../../components/ui/tooltip";
import { useEditContext, useFieldsEditContext } from "../client/editContext";
import { SimpleTable } from "../ui/SimpleTable";
import { getAbsoluteIconUrl, stripGuid } from "../utils";
function getValidationItemKey(item) {
    return [
        item.id?.toLowerCase(),
        item.language?.toLowerCase(),
        item.version ?? 0,
        item.database?.toLowerCase() ?? "",
    ].join("|");
}
function getValidationItemIdentityKey(item) {
    return [
        item.id?.toLowerCase(),
        item.language?.toLowerCase(),
        item.database?.toLowerCase() ?? "",
    ].join("|");
}
export function Validation() {
    const editContext = useEditContext();
    const fieldsContext = useFieldsEditContext();
    const [stubByItemKey, setStubByItemKey] = useState({});
    const validationResults = useMemo(() => editContext?.validationResult?.flatMap((x) => x.results.map((y) => ({
        ...y,
        item: { ...x.item, id: y.itemId },
        language: x.item.language,
        version: x.item.version,
    }))), [editContext?.validationResult]);
    useEffect(() => {
        if (!editContext?.itemsRepository ||
            !validationResults ||
            validationResults.length === 0)
            return;
        const descriptorsByKey = new Map();
        validationResults.forEach((result) => {
            const key = getValidationItemKey(result.item);
            if (!stubByItemKey[key]) {
                descriptorsByKey.set(key, result.item);
            }
        });
        const descriptorsMissingStubs = Array.from(descriptorsByKey.values());
        if (descriptorsMissingStubs.length === 0)
            return;
        let cancelled = false;
        const descriptorKeysByIdentity = new Map();
        descriptorsMissingStubs.forEach((descriptor) => {
            const identityKey = getValidationItemIdentityKey(descriptor);
            const keys = descriptorKeysByIdentity.get(identityKey) ?? [];
            keys.push(getValidationItemKey(descriptor));
            descriptorKeysByIdentity.set(identityKey, keys);
        });
        editContext.itemsRepository
            .getItemsStubs(descriptorsMissingStubs, editContext.currentItemDescriptor)
            .then((stubs) => {
            if (cancelled || stubs.length === 0)
                return;
            setStubByItemKey((current) => {
                const next = { ...current };
                let changed = false;
                stubs.forEach((stub) => {
                    next[getValidationItemKey(stub)] = stub;
                    changed = true;
                    descriptorKeysByIdentity
                        .get(getValidationItemIdentityKey(stub))
                        ?.forEach((key) => {
                        next[key] = stub;
                    });
                });
                return changed ? next : current;
            });
        })
            .catch((error) => {
            console.error("Error loading validation item stubs:", error);
        });
        return () => {
            cancelled = true;
        };
    }, [
        editContext?.itemsRepository,
        editContext?.currentItemDescriptor,
        stubByItemKey,
        validationResults,
    ]);
    if (!validationResults)
        return null;
    const nameBodyTemplate = (validationResult) => {
        const stub = stubByItemKey[getValidationItemKey(validationResult.item)];
        const name = (_jsxs("div", { className: "flex min-w-0 items-start gap-2", children: [stub?.icon && (_jsx("img", { src: getAbsoluteIconUrl(stub.icon, 24), alt: "", width: 24, height: 24, className: "h-6 w-6 shrink-0 object-contain" })), _jsxs("span", { className: "min-w-0 break-all", children: [_jsx("span", { className: "font-medium", children: validationResult.itemName }), " ", _jsxs("span", { className: "text-neutral-grey-50", children: ["(", validationResult.language, ", ", validationResult.version, ")"] })] })] }));
        if (!stub?.path)
            return name;
        return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: name }), _jsx(TooltipContent, { side: "bottom", align: "start", className: "max-w-72 break-all", children: stub.path })] }));
    };
    const validationTemplate = (validationResult) => {
        return _jsx("div", { children: validationResult.message });
    };
    const columns = [
        { body: nameBodyTemplate, header: "Item" },
        {
            body: validationTemplate,
            align: "center",
            header: _jsx(Check, { className: "h-4 w-4" }),
        },
    ];
    if (validationResults.length === 0) {
        return (_jsx("div", { className: "text-neutral-grey-50 p-4 text-center text-xs", children: "No validation results" }));
    }
    return (_jsxs("div", { children: [editContext?.validating && (_jsx("div", { className: "p-3 text-center", children: _jsx(Loader2, { className: "h-5 w-5 animate-spin" }) })), !editContext?.validating && (_jsx(SimpleTable, { "data-testid": "validation-results-table", items: validationResults, columns: columns, onRowClick: async ({ item: result }) => {
                    if (!editContext)
                        return;
                    const itemDescriptor = {
                        id: result.itemId,
                        language: result.language,
                        version: result.version,
                    };
                    const currentItem = editContext.currentItemDescriptor;
                    const isCurrentItem = !!currentItem &&
                        stripGuid(currentItem?.id ?? "") ===
                            stripGuid(itemDescriptor.id) &&
                        currentItem.language === itemDescriptor.language &&
                        currentItem.version === itemDescriptor.version;
                    if (!isCurrentItem) {
                        const loadedItem = await editContext.loadItem(itemDescriptor);
                        if (!loadedItem)
                            return;
                    }
                    if (result.fieldId) {
                        await fieldsContext?.setFocusedField({
                            item: itemDescriptor,
                            fieldId: result.fieldId,
                        }, false);
                    }
                    else {
                        editContext.select?.([result.itemId]);
                    }
                } }))] }));
}
//# sourceMappingURL=Validation.js.map