import { describe, expect, it, vi } from 'vitest'
import { apiFetch } from '@/lib/api'
import { submitReservationDraft } from './reservationWizard.submit'
import type { ReservationDraft } from './reservationWizard.types'

vi.mock('@/lib/api', () => ({
  apiFetch: vi.fn(),
}))

function draft(): ReservationDraft {
  return {
    customer: {
      mode: 'new',
      selectedCustomerId: null,
      createdCustomerId: null,
      firstName: { fr: 'Sara', ar: '' },
      lastName: { fr: 'Alaoui', ar: '' },
      email: 'sara@example.com',
      phone: '+212600000000',
      hydratedFromCustomerId: null,
    },
    identity: {
      dateOfBirth: '1990-01-01',
      nationality: 'Moroccan',
      fullAddress: '12 Main Street',
      identityDocumentNumber: 'AB123',
      internationalLicenseNumber: '',
    },
    license: {
      number: 'DL-123',
      country: 'MA',
      issuedAt: '2020-01-01',
      expiry: '2099-01-01',
      category: 'B',
      existingImageUrl: null,
      newImageFile: null,
    },
    rental: {
      vehicleId: 'vehicle_1',
      startDate: '2026-07-01T10:00',
      endDate: '2026-07-03T10:00',
      pickupLocation: '',
      returnLocation: '',
    },
    payment: {
      depositAmount: '0',
      paymentMode: 'CASH',
      notes: '',
    },
    additionalDrivers: [],
  }
}

describe('submitReservationDraft', () => {
  it('reports the created customer id before a later reservation failure', async () => {
    const api = vi.mocked(apiFetch)
    api
      .mockResolvedValueOnce({ available: true })
      .mockResolvedValueOnce({ id: 'customer_1' })
      .mockRejectedValueOnce(new Error('reservation failed'))
    const resolvedCustomerIds: string[] = []

    await expect(submitReservationDraft(draft(), {
      onCustomerIdResolved: (customerId) => resolvedCustomerIds.push(customerId),
    })).rejects.toThrow('reservation failed')

    expect(resolvedCustomerIds).toEqual(['customer_1'])
    expect(api).toHaveBeenCalledTimes(3)
  })

  it('uses a previously created customer on retry', async () => {
    const api = vi.mocked(apiFetch)
    api
      .mockResolvedValueOnce({ available: true })
      .mockResolvedValueOnce({ id: 'reservation_1' })
    const retryDraft = draft()
    retryDraft.customer.createdCustomerId = 'customer_1'

    await submitReservationDraft(retryDraft)

    expect(api).toHaveBeenNthCalledWith(2, '/customers/customer_1', expect.objectContaining({ method: 'PATCH' }))
  })
})
