import type { TripRole } from '@/types/db'

/**
 * Per-trip permission matrix. Nash: "The relation between the order and the
 * emails of the invited people into that order — that's what's relevant."
 * Invite rules follow the circle-based model in the product docs.
 */
export const INVITE_RULES: Record<TripRole, TripRole[]> = {
  broker: ['dispatcher', 'shipper', 'pilot', 'driver'],
  dispatcher: ['driver', 'pilot', 'broker'],
  driver: ['dispatcher', 'pilot'],
  pilot: ['driver'],
  shipper: ['broker'],
  admin: ['broker', 'dispatcher', 'driver', 'pilot', 'shipper'],
}

export function canInvite(inviterRole: TripRole, inviteeRole: TripRole): boolean {
  return INVITE_RULES[inviterRole]?.includes(inviteeRole) ?? false
}

/** If you can invite a role you can remove that role (docs rule). */
export function canRemove(removerRole: TripRole, removedRole: TripRole): boolean {
  return canInvite(removerRole, removedRole)
}

export function canUploadDocuments(role: TripRole): boolean {
  return role !== 'shipper'
}

// "Anyone that has access to this load will be able to buy the Google Maps" — Nash
export function canRequestServices(role: TripRole): boolean {
  return INVITE_RULES[role] !== undefined
}

/**
 * Who sees a participant's phone number on the People tab (Nash,
 * 2026-09-18): "if I want to call the driver, I should be able to see his
 * phone number… if the broker is invited to the trip, the broker should have
 * the phone number for the dispatcher, for the driver… The broker does not
 * need to see the phone number for the pilots unless he's the one that
 * invited them. But the carrier should always see the phone number for the
 * pilots that are part of this trip, pilot dispatchers and pilots."
 *
 *   • admin                         → every number
 *   • a non-pilot participant       → everyone on the trip sees it
 *   • a pilot's number              → carrier side (dispatcher, driver) always;
 *                                     anyone else only if they invited that pilot
 */
export function canSeeParticipantPhone(params: {
  participant: { role: TripRole; invited_by: string | null }
  viewerRole: TripRole | null
  viewerUserId: string | null | undefined
  viewerIsAdmin: boolean
}): boolean {
  if (params.viewerIsAdmin) return true
  if (params.participant.role !== 'pilot') return true
  if (params.viewerRole === 'dispatcher' || params.viewerRole === 'driver') return true
  return !!params.viewerUserId && params.participant.invited_by === params.viewerUserId
}
