import { getAccessibleModules } from '@/business/app-shell/selectors';
import type { Module, ModuleId } from '@/shared/types/app';
import type { CurrentUser } from '@/shared/types/auth';

export type TopBarSearchResultKind = 'module' | 'content';

export interface TopBarSearchResult {
  /** Unique key across modules + content. */
  readonly id: string;
  readonly kind: TopBarSearchResultKind;
  readonly label: string;
  /** Secondary line — "Module", or the owning module's name for content. */
  readonly sublabel: string;
  /** Navigation target (module to open on select). */
  readonly moduleId: ModuleId;
}

/** A pre-mapped searchable content item (built from a content-catalog payload). */
export interface TopBarContentItem {
  readonly id: string;
  readonly label: string;
  readonly moduleId: ModuleId;
  readonly moduleName: string;
}

export const TOP_BAR_SEARCH_RESULT_LIMIT = 8;

function normalize(value: string): string {
  return value.trim().toLowerCase();
}

/** Accessible modules whose name (or id) matches the query. */
export function searchModules(
  modules: readonly Module[],
  user: CurrentUser | null | undefined,
  query: string,
): TopBarSearchResult[] {
  const normalized = normalize(query);
  if (!normalized) {
    return [];
  }

  return getAccessibleModules(modules, user)
    .filter(
      (module) =>
        module.name.toLowerCase().includes(normalized) ||
        module.id.includes(normalized),
    )
    .map((module) => ({
      id: `module:${module.id}`,
      kind: 'module' as const,
      label: module.name,
      sublabel: 'Module',
      moduleId: module.id,
    }));
}

/** Pre-mapped content items whose label matches the query. */
export function searchContentItems(
  items: readonly TopBarContentItem[],
  query: string,
): TopBarSearchResult[] {
  const normalized = normalize(query);
  if (!normalized) {
    return [];
  }

  return items
    .filter((item) => item.label.toLowerCase().includes(normalized))
    .map((item) => ({
      id: `content:${item.moduleId}:${item.id}`,
      kind: 'content' as const,
      label: item.label,
      sublabel: item.moduleName,
      moduleId: item.moduleId,
    }));
}

/** Combined, capped results: modules first, then content. */
export function buildTopBarSearchResults(
  modules: readonly Module[],
  user: CurrentUser | null | undefined,
  query: string,
  contentItems: readonly TopBarContentItem[],
  limit: number = TOP_BAR_SEARCH_RESULT_LIMIT,
): TopBarSearchResult[] {
  if (!normalize(query)) {
    return [];
  }

  return [
    ...searchModules(modules, user, query),
    ...searchContentItems(contentItems, query),
  ].slice(0, limit);
}
