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

const prismaMock = vi.hoisted(() => ({
  offer: { findMany: vi.fn(), findFirst: vi.fn() },
  company: { findMany: vi.fn(), findFirst: vi.fn(), findFirstOrThrow: vi.fn() },
  vehicle: { findMany: vi.fn(), findFirst: vi.fn(), findFirstOrThrow: vi.fn() },
  reservation: { create: vi.fn(), findUnique: vi.fn(), update: vi.fn() },
  customer: { findUnique: vi.fn(), create: vi.fn(), update: vi.fn() },
  review: { findMany: vi.fn(), create: vi.fn() },
}))

vi.mock('../../lib/prisma', () => ({ prisma: prismaMock }))

import * as repo from './carplace.repo'

describe('carplace.repo public query and write boundaries', () => {
  it('finds public offers using active/public/current-window filters and featured ordering', async () => {
    vi.useFakeTimers()
    vi.setSystemTime(new Date('2026-06-09T10:00:00.000Z'))

    await repo.findPublicOffers()

    expect(prismaMock.offer.findMany).toHaveBeenCalledWith(expect.objectContaining({
      where: {
        isPublic: true,
        isActive: true,
        validFrom: { lte: new Date('2026-06-09T10:00:00.000Z') },
        validUntil: { gte: new Date('2026-06-09T10:00:00.000Z') },
      },
      orderBy: [{ isFeatured: 'desc' }, { createdAt: 'desc' }],
      take: 50,
    }))
    vi.useRealTimers()
  })

  it('lists carplace cities only from active listed companies with a public city', async () => {
    await repo.findCitiesFromCompanies()

    expect(prismaMock.company.findMany).toHaveBeenCalledWith({
      where: {
        status: { in: ['ACTIVE', 'TRIALING'] },
        brand: { isListedOnCarplace: true, publicCity: { not: null } },
      },
      select: { brand: { select: { publicCity: true } } },
    })
  })

  it('requires published vehicles and an active company when loading carplace vehicle details', async () => {
    await repo.findVehicleForCarplace('vehicle_1', 'atlas')

    expect(prismaMock.vehicle.findFirst).toHaveBeenCalledWith({
      where: {
        id: 'vehicle_1',
        isPublished: true,
        company: {
          OR: [{ slug: 'atlas' }, { brand: { subdomain: 'atlas' } }],
          status: { in: ['ACTIVE', 'TRIALING'] },
        },
      },
      include: { company: { include: { brand: true } } },
    })
  })

  it('patches carplace customer address fields without deleting existing address metadata', async () => {
    prismaMock.customer.findUnique.mockResolvedValueOnce({
      id: 'customer_1',
      address: { fullAddress: 'Old address', loyaltyNote: 'keep', internationalLicenseNumber: 'INT-1' },
    })

    await repo.upsertCarplaceCustomer('company_1', {
      email: 'renter@example.test',
      firstName: 'Nora',
      lastName: 'Renter',
      identityDocumentNumber: 'ID-9',
      internationalLicenseNumber: undefined,
    })

    expect(prismaMock.customer.update).toHaveBeenCalledWith({
      where: { id: 'customer_1' },
      data: expect.objectContaining({
        firstName: 'Nora',
        address: {
          fullAddress: 'Old address',
          loyaltyNote: 'keep',
          internationalLicenseNumber: 'INT-1',
          identityDocumentNumber: 'ID-9',
        },
      }),
    })
  })

  it('creates carplace reservations as draft carplace-sourced records', async () => {
    const startDate = new Date('2026-07-01T10:00:00.000Z')
    const endDate = new Date('2026-07-05T10:00:00.000Z')

    await repo.createCarplaceReservation({
      companyId: 'company_1',
      vehicleId: 'vehicle_1',
      customerId: 'customer_1',
      startDate,
      endDate,
      dailyRate: 500,
      totalDays: 4,
      totalAmount: 2000,
      pickupLocation: 'Airport',
      returnLocation: null,
    })

    expect(prismaMock.reservation.create).toHaveBeenCalledWith({
      data: expect.objectContaining({
        companyId: 'company_1',
        vehicleId: 'vehicle_1',
        customerId: 'customer_1',
        source: 'CARPLACE',
        status: 'DRAFT',
      }),
    })
  })

  it('submits public reviews as published records and prevents null renter ids from becoming explicit nulls', async () => {
    await repo.createReview({
      reservationId: 'reservation_1',
      companyId: 'company_1',
      renterId: null,
      overallRating: 5,
      vehicleRating: 4,
      serviceRating: 5,
      comment: 'Clean car',
    })

    expect(prismaMock.review.create).toHaveBeenCalledWith({
      data: {
        reservationId: 'reservation_1',
        companyId: 'company_1',
        renterId: undefined,
        overallRating: 5,
        vehicleRating: 4,
        serviceRating: 5,
        comment: 'Clean car',
        isPublished: true,
      },
    })
  })
})
