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

vi.mock('../../lib/prisma', () => ({
  prisma: {
    review: { findMany: vi.fn(), count: vi.fn(), findFirst: vi.fn(), update: vi.fn() },
    reservation: { update: vi.fn() },
  },
}))

import { prisma } from '../../lib/prisma'
import * as repo from './review.repo'

describe('review.repo edge behavior', () => {
  beforeEach(() => vi.clearAllMocks())

  it('merges caller filters with company boundary and paginates newest first', async () => {
    vi.mocked(prisma.review.findMany).mockResolvedValue([] as never)
    vi.mocked(prisma.review.count).mockResolvedValue(0 as never)

    await repo.findMany('company_1', { overallRating: 5 }, 20, 10)

    const where = { companyId: 'company_1', overallRating: 5 }
    expect(prisma.review.findMany).toHaveBeenCalledWith(expect.objectContaining({
      where,
      skip: 20,
      take: 10,
      orderBy: { createdAt: 'desc' },
    }))
    expect(prisma.review.count).toHaveBeenCalledWith({ where })
  })

  it('computes rounded review stats while ignoring missing sub-ratings', async () => {
    vi.mocked(prisma.review.findMany).mockResolvedValue([
      { overallRating: 5, vehicleRating: 5, serviceRating: 4 },
      { overallRating: 4, vehicleRating: null, serviceRating: 5 },
      { overallRating: 2, vehicleRating: 3, serviceRating: null },
    ] as never)

    await expect(repo.getStats('company_1')).resolves.toEqual({
      total: 3,
      averageOverall: 3.7,
      averageVehicle: 4,
      averageService: 4.5,
      byRating: { 1: 0, 2: 1, 3: 0, 4: 1, 5: 1 },
    })
  })

  it('returns zeroed stats when no reviews exist', async () => {
    vi.mocked(prisma.review.findMany).mockResolvedValue([] as never)

    await expect(repo.getStats('company_1')).resolves.toEqual({
      total: 0,
      averageOverall: 0,
      averageVehicle: 0,
      averageService: 0,
      byRating: { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 },
    })
  })

  it('writes the requested reminder timestamp field only', async () => {
    const sentAt = new Date('2026-12-01T10:00:00.000Z')

    await repo.sendReminder('reservation_1', sentAt, 'reviewFinalReminderSentAt')

    expect(prisma.reservation.update).toHaveBeenCalledWith({
      where: { id: 'reservation_1' },
      data: { reviewFinalReminderSentAt: sentAt },
    })
  })
})
