/**
 * SDK Catalog Manager - Central Registry
 *
 * Public API for browsing, searching, and converting catalog entries.
 * Registry data definitions live in catalog-registry-data.ts.
 */

import type {
  CatalogId,
  CatalogMeta,
  CatalogModule,
  CatalogEntry,
  CatalogStats,
  CatalogOverviewStats,
  CustomCatalogEntry,
  CustomCatalogs,
} from './types'

import { CATALOG_REGISTRY, SYSTEM_ENTRIES_MAP } from './catalog-registry-data'

// Re-export so existing imports keep working
export { CATALOG_REGISTRY }

// =============================================================================
// HELPER: Resolve localized text fields
// =============================================================================

function resolveField(value: unknown): string {
  if (value === null || value === undefined) return ''
  if (typeof value === 'string') return value
  if (typeof value === 'number') return String(value)
  if (typeof value === 'object' && 'de' in (value as Record<string, unknown>)) {
    return String((value as Record<string, string>).de || '')
  }
  return String(value)
}

// =============================================================================
// ENTRY CONVERTERS
// =============================================================================

function systemEntryToCatalogEntry(
  catalogId: CatalogId,
  data: Record<string, unknown>,
): CatalogEntry {
  const meta = CATALOG_REGISTRY[catalogId]
  const idValue = resolveField(data[meta.idField])
  const nameValue = resolveField(data[meta.nameField])
  const descValue = meta.descriptionField ? resolveField(data[meta.descriptionField]) : undefined
  const catValue = meta.categoryField ? resolveField(data[meta.categoryField]) : undefined

  return {
    id: idValue || crypto.randomUUID(),
    catalogId,
    source: 'system',
    data,
    displayName: nameValue || idValue || '(Unbenannt)',
    displayDescription: descValue,
    category: catValue,
  }
}

function customEntryToCatalogEntry(
  catalogId: CatalogId,
  entry: CustomCatalogEntry,
): CatalogEntry {
  const meta = CATALOG_REGISTRY[catalogId]
  const nameValue = resolveField(entry.data[meta.nameField])
  const descValue = meta.descriptionField ? resolveField(entry.data[meta.descriptionField]) : undefined
  const catValue = meta.categoryField ? resolveField(entry.data[meta.categoryField]) : undefined

  return {
    id: entry.id,
    catalogId,
    source: 'custom',
    data: entry.data,
    displayName: nameValue || '(Unbenannt)',
    displayDescription: descValue,
    category: catValue,
  }
}

// =============================================================================
// PUBLIC API
// =============================================================================

export function getSystemEntries(catalogId: CatalogId): CatalogEntry[] {
  const raw = SYSTEM_ENTRIES_MAP[catalogId] || []
  return raw.map(data => systemEntryToCatalogEntry(catalogId, data))
}

export function getAllEntries(
  catalogId: CatalogId,
  customEntries: CustomCatalogEntry[] = [],
): CatalogEntry[] {
  const system = getSystemEntries(catalogId)
  const custom = customEntries.map(e => customEntryToCatalogEntry(catalogId, e))
  return [...system, ...custom]
}

export function getCatalogsByModule(module: CatalogModule): CatalogMeta[] {
  return Object.values(CATALOG_REGISTRY).filter(c => c.module === module)
}

export function getCatalogStats(
  catalogId: CatalogId,
  customEntries: CustomCatalogEntry[] = [],
): CatalogStats {
  const meta = CATALOG_REGISTRY[catalogId]
  return {
    catalogId,
    systemCount: meta.systemCount,
    customCount: customEntries.length,
    totalCount: meta.systemCount + customEntries.length,
  }
}

export function getOverviewStats(customCatalogs: CustomCatalogs): CatalogOverviewStats {
  const modules: CatalogModule[] = ['dsfa', 'vvt', 'vendor', 'ai_act', 'reference']
  const byModule = {} as Record<CatalogModule, { catalogs: number; entries: number }>

  let totalSystemEntries = 0
  let totalCustomEntries = 0

  for (const mod of modules) {
    const cats = getCatalogsByModule(mod)
    let entries = 0
    for (const cat of cats) {
      const customCount = customCatalogs[cat.id]?.length ?? 0
      entries += cat.systemCount + customCount
      totalSystemEntries += cat.systemCount
      totalCustomEntries += customCount
    }
    byModule[mod] = { catalogs: cats.length, entries }
  }

  return {
    totalCatalogs: Object.keys(CATALOG_REGISTRY).length,
    totalSystemEntries,
    totalCustomEntries,
    totalEntries: totalSystemEntries + totalCustomEntries,
    byModule,
  }
}

export function searchCatalog(
  catalogId: CatalogId,
  query: string,
  customEntries: CustomCatalogEntry[] = [],
): CatalogEntry[] {
  const allEntries = getAllEntries(catalogId, customEntries)
  const meta = CATALOG_REGISTRY[catalogId]
  const q = query.toLowerCase().trim()

  if (!q) return allEntries

  return allEntries
    .map(entry => {
      let score = 0
      for (const field of meta.searchableFields) {
        const value = resolveField(entry.data[field]).toLowerCase()
        if (value.includes(q)) {
          score += value.startsWith(q) ? 10 : 5
        }
      }
      // Also search display name
      if (entry.displayName.toLowerCase().includes(q)) {
        score += 15
      }
      return { entry, score }
    })
    .filter(r => r.score > 0)
    .sort((a, b) => b.score - a.score)
    .map(r => r.entry)
}
