import React, { useEffect, useRef, useState } from "react";
import TableView from "../../../Models/DatabaseModels/TableView";
import MoreMenu from "../MoreMenu/MoreMenu";
import MoreMenuItem from "../MoreMenu/MoreMenuItem";
import ModelAPI from "../../Utils/ModelAPI/ModelAPI";
import { LIMIT_PER_PROJECT } from "../../../Types/Database/LimitMax";
import SortOrder from "../../../Types/BaseDatabase/SortOrder";
import API from "../../../Utils/API";
import MoreMenuSection from "../MoreMenu/MoreMenuSection";
import { ButtonStyleType } from "../Button/Button";
import IconProp from "../../../Types/Icon/IconProp";
import { BarLoader } from "react-spinners";
import ConfirmModal from "../Modal/ConfirmModal";
import ModelFormModal from "../ModelFormModal/ModelFormModal";
import { FormType } from "../Forms/ModelForm";
import FormFieldSchemaType from "../Forms/Types/FormFieldSchemaType";
import ProjectUtil from "../../Utils/Project";
import User from "../../Utils/User";
import Icon, { SizeProp, ThickProp } from "../Icon/Icon";
const TableViewElement = (props) => {
    const [error, setError] = useState("");
    const [isLoading, setIsLoading] = useState(false);
    const [allTableViews, setAllTableViews] = useState([]);
    const [tableViewToDelete, setTableViewToDelete] = useState(undefined);
    const [tableViewToEdit, setTableViewToEdit] = useState(undefined);
    const [showCreateNewViewModal, setShowCreateNewViewModel] = useState(false);
    const moreMenuRef = useRef();
    const [currentlySelectedView, setCurrentlySelectedView] = useState(null);
    useEffect(() => {
        setCurrentlySelectedView(props.tableView);
    }, [props.tableView]);
    // load all the filters for this user and for this project.
    const fetchTableViews = async () => {
        try {
            setError("");
            setIsLoading(true);
            const tableViews = await ModelAPI.getList({
                modelType: TableView,
                query: {
                    projectId: ProjectUtil.getCurrentProjectId(),
                    createdByUserId: User.getUserId(),
                    tableId: props.tableId,
                },
                limit: LIMIT_PER_PROJECT,
                skip: 0,
                select: {
                    sort: true,
                    itemsOnPage: true,
                    query: true,
                    name: true,
                    facets: true,
                },
                sort: {
                    name: SortOrder.Ascending,
                },
            });
            setAllTableViews(tableViews.data);
        }
        catch (err) {
            setError(API.getFriendlyErrorMessage(err));
        }
        setIsLoading(false);
    };
    const deleteTableView = async (tableView) => {
        const tableViewId = tableView.id;
        try {
            setError("");
            setIsLoading(true);
            await ModelAPI.deleteItem({
                modelType: TableView,
                id: tableViewId,
            });
            await fetchTableViews();
        }
        catch (err) {
            setError(API.getFriendlyErrorMessage(err));
        }
        setIsLoading(false);
    };
    useEffect(() => {
        fetchTableViews().catch((err) => {
            setError(API.getFriendlyErrorMessage(err));
        });
    }, []);
    const getRightElementForTableViewMenuItem = (item) => {
        return (React.createElement("div", { className: "flex" },
            React.createElement("div", { className: "h-4 w-4 mr-2" },
                React.createElement(Icon, { icon: IconProp.Edit, className: "text-gray-400 hover:text-gray-600", size: SizeProp.Regular, thick: ThickProp.Thick, onClick: () => {
                        setTableViewToEdit(item);
                    } })),
            React.createElement("div", { className: "h-4 w-4" },
                React.createElement(Icon, { className: "text-gray-400 hover:text-gray-600", icon: IconProp.Trash, size: SizeProp.Regular, thick: ThickProp.Thick, onClick: () => {
                        setTableViewToDelete(item);
                    } }))));
    };
    const getViewItems = () => {
        return allTableViews.map((item, index) => {
            return (React.createElement(MoreMenuItem, { key: index, rightElement: getRightElementForTableViewMenuItem(item), text: item.name || "", className: "text-gray-600 hover:text-gray-800", icon: IconProp.Window, onClick: () => {
                    var _a;
                    (_a = props.onViewChange) === null || _a === void 0 ? void 0 : _a.call(props, item);
                    setCurrentlySelectedView(item);
                } }));
        });
    };
    const hasQueryFilters = Boolean(props.currentQuery) &&
        Object.keys(props.currentQuery).length > 0;
    /*
     * A facet snapshot is "active" only when it contains real selections —
     * a non-empty array, or an object whose nested values are non-empty.
     * Primitive top-level values (e.g. operator strings like "is") are
     * default settings emitted by useResourceOwners even with zero
     * selections, and must not count as active state — otherwise the
     * Saved Views trigger would always show on tables that wire up
     * useResourceOwners, even with no views and no user-applied filters.
     */
    const hasFacetState = Boolean(props.currentFacetState &&
        Object.values(props.currentFacetState).some((v) => {
            if (v === null || v === undefined) {
                return false;
            }
            if (Array.isArray(v)) {
                return v.length > 0;
            }
            if (typeof v === "object") {
                return Object.values(v).some((inner) => {
                    return Array.isArray(inner) ? inner.length > 0 : Boolean(inner);
                });
            }
            return false;
        }));
    const hasActiveFilters = hasQueryFilters || hasFacetState;
    const getMenuContents = () => {
        if (isLoading) {
            return [React.createElement(BarLoader, { key: -1 })];
        }
        const elements = [];
        if (allTableViews.length > 0) {
            elements.push(React.createElement(MoreMenuSection, { title: "Saved Views" }, getViewItems()));
        }
        if (hasActiveFilters) {
            elements.push(React.createElement(MoreMenuItem, { key: "save-new-view", text: "Save as New View", className: "bg-gray-50 hover:bg-gray-100 text-gray-700 hover:text-gray-900 font-medium -mt-2", icon: IconProp.Add, iconClassName: "", onClick: () => {
                    setShowCreateNewViewModel(true);
                } }));
        }
        return elements;
    };
    if (error) {
        return (React.createElement(ConfirmModal, { title: `Something went wrong...`, description: error, isLoading: false, submitButtonText: "Close", onSubmit: () => {
                return setError("");
            } }));
    }
    if (tableViewToEdit) {
        return (React.createElement(ModelFormModal, { modelType: TableView, modelIdToEdit: tableViewToEdit.id, name: "Edit View", title: "Edit View", description: "You can rename this table view to any name you like.", onClose: () => {
                setTableViewToEdit(undefined);
            }, submitButtonText: "Save Changes", onSuccess: async () => {
                setTableViewToEdit(undefined);
                await fetchTableViews();
            }, formProps: {
                name: "Edit View",
                modelType: TableView,
                id: "edit-table-view",
                fields: [
                    {
                        field: {
                            name: true,
                        },
                        fieldType: FormFieldSchemaType.Text,
                        placeholder: "Name of the view",
                        description: "Please enter the new name of the view",
                        title: "Name",
                        required: true,
                    },
                ],
                formType: FormType.Update,
            } }));
    }
    if (tableViewToDelete) {
        return (React.createElement(ConfirmModal, { description: `Are you sure you want to delete view - ${tableViewToDelete.name}?`, title: `Delete ${tableViewToDelete.name}`, isLoading: isLoading, onSubmit: async () => {
                await deleteTableView(tableViewToDelete);
                setTableViewToDelete(undefined);
            }, onClose: () => {
                setTableViewToDelete(undefined);
            }, submitButtonText: `Delete`, submitButtonType: ButtonStyleType.DANGER }));
    }
    if (showCreateNewViewModal) {
        return (React.createElement(ModelFormModal, { modelType: TableView, name: "Save New View", title: "Save New View", description: "You can save the current table settings as a new view.", onClose: () => {
                setShowCreateNewViewModel(false);
            }, submitButtonText: "Save Changes", onBeforeCreate: (tableView) => {
                let sort = {};
                if (props.currentSortOrder && props.currentSortBy) {
                    sort = {
                        [props.currentSortBy]: props.currentSortOrder,
                    };
                }
                tableView.tableId = props.tableId;
                tableView.query =
                    props.currentQuery || {};
                tableView.itemsOnPage = (props === null || props === void 0 ? void 0 : props.currentItemsOnPage) || 10;
                tableView.sort = sort || {};
                if (props.currentFacetState) {
                    tableView.facets = props.currentFacetState;
                }
                return Promise.resolve(tableView);
            }, onSuccess: async (tableView) => {
                var _a;
                setShowCreateNewViewModel(false);
                await fetchTableViews();
                // set as current view
                (_a = props.onViewChange) === null || _a === void 0 ? void 0 : _a.call(props, tableView);
            }, formProps: {
                name: "Save New View",
                modelType: TableView,
                id: "save-table-view",
                fields: [
                    {
                        field: {
                            name: true,
                        },
                        fieldType: FormFieldSchemaType.Text,
                        placeholder: "Name of the view",
                        description: "Please enter the new name of the view",
                        title: "Name",
                        required: true,
                    },
                ],
                formType: FormType.Create,
            } }));
    }
    const getElementToBeShownInsteadOfButton = () => {
        /*
         * Shared shape so the trigger lines up with the search bar + Create button
         * (text-sm font-medium + px-3 py-2 + 1px border → ~38px tall).
         */
        const triggerBase = "inline-flex cursor-pointer items-center gap-2 rounded-md border px-3 py-2 text-sm font-medium shadow-sm transition-colors";
        if (currentlySelectedView) {
            return (React.createElement("div", { className: `${triggerBase} border-indigo-200 bg-indigo-50 text-indigo-700 hover:border-indigo-300 hover:bg-indigo-100`, title: `Saved view: ${currentlySelectedView.name}` },
                React.createElement(Icon, { icon: IconProp.Bookmark, className: "h-4 w-4 flex-none text-indigo-500" }),
                React.createElement("span", { className: "inline-flex items-baseline gap-1.5 whitespace-nowrap leading-none" },
                    React.createElement("span", { className: "text-[10px] font-medium uppercase tracking-wider text-indigo-400" }, "View"),
                    React.createElement("span", { className: "max-w-[14rem] truncate text-sm font-semibold" }, currentlySelectedView.name)),
                React.createElement("span", { "aria-hidden": "true", className: "mx-0.5 h-4 w-px bg-indigo-200" }),
                React.createElement("button", { type: "button", "aria-label": "Clear saved view", title: "Clear saved view", className: "-mr-1 inline-flex h-5 w-5 flex-none items-center justify-center rounded-md text-indigo-500 transition-colors hover:bg-indigo-200 hover:text-indigo-900 focus:outline-none focus:ring-2 focus:ring-indigo-400", onClick: (event) => {
                        var _a;
                        event.stopPropagation();
                        setCurrentlySelectedView(null);
                        (_a = props.onViewChange) === null || _a === void 0 ? void 0 : _a.call(props, null);
                        closeDropdownMenu();
                    } },
                    React.createElement(Icon, { icon: IconProp.Close, className: "h-3 w-3" })),
                React.createElement(Icon, { icon: IconProp.ChevronDown, className: "h-3.5 w-3.5 flex-none text-indigo-400" })));
        }
        return (React.createElement("div", { className: `${triggerBase} border-gray-200 bg-white text-gray-700 hover:border-gray-300 hover:bg-gray-50`, title: "Saved Views" },
            React.createElement(Icon, { icon: IconProp.Bookmark, className: "h-4 w-4 flex-none text-gray-400" }),
            React.createElement("span", { className: "text-sm" }, "Saved Views"),
            allTableViews.length > 0 && (React.createElement("span", { className: "inline-flex h-5 min-w-[20px] items-center justify-center rounded-full bg-gray-100 px-1.5 text-[11px] font-medium text-gray-600" }, allTableViews.length.toLocaleString())),
            React.createElement(Icon, { icon: IconProp.ChevronDown, className: "h-3.5 w-3.5 flex-none text-gray-400" })));
    };
    const closeDropdownMenu = () => {
        if (moreMenuRef.current) {
            moreMenuRef.current.closeDropdown();
        }
    };
    if (!isLoading &&
        allTableViews.length === 0 &&
        !hasActiveFilters &&
        !currentlySelectedView) {
        return React.createElement(React.Fragment, null);
    }
    return (React.createElement(MoreMenu, { elementToBeShownInsteadOfButton: getElementToBeShownInsteadOfButton(), ref: moreMenuRef }, getMenuContents()));
};
export default TableViewElement;
//# sourceMappingURL=TableView.js.map