import React, { useCallback, useLayoutEffect, useRef } from 'react';

import {
  ChannelsSearchDialog,
  CreateChannelDialog,
  OpenDmDialog,
} from 'components/dialogs';
import { ChatContext, IChatContext, withContext } from 'context';
import { UserContactsPreviewComponent } from 'shared/components/contacts-preview/intex';
import {
  UserChannelsPreviewComponent,
  UserDmsPreviewComponent,
} from 'shared/graphql/__generated__';
import { SectionsConfig } from 'types';

import ChannelsSection from './components/channels-section';
import ContactsSection from './components/contacts-section';
import DmsSection from './components/dms-section';
import Toolbar from './components/toolbar';
import css from './sidebar.module.css';

// -- TYPES

interface ISidebarProps
  extends Pick<
    IChatContext,
    'setChannel' | 'user' | 'openedChannel' | 'usersFilter' | 'channelMembersFilter'
  > {
  sections: SectionsConfig;
  onClose: (() => void) | undefined;
}

// -- MAIN

const cnSection = {
  section: css.section,
  item: css['section-item'],
};
const slideIn = css.slideIn;
const Sidebar = React.memo(function Sidebar({
  user,
  setChannel,
  openedChannel,
  sections,
  onClose,
  usersFilter,
  channelMembersFilter,
}: ISidebarProps) {
  const userId = user ? user.id : '';
  const sidebarRef = useRef<HTMLDivElement>(null);
  const closeRef = useRef<boolean>(false);

  useLayoutEffect(() => {
    const sidebarContainer = sidebarRef.current;
    setTimeout(() => {
      if (sidebarContainer) {
        sidebarContainer.classList.add(slideIn);
      }
    }, 0);
  }, []);
  const onCloseTransition = () => {
    if (closeRef.current && onClose) {
      onClose();
    }
  };
  const closeCallback = useCallback(() => {
    closeRef.current = true;
    const sidebarContainer = sidebarRef.current;
    if (sidebarContainer) {
      sidebarContainer.classList.remove(slideIn);
    }
  }, []);
  return (
    <div className={css.base} ref={sidebarRef} onTransitionEnd={onCloseTransition}>
      <Toolbar onClose={closeCallback} />
      <div className={css.sections}>
        {sections.channels && (
          <UserChannelsPreviewComponent
            variables={{ channelMembersFilter }}
            context={{ important: true }}
          >
            {({ data }) => {
              const channelIdentities = data && data.user && data.user.channelIdentities;

              return (
                <ChannelsSection
                  className={cnSection}
                  currentUser={user}
                  setChannel={setChannel}
                  channelIdentities={channelIdentities}
                />
              );
            }}
          </UserChannelsPreviewComponent>
        )}

        {sections.dm && (
          <UserDmsPreviewComponent
            variables={{ channelMembersFilter }}
            context={{ important: true }}
          >
            {({ data }) => {
              const channelIdentities = data && data.user && data.user.channelIdentities;

              return (
                <DmsSection
                  className={cnSection}
                  currentUser={user}
                  setChannel={setChannel}
                  channelIdentities={channelIdentities}
                />
              );
            }}
          </UserDmsPreviewComponent>
        )}

        {sections.contacts && (
          <UserContactsPreviewComponent
            variables={{
              filter: usersFilter || {
                id: {
                  not_in: [userId],
                },
              },
            }}
          >
            {({ data }) => {
              const users = data && data.usersList && data.usersList.items;

              return (
                <ContactsSection
                  className={cnSection}
                  currentUser={user}
                  users={users}
                  setChannel={setChannel}
                  openedChannel={openedChannel}
                />
              );
            }}
          </UserContactsPreviewComponent>
        )}
      </div>

      <ChannelsSearchDialog />
      <CreateChannelDialog />
      <OpenDmDialog />
    </div>
  );
});

export default withContext<ISidebarProps, IChatContext>({
  context: ChatContext,
  keys: ['setChannel', 'user', 'openedChannel', 'usersFilter', 'channelMembersFilter'],
})(Sidebar);
