import * as React from 'react';

import { useNotification } from '../features/Notifications';
import { useRBACProvider } from '../features/RBAC';
import { hasPermissions } from '../utils/hasPermissions';

import type { domain } from '@strapi/permissions';

type Permission = domain.permission.Permission;

// NOTE: this component is very similar to the CheckPagePermissions
// except that it does not handle redirections nor loading state

export interface CheckPermissionsProps {
  children: React.ReactNode;
  permissions?: Permission[];
}

const CheckPermissions = ({ permissions = [], children }: CheckPermissionsProps) => {
  const { allPermissions } = useRBACProvider();
  const toggleNotification = useNotification();
  const [state, setState] = React.useState({ isLoading: true, canAccess: false });
  const isMounted = React.useRef(true);
  const abortController = new AbortController();
  const { signal } = abortController;

  React.useEffect(() => {
    const checkPermission = async () => {
      try {
        setState({ isLoading: true, canAccess: false });

        const canAccess = await hasPermissions(allPermissions || [], permissions, signal);

        if (isMounted.current) {
          setState({ isLoading: false, canAccess });
        }
      } catch (err) {
        if (isMounted.current) {
          console.error(err);
          toggleNotification?.({
            type: 'warning',
            message: { id: 'notification.error' },
          });

          setState({ isLoading: false, canAccess: false });
        }
      }
    };

    checkPermission();

    return () => {
      abortController.abort();
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [permissions]);

  React.useEffect(() => {
    return () => {
      isMounted.current = false;
    };
  }, []);

  if (state.isLoading) {
    return null;
  }

  if (!state.canAccess) {
    return null;
  }

  return <>{children}</>;
};

export { CheckPermissions };
