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

vi.mock('@/lib/prisma', () => ({
  prisma: {
    spot: {
      findMany: vi.fn().mockResolvedValue([]),
      findUnique: vi.fn().mockResolvedValue(null),
    },
    $queryRaw: vi.fn().mockResolvedValue([]),
  },
}))

import { listApprovedSpots, getSpotDetail } from './spots'

describe('listApprovedSpots', () => {
  beforeEach(() => vi.clearAllMocks())

  it('returns spots and nextCursor', async () => {
    const { prisma } = await import('@/lib/prisma')
    vi.mocked(prisma.spot.findMany).mockResolvedValue([] as any)
    const result = await listApprovedSpots()
    expect(result).toHaveProperty('spots')
    expect(result).toHaveProperty('nextCursor')
  })

  it('uses $queryRaw for geo search', async () => {
    const { prisma } = await import('@/lib/prisma')
    await listApprovedSpots({ lat: 38.71, lng: -9.13, radiusKm: 20 })
    expect(prisma.$queryRaw).toHaveBeenCalled()
  })

  it('caps take at 50', async () => {
    const { prisma } = await import('@/lib/prisma')
    vi.mocked(prisma.spot.findMany).mockResolvedValue([] as any)
    await listApprovedSpots({ take: 999 })
    const call = vi.mocked(prisma.spot.findMany).mock.calls[0][0] as any
    expect(call.take).toBe(51)
  })

  it('sets nextCursor when more results exist', async () => {
    const { prisma } = await import('@/lib/prisma')
    const fakeSix = Array.from({ length: 6 }, (_, i) => ({
      id: `s${i}`, name: 'X', description: 'Y', lat: 0, lng: 0,
      difficulty: 'BEGINNER', coverImage: null, tags: [], authorId: null,
      createdAt: new Date(), _count: { reviews: 0 },
    }))
    vi.mocked(prisma.spot.findMany).mockResolvedValue(fakeSix as any)
    const result = await listApprovedSpots({ take: 5 })
    expect(result.spots).toHaveLength(5)
    expect(result.nextCursor).toBe('s4')
  })
})

describe('getSpotDetail', () => {
  it('queries by id with APPROVED status', async () => {
    const { prisma } = await import('@/lib/prisma')
    await getSpotDetail('spot-1')
    expect(prisma.spot.findUnique).toHaveBeenCalledWith(
      expect.objectContaining({ where: expect.objectContaining({ id: 'spot-1' }) })
    )
  })
})
