import { memo, useCallback, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';

import LibrariesSidebar from '@material-hu/components/composed-components/LibrariesSidebar';
import { SidebarWrapper } from '@material-hu/components/composed-components/LibrariesSidebar/components/SidebarWrapper';
import { type SortedItem } from '@material-hu/components/composed-components/LibrariesSidebar/types';
import { getNewPositionOrders } from '@material-hu/components/composed-components/LibrariesSidebar/utils';
import { useDrawerLayer } from '@material-hu/components/layers/Drawers';

import { queryClient } from 'src/config/react-query';

import { useArticleId } from '../hooks/useArticleId';
import { useBulkUpdatePosition } from '../hooks/useBulkUpdatePositions';
import { getArticleQueryOptions, useGetArticle } from '../hooks/useGetArticle';
import { useSidebarModel } from '../hooks/useSidebarModel';
import { huLibrariesRoutes } from '../routes';
import { getCachedArticleById } from '../utils';

import CreateArticleDrawer from './CreateArticleDrawer';
import { SidebarSearchBar } from './SidebarSearch';

const MemoizedLibrariesSidebar = memo(LibrariesSidebar);

export const Sidebar = memo(() => {
  const { rootId } = useArticleId();
  const navigate = useNavigate();

  const { data: article } = useGetArticle(rootId);
  const canManageArticle = Boolean(article?.isEditor && rootId);

  const { mutate: bulkUpdatePosition } = useBulkUpdatePosition(rootId);

  const { model, isLoading, onItemClick } = useSidebarModel(
    canManageArticle,
    rootId,
  );

  const capabilities = useMemo(
    () => ({
      canCreate: canManageArticle,
      showStatusBadge: canManageArticle,
    }),
    [canManageArticle],
  );

  const { openDrawer } = useDrawerLayer();

  const handleAdd = useCallback(
    (articleId?: number) =>
      openDrawer({
        content: <CreateArticleDrawer articleId={articleId ?? null} />,
      }),
    [openDrawer],
  );

  const handleSort = useCallback(
    (payload: SortedItem[]) =>
      bulkUpdatePosition({ orders: getNewPositionOrders(payload) }),
    [bulkUpdatePosition],
  );

  const handleAddMouseEnter = useCallback((articleId?: number) => {
    if (!articleId) return;
    const cachedArticle = getCachedArticleById(articleId);
    if (cachedArticle) return;
    queryClient.prefetchQuery(getArticleQueryOptions(articleId));
  }, []);

  const handleNavigateBack = useCallback(
    () => navigate(huLibrariesRoutes.base()),
    [navigate],
  );

  const onAdd = useMemo(
    () => (canManageArticle ? handleAdd : undefined),
    [canManageArticle, handleAdd],
  );

  const onSort = useMemo(
    () => (canManageArticle ? handleSort : undefined),
    [canManageArticle, handleSort],
  );

  return (
    <SidebarWrapper>
      <SidebarSearchBar />
      <MemoizedLibrariesSidebar
        model={model}
        capabilities={capabilities}
        parentId={rootId}
        loading={isLoading}
        onBack={handleNavigateBack}
        onItemClick={onItemClick}
        onAddMouseEnter={handleAddMouseEnter}
        onAdd={onAdd}
        onSort={onSort}
      />
    </SidebarWrapper>
  );
});
