import React, { useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Label, LabelPermissionsMember } from 'backend-api/models';
import { bem } from 'utils/bem';
import { ReusableTable, EmptyViewMode } from 'label-permissions/components';
import { GridApi } from 'ag-grid-community';
import { getLabelTeamMembers, openEditArtistsModal } from 'label-permissions/actions';
import { teamMembersSelector } from 'label-permissions/selectors';
import { EditArtistsModalPayload } from 'label-permissions/types';
import { EditArtistsContainer } from '../edit-artists-container';
import { buildTableConfig } from './transducers';
import { useTeamMembers } from './hooks';
import { BEM_CLASS, SMembersTable } from './s-members-table-container';
import { useAppContext } from 'common-v2/hooks';

interface TeamMembersTableProps {
  search: string;
  label?: Label;
}

const classes = bem(BEM_CLASS);

export const MembersTableContainer = React.memo(({ search, label }: TeamMembersTableProps) => {
  const dispatch = useDispatch();
  const { user: currentUser } = useAppContext();
  const { teamMembers, isSearchActive } = useTeamMembers(search);

  const { loading: teamMembersLoading } = useSelector(teamMembersSelector);

  const openEditArtists = useCallback(
    (payload: EditArtistsModalPayload) => {
      dispatch(openEditArtistsModal(payload));
    },
    [dispatch]
  );

  const fetchTableData = useCallback(() => {
    if (!label?.id) return;
    dispatch(getLabelTeamMembers.request(label.id));
  }, [dispatch, label?.id]);

  const getTableConfig = useCallback(
    (emptyViewMode: EmptyViewMode) =>
      buildTableConfig({
        classNames: { artistsCell: classes('artists-cell') },
        openEditArtistsModal: openEditArtists,
        isSortingDisabled: emptyViewMode !== EmptyViewMode.None,
        isUserAdmin: Boolean(currentUser?.isAdmin),
      }),
    [currentUser?.isAdmin, openEditArtists]
  );

  const onTableResize = useCallback((api: GridApi<LabelPermissionsMember[]>) => {
    // NOTE: Avoid redraw rows on the middle of another drawing process
    queueMicrotask(() => {
      api.redrawRows();
    });
  }, []);

  return (
    <SMembersTable>
      <ReusableTable<LabelPermissionsMember>
        data={teamMembers}
        loading={teamMembersLoading}
        getTableConfig={getTableConfig}
        fetchData={fetchTableData}
        isSearchActive={isSearchActive}
        onTableResize={onTableResize}
        errorMessage={
          <span>
            An error occurred while loading the
            <br />
            Team Members data, please try again.
          </span>
        }
        emptyMessage="There are no team members in this label."
      />

      <EditArtistsContainer onDataUpdated={fetchTableData} />
    </SMembersTable>
  );
});
