import React, { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';
import { useModal } from '@faceless-ui/modal';
import { useTranslation } from 'react-i18next';
import { toast } from 'react-toastify';
import DefaultEdit from '../../views/collections/Edit/Default';
import X from '../../icons/X';
import buildStateFromSchema from '../../forms/Form/buildStateFromSchema';
import { getTranslation } from '../../../../utilities/getTranslation';
import { Drawer, DrawerToggler } from '../Drawer';
import Button from '../Button';
import { useConfig } from '../../utilities/Config';
import { useLocale } from '../../utilities/Locale';
import { useAuth } from '../../utilities/Auth';
import { DocumentInfoProvider } from '../../utilities/DocumentInfo';
import RenderCustomComponent from '../../utilities/RenderCustomComponent';
import usePayloadAPI from '../../../hooks/usePayloadAPI';
import formatFields from '../../views/collections/Edit/formatFields';
import { useRelatedCollections } from '../../forms/field-types/Relationship/AddNew/useRelatedCollections';
import IDLabel from '../IDLabel';
import { useEditDepth } from '../../utilities/EditDepth';
import './index.scss';
const baseClass = 'doc-drawer';
const formatDocumentDrawerSlug = ({ collectionSlug, id, depth, uuid, }) => `doc-drawer_${collectionSlug}_${depth}${id ? `_${id}` : ''}_${uuid}`;
export const DocumentDrawerToggler = ({ children, className, drawerSlug, id, collectionSlug, ...rest }) => {
    const { t, i18n } = useTranslation(['fields', 'general']);
    const [collectionConfig] = useRelatedCollections(collectionSlug);
    return (React.createElement(DrawerToggler, { slug: drawerSlug, formatSlug: false, className: className, "aria-label": t(!id ? 'fields:addNewLabel' : 'general:editLabel', { label: getTranslation(collectionConfig.labels.singular, i18n) }), ...rest }, children));
};
export const DocumentDrawer = ({ collectionSlug, id, drawerSlug, onSave, customHeader, }) => {
    var _a, _b, _c;
    const { serverURL, routes: { api } } = useConfig();
    const { toggleModal, modalState, closeModal } = useModal();
    const locale = useLocale();
    const { permissions, user } = useAuth();
    const [initialState, setInitialState] = useState();
    const { t, i18n } = useTranslation(['fields', 'general']);
    const hasInitializedState = useRef(false);
    const [isOpen, setIsOpen] = useState(false);
    const [collectionConfig] = useRelatedCollections(collectionSlug);
    const [fields, setFields] = useState(() => formatFields(collectionConfig, true));
    useEffect(() => {
        setFields(formatFields(collectionConfig, true));
    }, [collectionSlug, collectionConfig]);
    const [{ data, isLoading: isLoadingDocument, isError }] = usePayloadAPI((id ? `${serverURL}${api}/${collectionSlug}/${id}` : null), { initialParams: { 'fallback-locale': 'null', depth: 0, draft: 'true' } });
    useEffect(() => {
        if (isLoadingDocument || hasInitializedState.current === true) {
            return;
        }
        const awaitInitialState = async () => {
            const state = await buildStateFromSchema({
                fieldSchema: fields,
                data,
                user,
                operation: id ? 'update' : 'create',
                id,
                locale,
                t,
            });
            setInitialState(state);
        };
        awaitInitialState();
        hasInitializedState.current = true;
    }, [data, fields, id, user, locale, isLoadingDocument, t]);
    useEffect(() => {
        var _a;
        setIsOpen(Boolean((_a = modalState[drawerSlug]) === null || _a === void 0 ? void 0 : _a.isOpen));
    }, [modalState, drawerSlug]);
    useEffect(() => {
        var _a;
        if (isOpen && !isLoadingDocument && isError) {
            closeModal(drawerSlug);
            toast.error(((_a = data.errors) === null || _a === void 0 ? void 0 : _a[0].message) || t('error:unspecific'));
        }
    }, [isError, t, isOpen, data, drawerSlug, closeModal, isLoadingDocument]);
    if (isError)
        return null;
    if (isOpen) {
        // IMPORTANT: we must ensure that modals are not recursively rendered
        // to do this, do not render the drawer until it is open
        return (React.createElement(Drawer, { slug: drawerSlug, formatSlug: false, className: baseClass },
            React.createElement(DocumentInfoProvider, { collection: collectionConfig },
                React.createElement(RenderCustomComponent, { DefaultComponent: DefaultEdit, CustomComponent: (_c = (_b = (_a = collectionConfig.admin) === null || _a === void 0 ? void 0 : _a.components) === null || _b === void 0 ? void 0 : _b.views) === null || _c === void 0 ? void 0 : _c.Edit, componentProps: {
                        isLoading: !initialState,
                        data,
                        id,
                        collection: collectionConfig,
                        permissions: permissions.collections[collectionConfig.slug],
                        isEditing: Boolean(id),
                        apiURL: id ? `${serverURL}${api}/${collectionSlug}/${id}` : null,
                        onSave,
                        initialState,
                        hasSavePermission: true,
                        action: `${serverURL}${api}/${collectionSlug}${id ? `/${id}` : ''}?locale=${locale}&depth=0&fallback-locale=null`,
                        disableEyebrow: true,
                        disableActions: true,
                        me: true,
                        disableLeaveWithoutSaving: true,
                        customHeader: (React.createElement("div", { className: `${baseClass}__header` },
                            React.createElement("div", { className: `${baseClass}__header-content` },
                                React.createElement("h2", null, !customHeader ? t(!id ? 'fields:addNewLabel' : 'general:editLabel', { label: getTranslation(collectionConfig.labels.singular, i18n) }) : customHeader),
                                React.createElement(Button, { buttonStyle: "none", className: `${baseClass}__header-close`, onClick: () => toggleModal(drawerSlug), "aria-label": t('general:close') },
                                    React.createElement(X, null))),
                            id && (React.createElement(IDLabel, { id: id })))),
                    } }))));
    }
    return null;
};
export const useDocumentDrawer = ({ id, collectionSlug }) => {
    const drawerDepth = useEditDepth();
    const uuid = useId();
    const { modalState, toggleModal } = useModal();
    const [isOpen, setIsOpen] = useState(false);
    const drawerSlug = formatDocumentDrawerSlug({
        collectionSlug,
        id,
        depth: drawerDepth,
        uuid,
    });
    useEffect(() => {
        var _a;
        setIsOpen(Boolean((_a = modalState[drawerSlug]) === null || _a === void 0 ? void 0 : _a.isOpen));
    }, [modalState, drawerSlug]);
    const toggleDrawer = useCallback(() => {
        toggleModal(drawerSlug);
    }, [toggleModal, drawerSlug]);
    const MemoizedDrawer = useMemo(() => {
        return ((props) => (React.createElement(DocumentDrawer, { ...props, collectionSlug: collectionSlug, id: id, drawerSlug: drawerSlug, key: drawerSlug })));
    }, [id, drawerSlug, collectionSlug]);
    const MemoizedDrawerToggler = useMemo(() => {
        return ((props) => (React.createElement(DocumentDrawerToggler, { ...props, id: id, collectionSlug: collectionSlug, drawerSlug: drawerSlug })));
    }, [id, drawerSlug, collectionSlug]);
    const MemoizedDrawerState = useMemo(() => ({
        drawerSlug,
        drawerDepth,
        isDrawerOpen: isOpen,
        toggleDrawer,
    }), [drawerDepth, drawerSlug, isOpen, toggleDrawer]);
    return [
        MemoizedDrawer,
        MemoizedDrawerToggler,
        MemoizedDrawerState,
    ];
};
