import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { json } from "@codemirror/lang-json";
import dayjs from "dayjs";
import { basicSetup } from "codemirror";
import { useMemo, useRef, useState } from "react";
import { UserInfo } from "@vertesia/ui/features";
import { useUserSession } from "@vertesia/ui/session";
import { CodeMirrorEditor, GeneratedForm, ManagedObject } from "@vertesia/ui/widgets";
import { Button, ErrorBox, FormItem, Input, Styles, Textarea, useFetch, useToast, Panel } from "@vertesia/ui/core";
import { SelectContentType, stringifyTableLayout } from "../types";
const extensions = [basicSetup, json()];
export function EditCollectionView({ refetch, collection }) {
    const typeId = collection.type?.id;
    const tableLayoutRef = useRef(undefined);
    const toast = useToast();
    const { client } = useUserSession();
    const [isUpdating, setUpdating] = useState(false);
    const [metadata, setMetadata] = useState({
        name: collection.name,
        description: collection.description || "",
        query: collection.query ? JSON.stringify(collection.query, null, 2) : "",
        tags: collection.tags || [],
        type: collection.type?.id || "",
        allowed_types: collection.allowed_types || [],
    });
    const tableLayoutValue = useMemo(() => {
        return stringifyTableLayout(collection.table_layout);
    }, [collection.table_layout]);
    const onSubmit = () => {
        let query = undefined;
        try {
            query = metadata.query ? JSON.parse(metadata.query) : undefined;
        }
        catch (err) {
            toast({
                title: "Invalid Query JSON",
                description: err.message,
                status: "error",
                duration: 5000,
            });
            return;
        }
        const payload = {
            name: metadata.name,
            description: metadata.description,
            query: query,
            tags: metadata.tags,
            type: metadata.type,
            allowed_types: metadata.allowed_types,
        };
        let error;
        if (!payload.name) {
            error = "Name is required";
        }
        if (!payload.type) {
            payload.type = null;
        }
        if (error) {
            toast({
                title: "Validation failed",
                description: error,
                status: "error",
                duration: 5000,
            });
            return;
        }
        if (tableLayoutRef.current) {
            const layout = tableLayoutRef.current.getValue();
            if (layout) {
                try {
                    payload.table_layout = JSON.parse(layout);
                }
                catch (err) {
                    toast({
                        title: "Invalid Table Layout",
                        description: err.message,
                        status: "error",
                        duration: 5000,
                    });
                    return;
                }
            }
            else {
                payload.table_layout = null;
            }
        }
        setUpdating(true);
        client.store.collections
            .update(collection.id, payload)
            .then(() => {
            refetch();
            toast({
                title: "Collection updated",
                description: "Collection has been updated successfully",
                status: "success",
                duration: 3000,
            });
        })
            .catch((err) => {
            toast({
                title: "Failed to update collection",
                description: err.message,
                status: "error",
                duration: 5000,
            });
        })
            .finally(() => {
            setUpdating(false);
        });
    };
    const setField = (name, value) => {
        setMetadata({
            ...metadata,
            [name]: value,
        });
    };
    return (_jsxs("div", { className: "flex flex-col gap-4 py-2", children: [_jsxs(Panel, { title: "Configuration", action: _jsx(Button, { size: "lg", isDisabled: isUpdating, onClick: onSubmit, children: "Save" }), children: [_jsxs("div", { className: "flex justify-between mb-2", children: [_jsxs("div", { className: "w-1/2 gap-2 flex flex-col", children: [_jsx("div", { className: "text-sm font-medium mb-1", children: "Created By" }), _jsxs("div", { className: "gap-2 flex items-center", children: [_jsx(UserInfo, { userRef: collection.created_by, showTitle: true }), _jsxs("span", { children: ["at ", dayjs(collection.created_at).format("YYYY-MM-DD HH:mm:ss")] })] })] }), _jsxs("div", { className: "w-1/2 gap-2 flex flex-col", children: [_jsx("div", { className: "text-sm font-medium mb-1", children: "Updated By" }), _jsxs("div", { className: "gap-2 flex items-center", children: [_jsx(UserInfo, { userRef: collection.updated_by, showTitle: true }), _jsxs("span", { children: ["at ", dayjs(collection.updated_at).format("YYYY-MM-DD HH:mm:ss")] })] })] })] }), _jsx(FormItem, { label: "Name", required: true, children: _jsx(Input, { value: metadata.name, onChange: (v) => setField("name", v) }) }), _jsx(FormItem, { label: "Description", children: _jsx(Textarea, { value: metadata.description, onChange: (e) => setField("description", e) }) }), !collection.dynamic &&
                        _jsx(FormItem, { label: "Allowed Content Types", description: "Select which content types can be added to the collection. If not set, then all content types are allowed.", children: _jsx(SelectContentType, { defaultValue: metadata.allowed_types || null, onChange: (v) => {
                                    if (Array.isArray(v)) {
                                        setField("allowed_types", v.map(type => type.id));
                                    }
                                    else {
                                        setField("allowed_types", v ? [v.id] : []);
                                    }
                                }, isClearable: true, multiple: true }) }), collection.dynamic && (_jsx(FormItem, { label: "Query", description: "Define the query to dynamically fetch content for the collection.", children: _jsx(Textarea, { className: Styles.INPUT, value: metadata.query, onChange: (e) => setField("query", e) }) })), _jsx(FormItem, { label: "Table Layout", description: "Define a custom layout for displaying the collection in tables.", children: _jsx(CodeMirrorEditor, { className: "border-1 rounded-md border-border", value: tableLayoutValue, extensions: extensions, editorRef: tableLayoutRef }) }), _jsx(FormItem, { label: "Type", description: "Select a content type to assign custom properties and data to the collection.", children: _jsx(SelectContentType, { defaultValue: metadata.type || null, onChange: (v) => {
                                if (Array.isArray(v)) {
                                    setField("type", v.length > 0 ? v[0].id : null);
                                }
                                else {
                                    setField("type", v?.id || null);
                                }
                            }, isClearable: true }) })] }), typeId && _jsx(PropertiesEditor, { typeId: typeId, collection: collection })] }));
}
function PropertiesEditor({ typeId, collection }) {
    const toast = useToast();
    const { client } = useUserSession();
    const [isUpdating, setIsUpdating] = useState(false);
    const { data: type, error } = useFetch(() => client.store.types.retrieve(typeId), [typeId]);
    const schema = type?.object_schema || {};
    const object = useMemo(() => new ManagedObject(schema, collection.properties || {}), [schema, collection.properties]);
    if (error) {
        return _jsx(ErrorBox, { title: "Failed to load type", children: error.message });
    }
    if (!type) {
        return null;
    }
    const _onSave = (data) => {
        const payload = { properties: data || {} };
        setIsUpdating(true);
        client.store.collections
            .update(collection.id, payload)
            .then(() => {
            toast({
                title: "Collection properties updated",
                description: "Collection has been updated successfully",
                status: "success",
                duration: 3000,
            });
        })
            .catch((err) => {
            toast({
                title: "Failed to update collection properties",
                description: err.message,
                status: "error",
                duration: 5000,
            });
        })
            .finally(() => {
            setIsUpdating(false);
        });
    };
    return (_jsx(Panel, { title: "Properties", action: _jsx(Button, { size: "lg", isLoading: isUpdating, type: "submit", children: "Save" }), children: _jsx(GeneratedForm, { object: object, onSubmit: _onSave }) }));
}
//# sourceMappingURL=EditCollectionView.js.map