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

// Mock fetch globally
const mockFetch = vi.fn()
global.fetch = mockFetch

// Mock NextRequest and NextResponse
vi.mock('next/server', () => ({
  NextRequest: class MockNextRequest {
    url: string
    constructor(url: string) {
      this.url = url
    }
  },
  NextResponse: {
    json: (data: unknown, init?: { status?: number }) => ({
      data,
      status: init?.status || 200,
    }),
  },
}))

describe('Legal Corpus API Proxy', () => {
  beforeEach(() => {
    mockFetch.mockClear()
  })

  describe('scroll action', () => {
    it('should call Qdrant scroll endpoint with correct collection', async () => {
      const mockScrollResponse = {
        result: {
          points: [
            { id: 'uuid-1', payload: { text: 'DSGVO Artikel 1', regulation_code: 'GDPR' } },
            { id: 'uuid-2', payload: { text: 'DSGVO Artikel 2', regulation_code: 'GDPR' } },
          ],
          next_page_offset: 'uuid-3',
        },
      }

      mockFetch.mockResolvedValueOnce({
        ok: true,
        json: () => Promise.resolve(mockScrollResponse),
      })

      const { GET } = await import('../route')
      const request = { url: 'http://localhost/api/legal-corpus?action=scroll&collection=bp_compliance_ce&limit=20' }
      const response = await GET(request as any)

      expect(mockFetch).toHaveBeenCalledTimes(1)
      const calledUrl = mockFetch.mock.calls[0][0]
      expect(calledUrl).toContain('/collections/bp_compliance_ce/points/scroll')

      const body = JSON.parse(mockFetch.mock.calls[0][1].body)
      expect(body.limit).toBe(20)
      expect(body.with_payload).toBe(true)
      expect(body.with_vector).toBe(false)
    })

    it('should pass offset parameter to Qdrant', async () => {
      mockFetch.mockResolvedValueOnce({
        ok: true,
        json: () => Promise.resolve({ result: { points: [], next_page_offset: null } }),
      })

      const { GET } = await import('../route')
      const request = { url: 'http://localhost/api/legal-corpus?action=scroll&collection=bp_compliance_gesetze&offset=some-uuid' }
      await GET(request as any)

      const body = JSON.parse(mockFetch.mock.calls[0][1].body)
      expect(body.offset).toBe('some-uuid')
    })

    it('should limit chunks to max 100', async () => {
      mockFetch.mockResolvedValueOnce({
        ok: true,
        json: () => Promise.resolve({ result: { points: [], next_page_offset: null } }),
      })

      const { GET } = await import('../route')
      const request = { url: 'http://localhost/api/legal-corpus?action=scroll&collection=bp_compliance_ce&limit=500' }
      await GET(request as any)

      const body = JSON.parse(mockFetch.mock.calls[0][1].body)
      expect(body.limit).toBe(100)
    })

    it('should apply text_search filter client-side', async () => {
      const mockScrollResponse = {
        result: {
          points: [
            { id: 'uuid-1', payload: { text: 'DSGVO Artikel 1 Datenschutz' } },
            { id: 'uuid-2', payload: { text: 'IFRS Standard 16 Leasing' } },
            { id: 'uuid-3', payload: { text: 'Datenschutz Grundverordnung' } },
          ],
          next_page_offset: null,
        },
      }

      mockFetch.mockResolvedValueOnce({
        ok: true,
        json: () => Promise.resolve(mockScrollResponse),
      })

      const { GET } = await import('../route')
      const request = { url: 'http://localhost/api/legal-corpus?action=scroll&collection=bp_compliance_ce&text_search=Datenschutz' }
      const response = await GET(request as any)

      // Should filter to only chunks containing "Datenschutz"
      expect((response as any).data.chunks).toHaveLength(2)
      expect((response as any).data.chunks[0].text).toContain('Datenschutz')
    })

    it('should flatten payload into chunk objects', async () => {
      const mockScrollResponse = {
        result: {
          points: [
            {
              id: 'uuid-1',
              payload: {
                text: 'IFRS 16 Leasing',
                regulation_code: 'EU_IFRS',
                language: 'de',
                celex: '32023R1803',
              },
            },
          ],
          next_page_offset: null,
        },
      }

      mockFetch.mockResolvedValueOnce({
        ok: true,
        json: () => Promise.resolve(mockScrollResponse),
      })

      const { GET } = await import('../route')
      const request = { url: 'http://localhost/api/legal-corpus?action=scroll&collection=bp_compliance_ce' }
      const response = await GET(request as any)

      const chunk = (response as any).data.chunks[0]
      expect(chunk.id).toBe('uuid-1')
      expect(chunk.text).toBe('IFRS 16 Leasing')
      expect(chunk.regulation_code).toBe('EU_IFRS')
      expect(chunk.language).toBe('de')
    })

    it('should return next_offset from Qdrant response', async () => {
      mockFetch.mockResolvedValueOnce({
        ok: true,
        json: () => Promise.resolve({
          result: { points: [], next_page_offset: 'next-uuid' },
        }),
      })

      const { GET } = await import('../route')
      const request = { url: 'http://localhost/api/legal-corpus?action=scroll&collection=bp_compliance_ce' }
      const response = await GET(request as any)

      expect((response as any).data.next_offset).toBe('next-uuid')
    })

    it('should handle Qdrant scroll failure', async () => {
      mockFetch.mockResolvedValueOnce({
        ok: false,
        status: 404,
      })

      const { GET } = await import('../route')
      const request = { url: 'http://localhost/api/legal-corpus?action=scroll&collection=nonexistent' }
      const response = await GET(request as any)

      expect((response as any).status).toBe(404)
    })

    it('should apply filter when filter_key and filter_value provided', async () => {
      mockFetch.mockResolvedValueOnce({
        ok: true,
        json: () => Promise.resolve({ result: { points: [], next_page_offset: null } }),
      })

      const { GET } = await import('../route')
      const request = { url: 'http://localhost/api/legal-corpus?action=scroll&collection=bp_compliance_ce&filter_key=language&filter_value=de' }
      await GET(request as any)

      const body = JSON.parse(mockFetch.mock.calls[0][1].body)
      expect(body.filter).toEqual({
        must: [{ key: 'language', match: { value: 'de' } }],
      })
    })

    it('should default collection to bp_compliance_gesetze', async () => {
      mockFetch.mockResolvedValueOnce({
        ok: true,
        json: () => Promise.resolve({ result: { points: [], next_page_offset: null } }),
      })

      const { GET } = await import('../route')
      const request = { url: 'http://localhost/api/legal-corpus?action=scroll' }
      await GET(request as any)

      const calledUrl = mockFetch.mock.calls[0][0]
      expect(calledUrl).toContain('/collections/bp_compliance_gesetze/')
    })
  })

  describe('collection-count action', () => {
    it('should return points_count from Qdrant collection info', async () => {
      mockFetch.mockResolvedValueOnce({
        ok: true,
        json: () => Promise.resolve({
          result: { points_count: 55053 },
        }),
      })

      const { GET } = await import('../route')
      const request = { url: 'http://localhost/api/legal-corpus?action=collection-count&collection=bp_compliance_ce' }
      const response = await GET(request as any)

      expect((response as any).data.count).toBe(55053)
    })

    it('should return 0 when Qdrant is unavailable', async () => {
      mockFetch.mockResolvedValueOnce({
        ok: false,
        status: 500,
      })

      const { GET } = await import('../route')
      const request = { url: 'http://localhost/api/legal-corpus?action=collection-count&collection=bp_compliance_ce' }
      const response = await GET(request as any)

      expect((response as any).data.count).toBe(0)
    })

    it('should default to bp_compliance_gesetze collection', async () => {
      mockFetch.mockResolvedValueOnce({
        ok: true,
        json: () => Promise.resolve({ result: { points_count: 1234 } }),
      })

      const { GET } = await import('../route')
      const request = { url: 'http://localhost/api/legal-corpus?action=collection-count' }
      await GET(request as any)

      const calledUrl = mockFetch.mock.calls[0][0]
      expect(calledUrl).toContain('/collections/bp_compliance_gesetze')
    })
  })
})
