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

import type { CatalogEntityConfig, EntitiesCatalogConfig } from '@redocly/config';
import type { BffCatalogEntity, BffCatalogRelatedEntityList } from '@redocly/theme/core/types';

import { useThemeHooks } from '@redocly/theme/core/hooks';
import { CatalogEntityDefaultRelations } from '@redocly/theme/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityDefaultRelations';
import { CatalogEntityTeamRelations } from '@redocly/theme/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityTeamRelations';
import { CatalogEntityApiDescriptionRelations } from '@redocly/theme/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityApiDescriptionRelations';

export type CatalogEntityRelationsProps = {
  entity: BffCatalogEntity;
  entitiesCatalogConfig: EntitiesCatalogConfig;
  catalogConfig: CatalogEntityConfig;
  initialRelations: BffCatalogRelatedEntityList;
  initialFilter?: string;
  searchQuery: string;
  setSearchQuery: (query: string) => void;
};
const LOAD_MORE_THRESHOLD = 10;
const ENTITY_DEFAULT_FILTERS: Record<string, string> = {
  team: 'type:user',
  'api-description': 'type:api-operation',
};

export function CatalogEntityRelations({
  entity,
  entitiesCatalogConfig,
  initialRelations,
  catalogConfig,
  searchQuery,
  setSearchQuery,
}: CatalogEntityRelationsProps): JSX.Element | null {
  const { useCatalogSort, useFetchCatalogEntitiesRelations } = useThemeHooks();
  const { sortOption, setSortOption, handleSortClick, isColumnSorted } = useCatalogSort();

  const [filter, setFilter] = useState<string | undefined>(ENTITY_DEFAULT_FILTERS[entity.type]);

  useEffect(() => {
    setFilter(ENTITY_DEFAULT_FILTERS[entity.key]);
  }, [entity.key]);

  const combinedFilter = useMemo(() => {
    const baseFilter = filter ?? ENTITY_DEFAULT_FILTERS[entity.type];
    if (entity.version && entity.revision) {
      const versionFilter = `version:"${entity.version}"`;
      const revisionFilter = `revision:"${entity.revision}"`;
      return baseFilter
        ? `${baseFilter} AND ${versionFilter} AND ${revisionFilter}`
        : `${versionFilter} AND ${revisionFilter}`;
    }

    return baseFilter;
  }, [filter, entity.version, entity.type, entity.revision]);

  const { items: relations, query } = useFetchCatalogEntitiesRelations(
    {
      entityKey: entity.key,
      search: searchQuery,
      sort: sortOption ?? undefined,
      filter: combinedFilter,
      limit: 10,
    },
    initialRelations,
  );

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

  switch (entity.type) {
    case 'team':
      return (
        <div data-component-name="Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelations/CatalogEntityTeamRelations">
          <CatalogEntityTeamRelations
            entity={entity}
            catalogConfig={catalogConfig}
            entitiesCatalogConfig={entitiesCatalogConfig}
            relations={relations}
            query={query}
            searchQuery={searchQuery}
            setSearchQuery={setSearchQuery}
            setFilter={setFilter}
            sortOption={sortOption}
            setSortOption={setSortOption}
            handleSortClick={handleSortClick}
            isColumnSorted={isColumnSorted}
            shouldShowLoadMore={shouldShowLoadMore}
          />
        </div>
      );
    case 'api-description':
      return (
        <div data-component-name="Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelations/CatalogEntityApiDescriptionRelations">
          <CatalogEntityApiDescriptionRelations
            entity={entity}
            catalogConfig={catalogConfig}
            entitiesCatalogConfig={entitiesCatalogConfig}
            relations={relations}
            query={query}
            searchQuery={searchQuery}
            setSearchQuery={setSearchQuery}
            setFilter={setFilter}
            sortOption={sortOption}
            setSortOption={setSortOption}
            handleSortClick={handleSortClick}
            isColumnSorted={isColumnSorted}
            shouldShowLoadMore={shouldShowLoadMore}
          />
        </div>
      );
    default:
      return (
        <div data-component-name="Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelations/CatalogEntityDefaultRelations">
          <CatalogEntityDefaultRelations
            entity={entity}
            catalogConfig={catalogConfig}
            entitiesCatalogConfig={entitiesCatalogConfig}
            relations={relations}
            query={query}
            searchQuery={searchQuery}
            setSearchQuery={setSearchQuery}
            sortOption={sortOption}
            setSortOption={setSortOption}
            handleSortClick={handleSortClick}
            isColumnSorted={isColumnSorted}
            shouldShowLoadMore={shouldShowLoadMore}
          />
        </div>
      );
  }
}
