/**
 * commerce blueprint · wiring seam for `@platform-modules/search`.
 *
 * Adapter-minimalism (CLAUDE.md §4): register ONE entity provider ('product') backed by an in-memory
 * list and expose searchEntities over it. A real host's provider runs a Postgres FTS query; the module
 * sanitizes the user query into a prefix-tsquery internally (`@platform-modules/util/fts`) before the
 * provider sees it — so this in-memory provider recovers the bare lexemes and AND-matches them rather
 * than substring-matching the raw tsquery string.
 */
import {
  searchEntities,
  type Hit,
  type SearchProvider,
  type SearchRegistry,
  type SearchResult,
} from '@platform-modules/search'

export type IndexedProduct = { id: string; title: string; description: string }

export type ProductIndex = {
  add(product: IndexedProduct): void
  registry: SearchRegistry<IndexedProduct[]>
  search(query: string): Promise<SearchResult>
}

/** Recover bare lexemes from a sanitized prefix-tsquery (`foo:* & bar:*` → `['foo','bar']`). */
function lexemes(sanitized: string): string[] {
  return sanitized
    .split('&')
    .map((token) => token.replace(/:\*/g, '').trim().toLowerCase())
    .filter(Boolean)
}

export function createProductIndex(): ProductIndex {
  const products: IndexedProduct[] = []

  const productProvider: SearchProvider<IndexedProduct[]> = async (query, ctx, window) => {
    const tokens = lexemes(query)
    const matched =
      tokens.length === 0
        ? []
        : ctx.filter((product) => {
            const haystack = `${product.title} ${product.description}`.toLowerCase()
            return tokens.every((token) => haystack.includes(token))
          })
    const hits: Hit[] = matched
      .slice(window.offset, window.offset + window.limit)
      .map((product, i) => ({ entityType: 'product', id: product.id, rank: 1 - i / 100, title: product.title }))
    return { hits, total: matched.length }
  }

  const registry: SearchRegistry<IndexedProduct[]> = { product: productProvider }

  return {
    add(product) {
      products.push(product)
    },
    registry,
    search(query) {
      return searchEntities(registry, { query, ctx: products, entityTypes: ['product'], limit: 10 })
    },
  }
}
