import { describe, expect, it, vi } from 'vitest'

import { buildTsquery } from '../../../../../../packages/db/src/search/build-tsquery'

describe('search platform parity', () => {
  it('sanitizes queries identically to the legacy tsquery builder', async () => {
    const calls: string[] = []
    const { runPlatformSearch } = await import('../search')

    await runPlatformSearch({
      query: `inv (foo) & bar:* 'quoted'`,
      entityTypes: ['customer'],
      limit: 5,
      ctx: {
        db: {} as never,
        tenantId: 'tenant-1',
        userId: 'user-1',
        isContractor: false,
      },
      registry: {
        customer: async (query) => {
          calls.push(query)
          return { hits: [], total: 0 }
        },
      },
    })

    expect(calls).toEqual([buildTsquery(`inv (foo) & bar:* 'quoted'`)])
  })

  it('forwards tenant-scoped host context into the provider window unchanged', async () => {
    const { runPlatformSearch } = await import('../search')

    let seenCtx:
      | {
          tenantId: string
          userId: string
          isContractor: boolean
        }
      | undefined
    let seenWindow: { limit: number; offset: number } | undefined

    await runPlatformSearch({
      query: 'project alpha',
      entityTypes: ['task'],
      limit: 3,
      ctx: {
        db: {} as never,
        tenantId: 'tenant-42',
        userId: 'user-7',
        isContractor: true,
      },
      registry: {
        task: async (_query, ctx, window) => {
          seenCtx = {
            tenantId: ctx.tenantId,
            userId: ctx.userId,
            isContractor: ctx.isContractor,
          }
          seenWindow = window
          return { hits: [], total: 0 }
        },
      },
    })

    expect(seenCtx).toEqual({
      tenantId: 'tenant-42',
      userId: 'user-7',
      isContractor: true,
    })
    expect(seenWindow).toEqual({ limit: 3, offset: 0 })
  })

  it('round-trips single-entity cursor pagination', async () => {
    const { runPlatformSearch } = await import('../search')

    const page = vi.fn(async (_query, _ctx, window) => {
      const ids = ['a', 'b', 'c', 'd']
      return {
        hits: ids.slice(window.offset, window.offset + window.limit).map((id, index) => ({
          entityType: 'customer',
          id,
          rank: 1 - index * 0.1,
          title: `Customer ${id.toUpperCase()}`,
        })),
        total: ids.length,
      }
    })

    const page1 = await runPlatformSearch({
      query: 'cust',
      entityTypes: ['customer'],
      limit: 2,
      ctx: {
        db: {} as never,
        tenantId: 'tenant-1',
        userId: 'user-1',
        isContractor: false,
      },
      registry: { customer: page },
    })

    const page2 = await runPlatformSearch({
      query: 'cust',
      entityTypes: ['customer'],
      limit: 2,
      cursor: page1.nextCursor,
      ctx: {
        db: {} as never,
        tenantId: 'tenant-1',
        userId: 'user-1',
        isContractor: false,
      },
      registry: { customer: page },
    })

    expect(page1.groups[0]?.hits.map((hit) => hit.id)).toEqual(['a', 'b'])
    expect(page1.nextCursor).not.toBeNull()
    expect(page2.groups[0]?.hits.map((hit) => hit.id)).toEqual(['c', 'd'])
    expect(page2.nextCursor).toBeNull()
  })

  it('treats a forged cursor as the first page without throwing', async () => {
    const { runPlatformSearch } = await import('../search')

    const seenOffsets: number[] = []

    await expect(
      runPlatformSearch({
        query: 'cust',
        entityTypes: ['customer'],
        limit: 2,
        cursor: '!!!not-base64',
        ctx: {
          db: {} as never,
          tenantId: 'tenant-1',
          userId: 'user-1',
          isContractor: false,
        },
        registry: {
          customer: async (_query, _ctx, window) => {
            seenOffsets.push(window.offset)
            return { hits: [], total: 0 }
          },
        },
      }),
    ).resolves.toEqual({ groups: [], nextCursor: null })

    expect(seenOffsets).toEqual([0])
  })
})
