import React, { useCallback, useMemo } from 'react';
import { bem } from 'utils/bem';
import { Table as ProjectsTable, TableContent } from 'common/components/table';
import { Pagination } from 'common/components/pagination';
import { BEM_CLASS, STable } from './s-table';
import { LoadingState } from 'common/types';
import { ProjectSortField } from 'backend-api/types';
import { Sort } from 'utils/sort';
import { ProjectsTab } from 'artist/types';
import { useActiveTab, useProjectsFilters } from 'artist/hooks';
import { usePagination } from 'hooks';
import { DEFAULT_SORT } from 'projects/constants';
import { Notification } from './components';
import { useDispatch, useSelector } from 'react-redux';
import { artistSelector, permissionsSelector } from 'artist/selectors';
import { disablePermissionsNotification } from 'artist/actions';
import { NoResults } from 'common/components/no-results';
import NoProjectsGraySvg from 'assets/no-projects-gray.svg';
import { TableTheme } from 'app/theme/table';
import { Project } from 'backend-api/models';

const classes = bem(BEM_CLASS);

interface TableProps {
  artistId: string;
  loading: LoadingState;
  query?: string;
  headerContent: TableContent<Project, ProjectSortField>[];
  bodyContent: Project[];
  totalCount: number;
}

export const Table = React.memo(({ artistId, loading, query, headerContent, bodyContent, totalCount }: TableProps) => {
  const dispatch = useDispatch();
  const isTableSearching = !!query && query.length > 0;

  const [filters, filtersDispatcher] = useProjectsFilters(artistId);
  const [activeTab] = useActiveTab(artistId);
  const { data: artistData } = useSelector(artistSelector);

  const filtersByStatus = useMemo(() => (filters.status ? filters.filtersByStatus[filters.status.id] : {}), [
    filters.filtersByStatus,
    filters.status,
  ]);
  const sort = useMemo(() => filtersByStatus.sort ?? DEFAULT_SORT, [filtersByStatus]);
  const pagination = usePagination(filtersByStatus, totalCount);
  const permissions = useSelector(permissionsSelector);

  const emptyProjects = useMemo(() => {
    if (loading !== LoadingState.Failed && !isTableSearching && bodyContent.length === 0) {
      let emptyMessageEnd = '';

      switch (activeTab) {
        case ProjectsTab.InProgress:
          emptyMessageEnd = 'projects in progress';
          break;
        case ProjectsTab.Upcoming:
          emptyMessageEnd = 'upcoming projects';
          break;
        case ProjectsTab.Completed:
          emptyMessageEnd = 'completed projects';
          break;
        case ProjectsTab.Unassigned:
          emptyMessageEnd = 'unassigned projects';
          break;
      }

      return (
        <NoResults
          withoutFiltersImage={NoProjectsGraySvg}
          withoutFiltersMessage={`${artistData?.info.name ?? 'Artist'} doesn't have any ${emptyMessageEnd}.`}
          dataSelector="artist-project-no-results"
        />
      );
    }

    return undefined;
  }, [activeTab, artistData?.info.name, bodyContent.length, isTableSearching, loading]);

  const onSortChange = useCallback(
    (sort: Sort<ProjectSortField>) => {
      filtersDispatcher.setSort(sort);
    },
    [filtersDispatcher]
  );
  const onPaginationChange = useCallback(
    (pagination: Pagination) => {
      filtersDispatcher.setPagination(pagination);
    },
    [filtersDispatcher]
  );
  const onNotificationClose = useCallback(() => {
    dispatch(disablePermissionsNotification());
  }, [dispatch]);

  return (
    <STable>
      <ProjectsTable
        tableContainerClassName={classes('container')}
        paginationClassName={classes('pagination')}
        dataSelector="artists-projects-table"
        headerContent={headerContent}
        bodyContent={bodyContent}
        theme={TableTheme.WHITE}
        sort={sort}
        onSortChange={onSortChange}
        pagination={pagination}
        onPaginationChange={onPaginationChange}
        isScrollable
        isSearching={isTableSearching}
        isLoading={loading === LoadingState.Started}
        isLoadingFailed={loading === LoadingState.Failed}
        notification={<Notification labels={permissions.unavailableLabels} onClose={onNotificationClose} />}
        isNotificationVisible={permissions.isNotificationVisible}
        noResultComponent={emptyProjects}
      />
    </STable>
  );
});
