import { getProtectedCustomerLicenseImageUrl } from '../../lib/storage'

export function parseReservationExtras(extras: unknown): Record<string, unknown> {
  if (!extras || typeof extras !== 'object' || Array.isArray(extras)) return {}
  return { ...(extras as Record<string, unknown>) }
}

export function normalizeOptionalString(value: string | null | undefined): string | null {
  const trimmed = typeof value === 'string' ? value.trim() : value
  return trimmed || null
}

function readAddressField(address: unknown, key: string): string | null {
  const extras = parseReservationExtras(address)
  const value = extras[key]
  return typeof value === 'string' && value.trim() ? value.trim() : null
}

export function buildReservationWorkflow(reservation: {
  status: string
  contractNumber: string | null
  invoiceNumber: string | null
  extras: unknown
}) {
  const extras = parseReservationExtras(reservation.extras)
  const closedAt = typeof extras.reservationClosedAt === 'string' ? extras.reservationClosedAt : null
  const contractGenerated = Boolean(reservation.contractNumber || reservation.invoiceNumber)
  const closed = Boolean(closedAt)

  return {
    contractGenerated,
    closed,
    closedAt,
    closedBy: typeof extras.reservationClosedBy === 'string' ? extras.reservationClosedBy : null,
    coreEditable: !closed && !contractGenerated && ['DRAFT', 'CONFIRMED'].includes(reservation.status),
    returnEditable: !closed && reservation.status === 'COMPLETED',
    checkInInspectionEditable: !closed && ['CONFIRMED', 'ACTIVE'].includes(reservation.status),
    checkOutInspectionEditable: !closed && reservation.status === 'COMPLETED',
  }
}

export function buildBookingRequestProgress(reservation: {
  source: string
  status: string
  paymentStatus?: string | null
  customer?: {
    driverLicense?: string | null
    dateOfBirth?: Date | null
    address?: unknown
    licenseImageUrl?: string | null
    licenseValidationStatus?: string | null
  } | null
}) {
  const customer = reservation.customer
  const paymentStatus = reservation.paymentStatus ?? 'UNPAID'
  const identityDocumentNumber = readAddressField(customer?.address, 'identityDocumentNumber')
  const fullAddress = readAddressField(customer?.address, 'fullAddress')

  const documentsMissing: string[] = []

  if (!customer?.dateOfBirth) documentsMissing.push('DATE_OF_BIRTH')
  if (!identityDocumentNumber) documentsMissing.push('IDENTITY_DOCUMENT')
  if (!fullAddress) documentsMissing.push('FULL_ADDRESS')
  if (!customer?.driverLicense) documentsMissing.push('DRIVER_LICENSE')
  if (!customer?.licenseImageUrl) documentsMissing.push('LICENSE_IMAGE')
  if ((customer?.licenseValidationStatus ?? 'PENDING') !== 'APPROVED') {
    documentsMissing.push('LICENSE_APPROVAL')
  }

  const companyConfirmed = !['DRAFT', 'CANCELLED', 'NO_SHOW'].includes(reservation.status)
  const documentsRequired = reservation.source === 'CARPLACE' && companyConfirmed && documentsMissing.length > 0
  const paymentRequired = reservation.source === 'CARPLACE' && companyConfirmed && !['PAID', 'COMPLETED'].includes(paymentStatus)

  let stage: 'REQUEST_SENT' | 'COMPANY_CONFIRMED' | 'DOCUMENTS_REQUIRED' | 'PAYMENT_REQUIRED' | 'BOOKING_CONFIRMED' | 'CANCELLED'
  if (['CANCELLED', 'NO_SHOW'].includes(reservation.status)) stage = 'CANCELLED'
  else if (!companyConfirmed) stage = 'REQUEST_SENT'
  else if (documentsRequired) stage = 'DOCUMENTS_REQUIRED'
  else if (paymentRequired) stage = 'PAYMENT_REQUIRED'
  else if (companyConfirmed) stage = 'BOOKING_CONFIRMED'
  else stage = 'COMPANY_CONFIRMED'

  const activeStepKey =
    stage === 'REQUEST_SENT'
      ? 'REQUEST_SENT'
      : stage === 'CANCELLED'
      ? 'BOOKING_CONFIRMED'
      : stage === 'DOCUMENTS_REQUIRED'
      ? 'DOCUMENTS_COMPLETED'
      : stage === 'PAYMENT_REQUIRED'
      ? 'PAYMENT_COMPLETED'
      : 'BOOKING_CONFIRMED'

  const steps = [
    { key: 'REQUEST_SENT', completed: true, active: activeStepKey === 'REQUEST_SENT' },
    { key: 'AVAILABILITY_CONFIRMED', completed: companyConfirmed, active: companyConfirmed && activeStepKey === 'REQUEST_SENT' },
    { key: 'DOCUMENTS_COMPLETED', completed: companyConfirmed && !documentsRequired, active: activeStepKey === 'DOCUMENTS_COMPLETED' },
    { key: 'PAYMENT_COMPLETED', completed: companyConfirmed && !paymentRequired, active: activeStepKey === 'PAYMENT_COMPLETED' },
    { key: 'BOOKING_CONFIRMED', completed: companyConfirmed && !documentsRequired && !paymentRequired, active: activeStepKey === 'BOOKING_CONFIRMED' },
  ]

  return {
    stage,
    companyConfirmed,
    documentsRequired,
    paymentRequired,
    documentsMissing,
    steps,
  }
}

export function serializeReservationForDashboard<T extends {
  extras: unknown
  status: string
  source: string
  contractNumber: string | null
  invoiceNumber: string | null
  paymentStatus?: string | null
  customer?: {
    id: string
    driverLicense?: string | null
    dateOfBirth?: Date | null
    address?: unknown
    licenseImageUrl?: string | null
    licenseValidationStatus?: string | null
  } | null
}>(reservation: T): T & {
  paymentMode: string | null
  workflow: ReturnType<typeof buildReservationWorkflow>
  bookingRequest: ReturnType<typeof buildBookingRequestProgress>
} {
  const extras = parseReservationExtras(reservation.extras)
  const customer =
    reservation.customer
      ? {
          ...reservation.customer,
          licenseImageUrl: reservation.customer.licenseImageUrl
            ? getProtectedCustomerLicenseImageUrl(reservation.customer.id)
            : null,
        }
      : reservation.customer

  return {
    ...reservation,
    ...(customer !== undefined ? { customer } : {}),
    paymentMode: typeof extras.paymentMode === 'string' ? extras.paymentMode : null,
    workflow: buildReservationWorkflow(reservation),
    bookingRequest: buildBookingRequestProgress({ ...reservation, customer }),
  }
}
