import { useMemo } from 'react';

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

export type EntityWithTypeAndKey = { type?: string; key?: string };

function isEntityExcluded(
  excludes: Array<{ key: string }> | undefined,
  entityKey: string,
): boolean {
  return excludes?.some((ex) => ex.key === entityKey) ?? false;
}

function doesCatalogIncludeEntityType(
  config: { includes?: Array<{ type: string }> },
  entityType: string,
): boolean {
  const hasNoIncludes = !config.includes || config.includes.length === 0;
  if (hasNoIncludes) return true;
  return config.includes?.some((inc) => inc.type === entityType) ?? false;
}

export function useCatalogEntityLink(entitiesCatalogConfig: EntitiesCatalogConfig | undefined) {
  const catalogEntries = useMemo(() => {
    const catalogs = entitiesCatalogConfig?.catalogs;
    if (!catalogs) return [];
    return Object.entries(catalogs)
      .filter((entry): entry is [string, NonNullable<(typeof entry)[1]>] => entry[1] != null)
      .sort(([keyA], [keyB]) => (keyA === 'all' ? 1 : 0) - (keyB === 'all' ? 1 : 0));
  }, [entitiesCatalogConfig]);

  const getEntityLink = (entity: EntityWithTypeAndKey): string | undefined => {
    if (!entity?.key) return undefined;
    const entityType = entity.type ?? '';

    for (const [catalogKey, config] of catalogEntries) {
      if (isEntityExcluded(config.excludes, entity.key)) continue;
      if (!doesCatalogIncludeEntityType(config, entityType)) continue;
      const slug = config.slug ?? catalogKey;
      return `catalogs/${slug}/entities/${entity.key}`;
    }
    return undefined;
  };

  return { getEntityLink };
}
