/**
 * Unit tests for FindParams.includeVectors — opt-in vector hydration on find().
 *
 * Verifies that find({ includeVectors: true }) returns each result's stored
 * embedding under entity.vector (matching get({ includeVectors: true })), that
 * the default keeps the perf contract of an empty vector, and that the
 * metadata-only find({ where }) path honors the flag too.
 */

import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import { Brainy } from '../../../src/brainy'
import { createTestConfig } from '../../helpers/test-factory'

describe('FindParams.includeVectors', () => {
  let brain: Brainy

  beforeEach(async () => {
    brain = new Brainy(createTestConfig())
    await brain.init()
  })

  afterEach(async () => {
    await brain.close()
  })

  it('returns the stored vector for query-based find when includeVectors is true', async () => {
    const id = await brain.add({
      type: 'document',
      data: 'machine learning and neural networks',
      metadata: { topic: 'ai' }
    })

    // Stored vector, as get() surfaces it — the reference for the find() result.
    const stored = await brain.get(id, { includeVectors: true })
    expect(stored!.vector.length).toBeGreaterThan(0)

    const results = await brain.find({
      query: 'machine learning and neural networks',
      includeVectors: true,
      limit: 10
    })

    const hit = results.find((r) => r.entity.id === id)
    expect(hit).toBeDefined()
    expect(hit!.entity.vector.length).toBeGreaterThan(0)
    expect(hit!.entity.vector).toEqual(stored!.vector)
  })

  it('returns an empty vector by default (perf contract preserved)', async () => {
    const id = await brain.add({
      type: 'document',
      data: 'default path should not hydrate vectors',
      metadata: { topic: 'perf' }
    })

    const results = await brain.find({
      query: 'default path should not hydrate vectors',
      limit: 10
    })

    const hit = results.find((r) => r.entity.id === id)
    expect(hit).toBeDefined()
    expect(hit!.entity.vector.length).toBe(0)
  })

  it('honors includeVectors on the metadata-only where path', async () => {
    const id = await brain.add({
      type: 'thing',
      data: 'metadata only filter target',
      metadata: { category: 'filtered' }
    })

    const stored = await brain.get(id, { includeVectors: true })

    const withVectors = await brain.find({
      where: { category: 'filtered' },
      includeVectors: true,
      limit: 10
    })
    const hit = withVectors.find((r) => r.entity.id === id)
    expect(hit).toBeDefined()
    expect(hit!.entity.vector.length).toBeGreaterThan(0)
    expect(hit!.entity.vector).toEqual(stored!.vector)

    // And the same filter without the flag stays empty.
    const withoutVectors = await brain.find({
      where: { category: 'filtered' },
      limit: 10
    })
    const plainHit = withoutVectors.find((r) => r.entity.id === id)
    expect(plainHit).toBeDefined()
    expect(plainHit!.entity.vector.length).toBe(0)
  })
})
