'use client';

import { jsx as _jsx } from "react/jsx-runtime";
import { formatAdminURL } from 'payload/shared';
import * as qs from 'qs-esm';
import React, { createContext, use, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useControllableState } from '../../hooks/useControllableState.js';
import { useAuth } from '../../providers/Auth/index.js';
import { requests } from '../../utilities/api.js';
import { formatDocTitle } from '../../utilities/formatDocTitle/index.js';
import { useConfig } from '../Config/index.js';
import { DocumentTitleProvider } from '../DocumentTitle/index.js';
import { useLocale, useLocaleLoading } from '../Locale/index.js';
import { usePreferences } from '../Preferences/index.js';
import { useTranslation } from '../Translation/index.js';
import { UploadEditsProvider, useUploadEdits } from '../UploadEdits/index.js';
import { useGetDocPermissions } from './useGetDocPermissions.js';
const Context = /*#__PURE__*/createContext({});
export const useDocumentInfo = () => use(Context);
const DocumentInfo = ({
  children,
  ...props
}) => {
  const {
    id,
    collectionSlug,
    currentEditor: currentEditorFromProps,
    docPermissions: docPermissionsFromProps,
    globalSlug,
    hasPublishedDoc: hasPublishedDocFromProps,
    hasPublishPermission: hasPublishPermissionFromProps,
    hasSavePermission: hasSavePermissionFromProps,
    initialData,
    initialState,
    isLocked: isLockedFromProps,
    lastUpdateTime: lastUpdateTimeFromProps,
    mostRecentVersionIsAutosaved: mostRecentVersionIsAutosavedFromProps,
    unpublishedVersionCount: unpublishedVersionCountFromProps,
    versionCount: versionCountFromProps
  } = props;
  const [docPermissions, setDocPermissions] = useControllableState(docPermissionsFromProps);
  const [hasSavePermission, setHasSavePermission] = useControllableState(hasSavePermissionFromProps);
  const [hasPublishPermission, setHasPublishPermission] = useControllableState(hasPublishPermissionFromProps);
  const {
    permissions
  } = useAuth();
  const {
    config: {
      admin: {
        dateFormat
      },
      routes: {
        api
      }
    },
    getEntityConfig
  } = useConfig();
  const collectionConfig = getEntityConfig({
    collectionSlug
  });
  const globalConfig = getEntityConfig({
    globalSlug
  });
  const abortControllerRef = useRef(new AbortController());
  const docConfig = collectionConfig || globalConfig;
  const {
    i18n
  } = useTranslation();
  const {
    uploadEdits
  } = useUploadEdits();
  /**
  * @deprecated This state will be removed in v4.
  * This is for performance reasons. Use the `DocumentTitleContext` instead.
  */
  const [title, setDocumentTitle] = useState(() => formatDocTitle({
    collectionConfig,
    data: {
      ...(initialData || {}),
      id
    },
    dateFormat,
    fallback: id?.toString(),
    globalConfig,
    i18n
  }));
  const [mostRecentVersionIsAutosaved, setMostRecentVersionIsAutosaved] = useState(mostRecentVersionIsAutosavedFromProps);
  const [versionCount, setVersionCount] = useState(versionCountFromProps);
  const [hasPublishedDoc, setHasPublishedDoc] = useState(hasPublishedDocFromProps);
  const [unpublishedVersionCount, setUnpublishedVersionCount] = useState(unpublishedVersionCountFromProps);
  const [documentIsLocked, setDocumentIsLocked] = useControllableState(isLockedFromProps);
  const [currentEditor, setCurrentEditor] = useControllableState(currentEditorFromProps);
  const [lastUpdateTime, setLastUpdateTime] = useControllableState(lastUpdateTimeFromProps);
  const [data, setData] = useControllableState(initialData);
  const [uploadStatus, setUploadStatus] = useControllableState('idle');
  const documentLockState = useRef({
    hasShownLockedModal: false,
    isLocked: false,
    user: null
  });
  const updateUploadStatus = useCallback(status => {
    setUploadStatus(status);
  }, [setUploadStatus]);
  const {
    getPreference,
    setPreference
  } = usePreferences();
  const {
    code: locale
  } = useLocale();
  const {
    localeIsLoading
  } = useLocaleLoading();
  const isInitializing = useMemo(() => initialState === undefined || initialData === undefined || localeIsLoading, [initialData, initialState, localeIsLoading]);
  const baseAPIPath = formatAdminURL({
    apiRoute: api,
    path: ''
  });
  let slug;
  let pluralType;
  let preferencesKey;
  if (globalSlug) {
    slug = globalSlug;
    pluralType = 'globals';
    preferencesKey = `global-${slug}`;
  }
  if (collectionSlug) {
    slug = collectionSlug;
    pluralType = 'collections';
    if (id) {
      preferencesKey = `collection-${slug}-${id}`;
    }
  }
  const unlockDocument = useCallback(async (docID, slug_0) => {
    try {
      const isGlobal = slug_0 === globalSlug;
      const request = await requests.get(`${baseAPIPath}/payload-locked-documents`, {
        credentials: 'include',
        params: isGlobal ? {
          'where[globalSlug][equals]': slug_0
        } : {
          'where[document.relationTo][equals]': slug_0,
          'where[document.value][equals]': docID
        }
      });
      const {
        docs
      } = await request.json();
      if (docs?.length > 0) {
        const lockID = docs[0].id;
        await requests.delete(`${baseAPIPath}/payload-locked-documents/${lockID}`, {
          credentials: 'include',
          headers: {
            'Content-Type': 'application/json'
          }
        });
        setDocumentIsLocked(false);
      }
    } catch (error) {
      // eslint-disable-next-line no-console
      console.error('Failed to unlock the document', error);
    }
  }, [baseAPIPath, globalSlug, setDocumentIsLocked]);
  const updateDocumentEditor = useCallback(async (docID_0, slug_1, user) => {
    try {
      const isGlobal_0 = slug_1 === globalSlug;
      // Check if the document is already locked
      const request_0 = await requests.get(`${baseAPIPath}/payload-locked-documents`, {
        credentials: 'include',
        params: isGlobal_0 ? {
          'where[globalSlug][equals]': slug_1
        } : {
          'where[document.relationTo][equals]': slug_1,
          'where[document.value][equals]': docID_0
        }
      });
      const {
        docs: docs_0
      } = await request_0.json();
      if (docs_0?.length > 0) {
        const lockID_0 = docs_0[0].id;
        const userData = typeof user === 'object' ? {
          relationTo: user.collection,
          value: user.id
        } : {
          relationTo: 'users',
          value: user
        };
        // Send a patch request to update the _lastEdited info
        await requests.patch(`${baseAPIPath}/payload-locked-documents/${lockID_0}`, {
          body: JSON.stringify({
            user: userData
          }),
          credentials: 'include',
          headers: {
            'Content-Type': 'application/json'
          }
        });
      }
    } catch (error_0) {
      // eslint-disable-next-line no-console
      console.error('Failed to update the document editor', error_0);
    }
  }, [baseAPIPath, globalSlug]);
  const getDocPermissions = useGetDocPermissions({
    id: id,
    api,
    collectionSlug,
    globalSlug,
    i18n,
    locale,
    permissions,
    setDocPermissions,
    setHasPublishPermission,
    setHasSavePermission
  });
  const getDocPreferences = useCallback(() => {
    return getPreference(preferencesKey);
  }, [getPreference, preferencesKey]);
  const setDocFieldPreferences = useCallback(async (path, fieldPreferences) => {
    const allPreferences = await getDocPreferences();
    if (preferencesKey) {
      try {
        await setPreference(preferencesKey, {
          ...allPreferences,
          fields: {
            ...(allPreferences?.fields || {}),
            [path]: {
              ...allPreferences?.fields?.[path],
              ...fieldPreferences
            }
          }
        });
      } catch (e) {
        console.error(e); // eslint-disable-line no-console
      }
    }
  }, [setPreference, preferencesKey, getDocPreferences]);
  const incrementVersionCount = useCallback(() => {
    const newCount = versionCount + 1;
    if (collectionConfig && collectionConfig.versions) {
      if (collectionConfig.versions.maxPerDoc > 0) {
        setVersionCount(Math.min(newCount, collectionConfig.versions.maxPerDoc));
      } else {
        setVersionCount(newCount);
      }
    } else if (globalConfig && globalConfig.versions) {
      if (globalConfig.versions.max > 0) {
        setVersionCount(Math.min(newCount, globalConfig.versions.max));
      } else {
        setVersionCount(newCount);
      }
    }
  }, [collectionConfig, globalConfig, versionCount]);
  /**
  * @todo: Remove this in v4
  * Users should use the `DocumentTitleContext` instead.
  */
  useEffect(() => {
    setDocumentTitle(formatDocTitle({
      collectionConfig,
      data: {
        ...data,
        id
      },
      dateFormat,
      fallback: id?.toString(),
      globalConfig,
      i18n
    }));
  }, [collectionConfig, globalConfig, data, dateFormat, i18n, id]);
  // clean on unmount
  useEffect(() => {
    const re1 = abortControllerRef.current;
    return () => {
      if (re1) {
        try {
          re1.abort();
        } catch (_err) {
          // swallow error
        }
      }
    };
  }, []);
  const action = React.useMemo(() => {
    const docPath = `${pluralType === 'globals' ? `/globals` : ''}/${slug}${id ? `/${id}` : ''}`;
    return `${baseAPIPath}${docPath}${qs.stringify({
      depth: 0,
      'fallback-locale': 'null',
      locale,
      uploadEdits: uploadEdits || undefined
    }, {
      addQueryPrefix: true
    })}`;
  }, [baseAPIPath, locale, pluralType, id, slug, uploadEdits]);
  const value = {
    ...props,
    action,
    currentEditor,
    data,
    docConfig,
    docPermissions,
    documentIsLocked,
    documentLockState,
    getDocPermissions,
    getDocPreferences,
    hasPublishedDoc,
    hasPublishPermission,
    hasSavePermission,
    incrementVersionCount,
    initialData,
    initialState,
    isInitializing,
    lastUpdateTime,
    mostRecentVersionIsAutosaved,
    preferencesKey,
    savedDocumentData: data,
    setCurrentEditor,
    setData,
    setDocFieldPreferences,
    setDocumentIsLocked,
    setDocumentTitle,
    setHasPublishedDoc,
    setLastUpdateTime,
    setMostRecentVersionIsAutosaved,
    setUnpublishedVersionCount,
    setUploadStatus: updateUploadStatus,
    title,
    unlockDocument,
    unpublishedVersionCount,
    updateDocumentEditor,
    updateSavedDocumentData: setData,
    uploadStatus,
    versionCount
  };
  return /*#__PURE__*/_jsx(Context, {
    value: value,
    children: /*#__PURE__*/_jsx(DocumentTitleProvider, {
      children: children
    })
  });
};
export const DocumentInfoProvider = props => {
  return /*#__PURE__*/_jsx(UploadEditsProvider, {
    children: /*#__PURE__*/_jsx(DocumentInfo, {
      ...props
    })
  });
};
//# sourceMappingURL=index.js.map