import { emptyBilingual } from '@/components/ui/BilingualInput'
import type { AdditionalDriverDraft, Customer, ReservationDraft } from './reservationWizard.types'

function readCustomerAddressValue(customer: Customer | undefined, key: string) {
  const address = customer?.address
  if (!address || typeof address !== 'object' || Array.isArray(address)) return ''
  const value = address[key]
  return typeof value === 'string' ? value : ''
}

export function createAdditionalDriver(): AdditionalDriverDraft {
  return {
    id: crypto.randomUUID(),
    firstName: emptyBilingual(),
    lastName: emptyBilingual(),
    email: '',
    phone: '',
    driverLicense: '',
    licenseExpiry: '',
    licenseIssuedAt: '',
    dateOfBirth: '',
    nationality: emptyBilingual(),
  }
}

export function createInitialDraft(): ReservationDraft {
  return {
    customer: {
      mode: 'existing',
      selectedCustomerId: null,
      createdCustomerId: null,
      firstName: emptyBilingual(),
      lastName: emptyBilingual(),
      email: '',
      phone: '',
      hydratedFromCustomerId: null,
    },
    identity: {
      dateOfBirth: '',
      nationality: '',
      fullAddress: '',
      identityDocumentNumber: '',
      internationalLicenseNumber: '',
    },
    license: {
      number: '',
      country: '',
      issuedAt: '',
      expiry: '',
      category: '',
      existingImageUrl: null,
      newImageFile: null,
    },
    rental: {
      vehicleId: '',
      startDate: '',
      endDate: '',
      pickupLocation: '',
      returnLocation: '',
    },
    payment: {
      depositAmount: '0',
      paymentMode: 'CASH',
      notes: '',
    },
    additionalDrivers: [],
  }
}

export type ReservationDraftAction =
  | { type: 'setCustomerMode'; mode: 'existing' | 'new' }
  | { type: 'selectExistingCustomer'; customer: Customer }
  | { type: 'setCreatedCustomerId'; customerId: string }
  | { type: 'updateCustomer'; field: keyof ReservationDraft['customer']; value: any }
  | { type: 'updateIdentity'; field: keyof ReservationDraft['identity']; value: string }
  | { type: 'updateLicense'; field: keyof ReservationDraft['license']; value: any }
  | { type: 'updateRental'; field: keyof ReservationDraft['rental']; value: string }
  | { type: 'updatePayment'; field: keyof ReservationDraft['payment']; value: string }
  | { type: 'addAdditionalDriver' }
  | { type: 'removeAdditionalDriver'; id: string }
  | { type: 'updateAdditionalDriver'; id: string; field: keyof AdditionalDriverDraft; value: any }
  | { type: 'reset' }

export function reservationDraftReducer(draft: ReservationDraft, action: ReservationDraftAction): ReservationDraft {
  switch (action.type) {
    case 'setCustomerMode':
      if (action.mode === draft.customer.mode) return draft
      if (action.mode === 'new') {
        return {
          ...draft,
          customer: {
            ...createInitialDraft().customer,
            mode: 'new',
            createdCustomerId: draft.customer.createdCustomerId,
          },
          identity: createInitialDraft().identity,
          license: createInitialDraft().license,
        }
      }

      return {
        ...draft,
        customer: createInitialDraft().customer,
        identity: createInitialDraft().identity,
        license: createInitialDraft().license,
      }
    case 'selectExistingCustomer':
      return {
        ...draft,
        customer: {
          mode: 'existing',
          selectedCustomerId: action.customer.id,
          createdCustomerId: null,
          firstName: { fr: action.customer.firstName ?? '', ar: action.customer.firstNameAr ?? '' },
          lastName: { fr: action.customer.lastName ?? '', ar: action.customer.lastNameAr ?? '' },
          email: action.customer.email ?? '',
          phone: action.customer.phone ?? '',
          hydratedFromCustomerId: action.customer.id,
        },
        identity: {
          dateOfBirth: action.customer.dateOfBirth ? action.customer.dateOfBirth.slice(0, 10) : '',
          nationality: action.customer.nationality ?? '',
          fullAddress: readCustomerAddressValue(action.customer, 'fullAddress'),
          identityDocumentNumber: readCustomerAddressValue(action.customer, 'identityDocumentNumber'),
          internationalLicenseNumber: readCustomerAddressValue(action.customer, 'internationalLicenseNumber'),
        },
        license: {
          number: action.customer.driverLicense ?? action.customer.licenseNumber ?? '',
          country: action.customer.licenseCountry ?? '',
          issuedAt: action.customer.licenseIssuedAt ? action.customer.licenseIssuedAt.slice(0, 10) : '',
          expiry: action.customer.licenseExpiry ? action.customer.licenseExpiry.slice(0, 10) : '',
          category: action.customer.licenseCategory ?? '',
          existingImageUrl: action.customer.licenseImageUrl ?? null,
          newImageFile: null,
        },
      }
    case 'setCreatedCustomerId':
      return { ...draft, customer: { ...draft.customer, createdCustomerId: action.customerId } }
    case 'updateCustomer':
      return { ...draft, customer: { ...draft.customer, [action.field]: action.value } }
    case 'updateIdentity':
      return { ...draft, identity: { ...draft.identity, [action.field]: action.value } }
    case 'updateLicense':
      return { ...draft, license: { ...draft.license, [action.field]: action.value } }
    case 'updateRental':
      return { ...draft, rental: { ...draft.rental, [action.field]: action.value } }
    case 'updatePayment':
      return { ...draft, payment: { ...draft.payment, [action.field]: action.value } }
    case 'addAdditionalDriver':
      return { ...draft, additionalDrivers: [...draft.additionalDrivers, createAdditionalDriver()] }
    case 'removeAdditionalDriver':
      return { ...draft, additionalDrivers: draft.additionalDrivers.filter((driver) => driver.id !== action.id) }
    case 'updateAdditionalDriver':
      return {
        ...draft,
        additionalDrivers: draft.additionalDrivers.map((driver) =>
          driver.id === action.id ? { ...driver, [action.field]: action.value } : driver,
        ),
      }
    case 'reset':
      return createInitialDraft()
  }
}
