import React, { JSX, useEffect } from 'react';

import type { CatalogEntityConfig } from '@redocly/config';

import { BffCatalogEntity, BffCatalogEntityList } from '@redocly/theme/core/types';
import {
  useThemeHooks,
  useCatalogEntities,
  useCatalogEntityDetails,
} from '@redocly/theme/core/hooks';
import { ArrowDownIcon } from '@redocly/theme/icons/ArrowDownIcon/ArrowDownIcon';
import { CatalogCardView } from '@redocly/theme/components/Catalog/CatalogCardView/CatalogCardView';
import { CatalogTableView } from '@redocly/theme/components/Catalog/CatalogTableView/CatalogTableView';
import { HighlightContext } from '@redocly/theme/components/Catalog/CatalogHighlight';
import { LoadMore } from '@redocly/theme/components/LoadMore/LoadMore';
import { CatalogEntitiesEmptyState } from '@redocly/theme/components/Catalog/CatalogEntitiesEmptyState';

export type CatalogEntitiesProps = {
  catalogConfig: CatalogEntityConfig;
  excludedEntities?: CatalogEntityConfig['excludes'];
  filterQuery: string;
  entitiesTypes: string[];
  searchQuery: string;
  viewMode: string;
  setEntitiesCounter: (counter: number) => void;
  initialEntitiesList?: BffCatalogEntityList;
  sortOption: string | null;
  handleSortClick: (sortKey: string, direction: 'asc' | 'desc') => void;
  isColumnSorted: (sortKey: string, direction: 'asc' | 'desc') => boolean;
};

const LOAD_MORE_THRESHOLD = 10;

export function CatalogEntities(props: CatalogEntitiesProps): JSX.Element {
  const {
    catalogConfig,
    excludedEntities,
    filterQuery,
    entitiesTypes,
    sortOption,
    searchQuery,
    viewMode,
    setEntitiesCounter,
    handleSortClick,
    isColumnSorted,
  } = props;

  const { getEntityDetailsLink } = useCatalogEntityDetails({
    catalogConfig,
  });
  const { useTelemetry, useFetchCatalogEntities } = useThemeHooks();
  const telemetry = useTelemetry();
  const { initialFilter } = useCatalogEntities({
    entitiesTypes,
    excludedEntities,
  });

  const {
    items: entities,
    query,
    total,
  } = useFetchCatalogEntities(
    {
      limit: LOAD_MORE_THRESHOLD,
      filter:
        initialFilter && filterQuery
          ? `(${initialFilter}) AND (${filterQuery})`
          : initialFilter || filterQuery,
      sort: sortOption || (viewMode === 'table' ? 'updated_at' : 'type,title'),
      search: searchQuery,
    },
    props.initialEntitiesList,
  );

  const onRowClick = (entity: BffCatalogEntity) => {
    if (searchQuery) {
      telemetry.sendCatalogEntitiesListSearchResultClickedMessage([
        {
          id: entity.id,
          object: 'catalog_entity',
          uri: getEntityDetailsLink(entity),
          query: searchQuery,
          entityKey: entity.key,
          entityType: entity.type,
        },
      ]);
    }
  };

  const shouldShowLoadMore =
    query.hasNextPage ||
    (query.isPlaceholderData && entities && entities.length >= LOAD_MORE_THRESHOLD);

  useEffect(() => {
    setEntitiesCounter(total || 0);
  }, [total, setEntitiesCounter]);

  if (!query.isPending && (!entities || entities.length === 0)) {
    return <CatalogEntitiesEmptyState />;
  }

  return (
    <HighlightContext.Provider value={[searchQuery]} data-component-name="Catalog/CatalogEntities">
      {viewMode === 'cards' ? (
        <CatalogCardView entities={entities} catalogConfig={catalogConfig} />
      ) : (
        <CatalogTableView<BffCatalogEntity>
          entities={entities}
          catalogConfig={catalogConfig}
          currentSortOption={sortOption}
          handleSortClick={handleSortClick}
          isColumnSorted={isColumnSorted}
          onRowClick={onRowClick}
        />
      )}

      {shouldShowLoadMore && (
        <LoadMore
          icon={<ArrowDownIcon size="var(--catalog-load-more-icon-size)" />}
          onClick={query.fetchNextPage}
          disabled={query.isFetchingNextPage}
          blinking={query.isFetchingNextPage}
          label={query.isFetchingNextPage ? 'Loading...' : 'Load More'}
        />
      )}
    </HighlightContext.Provider>
  );
}
