export type UserRole = 'broker' | 'dispatcher' | 'driver' | 'admin'
export type TripRole = 'broker' | 'dispatcher' | 'driver' | 'pilot' | 'shipper' | 'admin'
export type TripStatus = 'draft' | 'waiting_for_permits' | 'active' | 'completed' | 'cancelled'
export type PermitSource = 'upload' | 'synchron'
export type DocumentKind = 'rate_confirmation' | 'permit' | 'provision' | 'route' | 'other'
export type ExtractionStatus = 'pending' | 'processed' | 'failed' | 'skipped'
export type WarningKind =
  | 'dimension_mismatch'
  | 'expired'
  | 'expiring'
  | 'curfew'
  | 'escort'
  | 'missing_permit'
  | 'other'
export type WarningSeverity = 'info' | 'warning' | 'danger'
/** `imported` = from a historical order: shown on the trip, grants no access until claimed (2026-09-14). */
export type ParticipantStatus = 'invited' | 'active' | 'removed' | 'imported'
/** Where a document's file lives (migration 0017). */
export type StorageProvider = 'supabase' | 's3' | 'external'
export type RequestType = 'permit_request' | 'route_request'
export type RequestStatus = 'requested' | 'in_progress' | 'fulfilled' | 'cancelled'

export interface Profile {
  id: string
  email: string
  full_name: string
  phone: string | null
  company_name: string | null
  default_role: UserRole
  /**
   * Agent chat languages (2026-09-07, Task 71). Nash: "one language, English,
   * first, and then a button to add… It should stick to your profile." Absent
   * before migration 0011 → treat as ['en'] / 'en'.
   */
  chat_languages?: string[] | null
  primary_language?: string | null
  /** Verified delivery address when it differs from the login email (migration 0028). */
  delivery_email?: string | null
  pending_email?: string | null
  /** Sign-in email change in progress (migration 0031). */
  pending_login_email?: string | null
  login_email_changed_at?: string | null
  /** Imported historical identity (migration 0038). Null claim_status = a profile the app created for a signed-in person. */
  claim_status?: 'unclaimed' | 'claim_candidate' | 'claimed' | 'manual_review' | 'conflict' | null
  claimed_at?: string | null
  claimed_user_id?: string | null
  source_system?: string | null
  source_record_id?: string | null
  email_normalized?: string | null
  historical_import?: boolean
  created_at: string
}

export interface BrokerPage {
  id: string
  owner_id: string
  slug: string
  display_name: string
  intro_message: string | null
  enabled: boolean
  /** Default permit-handling rules (intake doc §22): 'ask' = choose per trip. */
  default_permit_policy: 'synchron_required' | 'upload_allowed' | 'ask'
  default_payment_party: 'broker' | 'carrier' | 'ask'
  /** The verified company this intake page belongs to (Task 94; migration 0013). */
  company_id?: string | null
  created_at: string
}

export interface Trip {
  id: string
  ref_code: string
  created_by: string | null
  broker_page_id: string | null
  status: TripStatus
  permit_source: PermitSource
  carrier_name: string
  unit_number: string | null
  origin: string
  destination: string
  commodity: string
  load_length_in: number | null
  load_width_in: number | null
  load_height_in: number | null
  load_weight_lbs: number | null
  overall_length_in: number | null
  overall_width_in: number | null
  overall_height_in: number | null
  overall_weight_lbs: number | null
  permit_policy: 'synchron_required' | 'upload_allowed' | null
  /** Who pays Synchron for permit processing (Synchron flow only; null = n/a). */
  payment_responsible_party: 'broker' | 'carrier' | null
  /** Provenance (migration 0017). Null source_system = created in HeavyHaul Agent. */
  source_system?: string | null
  source_record_id?: string | null
  source_order_number?: string | null
  /** One Synchron order for this trip, independent of its Workspace trip number. */
  synchron_order_token?: string | null
  synchron_order_id?: string | null
  source_status?: string | null
  imported_at?: string | null
  /** Who processed the order at the provider — a label, never a participant. */
  processed_by_label?: string | null
  carrier_company_id?: string | null
  pickup_date: string | null
  delivery_date: string | null
  notes: string | null
  completed_at: string | null
  created_at: string
  updated_at: string
}

export interface TripParticipant {
  id: string
  trip_id: string
  user_id: string | null
  email: string
  name: string
  phone: string | null
  phone_ext: string | null
  role: TripRole
  status: ParticipantStatus
  invited_by: string | null
  /**
   * When THIS participant marked the trip complete for themselves
   * (2026-09-07). Nash: "this marks it complete for me as the user… I don't
   * want to force close, force complete for all users this trip."
   */
  completed_at: string | null
  /** When they answered the "someone else completed this trip" prompt. */
  completion_prompt_dismissed_at: string | null
  /** False = this participant's agent Q&A on this trip is hidden from others. */
  share_chat: boolean
  /** Provenance + claim (migration 0017). Set on rows created by a historical import. */
  source_system?: string | null
  source_record_id?: string | null
  claimed_at?: string | null
  claim_method?: 'email_verified' | 'admin' | null
  /** The Synchron user token for this person (migration 0040). */
  source_token?: string | null
  /**
   * Which company and role the person acts with ON THIS TRIP (migration 0049,
   * Nash 2026-09-30): a person who dispatches for two carriers chooses one per
   * trip. Null = not chosen yet, or a row from before the feature.
   */
  context_company_id?: string | null
  context_role_type?: string | null
  /** How the person got onto the trip (migration 0049). Null = before the feature. */
  addition_method?: AdditionMethod | null
  triggering_user_id?: string | null
  triggering_company_id?: string | null
  auto_participant_rule_id?: string | null
  /** When Auto-Participant rules were evaluated for this row (fire once). */
  rules_evaluated_at?: string | null
  created_at: string
}

/** Why a participant row exists (migration 0049). Auto-Participant is how someone got on, never a role. */
export type AdditionMethod =
  | 'manual_invite'
  | 'trip_creator'
  | 'invitation_accepted'
  | 'intake'
  | 'personal_auto_participant'
  | 'company_auto_participant'
  | 'synchron_import'
  | 'admin'

/* ---------------- Auto-Participants (migration 0049, 2026-09-30) ---------------- */

export type AutoParticipantRuleType = 'personal' | 'company'
export type AutoParticipantScope =
  | 'all_personal_trips'
  | 'all_company_trips'
  | 'carrier_trips'
  | 'freight_broker_trips'
  | 'pilot_company_trips'
export type AutoParticipantRuleStatus = 'pending' | 'active' | 'declined' | 'revoked' | 'disabled' | 'suspended'

/** "Automatically include this person in my / our company's trips." */
export interface AutoParticipantRule {
  id: string
  rule_type: AutoParticipantRuleType
  owner_user_id: string | null
  owner_company_id: string | null
  participant_user_id: string | null
  participant_email: string
  participant_email_normalized: string
  participant_first_name: string | null
  participant_last_name: string | null
  /** The role the person takes part with; null until chosen (acceptance, or per trip). */
  participant_role_type: string | null
  scope_type: AutoParticipantScope
  status: AutoParticipantRuleStatus
  suspended_reason: string | null
  requires_acceptance: boolean
  accepted_at: string | null
  accepted_by: string | null
  accept_token: string | null
  token_expires_at: string | null
  created_by: string
  effective_from: string | null
  disabled_at: string | null
  disabled_by: string | null
  conditions: Record<string, unknown>
  created_at: string
  updated_at: string
}

/** Every rule that supports one participant's presence on a trip (one row can qualify through several rules). */
export interface TripParticipantSource {
  id: string
  participant_id: string
  rule_id: string
  triggering_user_id: string | null
  triggering_company_id: string | null
  created_at: string
}

export interface AutoParticipantRuleEvent {
  id: string
  rule_id: string
  event: string
  actor_user_id: string | null
  actor_label: string
  trip_id: string | null
  participant_id: string | null
  detail: Record<string, unknown>
  created_at: string
}

export interface TripInvitation {
  id: string
  trip_id: string
  participant_id: string | null
  email: string
  role: TripRole
  token: string
  invited_by: string | null
  expires_at: string
  accepted_at: string | null
  accepted_by: string | null
  created_at: string
}

export interface TripDocument {
  id: string
  trip_id: string
  kind: DocumentKind
  /** Bucket path — null only when the provider still hosts the file (storage_provider = external). */
  storage_path: string | null
  file_name: string
  mime_type: string | null
  size_bytes: number | null
  uploaded_by: string | null
  uploader_label: string
  /** Migration 0017. Absent before it → 'supabase'. Resolve URLs only through src/lib/data/document-urls.ts. */
  storage_provider?: StorageProvider | null
  external_url?: string | null
  source_system?: string | null
  source_record_id?: string | null
  content_hash?: string | null
  /** When the hosted original may be deleted (§8: 365 days). Extracted text is never deleted. */
  retention_until?: string | null
  text_extracted_at?: string | null
  created_at: string
}

export interface Permit {
  id: string
  trip_id: string
  document_id: string | null
  state_code: string
  permit_number: string | null
  effective_date: string | null
  expiration_date: string | null
  permit_length_in: number | null
  permit_width_in: number | null
  permit_height_in: number | null
  permit_weight_lbs: number | null
  extraction: Record<string, unknown> | null
  extraction_status: ExtractionStatus
  /** Provenance (migration 0017). */
  source_system?: string | null
  source_record_id?: string | null
  source_status?: string | null
  attached_at?: string | null
  /** Provider route token — Express Route matching foundation (§14). */
  route_token?: string | null
  route_processing_status?: 'queued' | 'ready' | 'needs_preparation' | 'failed' | 'unsupported'
  route_links?: string[] | null
  route_gpx_url?: string | null
  route_hummer_url?: string | null
  discrepancy_flag?: boolean | null
  /** What the issuing state charged for this permit (migration 0033). Never sent to a pilot. */
  permit_cost_amount?: number | null
  permit_cost_currency?: string | null
  permit_cost_status?: 'found' | 'not_found' | 'needs_review' | 'manually_entered' | 'corrected'
  permit_cost_confidence?: 'high' | 'medium' | 'low' | null
  permit_cost_source?: 'extraction' | 'manual' | 'api' | null
  permit_cost_extracted_text?: string | null
  permit_cost_extracted_amount?: number | null
  permit_cost_manual_override?: number | null
  permit_cost_verified?: boolean
  permit_cost_updated_by?: string | null
  permit_cost_last_updated_at?: string | null
  /** A revision points at the permit it replaces, so the fee is not counted twice. */
  supersedes_permit_id?: string | null
  cost_counts_toward_total?: boolean
  created_at: string
}

export interface TripWarning {
  id: string
  trip_id: string
  permit_id: string | null
  kind: WarningKind
  severity: WarningSeverity
  message: string
  resolved: boolean
  created_at: string
}

export interface ServiceRequest {
  id: string
  trip_id: string
  type: RequestType
  state_code: string | null
  notes: string | null
  status: RequestStatus
  requested_by: string | null
  requester_label: string
  route_type: 'express' | 'extended' | null
  /** Google Maps parts — 1..N links (Texas routes can run to 12 parts). */
  route_links: string[] | null
  /** GPX file the driver sends to the in-cab truck GPS over Bluetooth. */
  route_gpx_url: string | null
  /** Deep link that opens this route in the Hummer GPS app. */
  route_hummer_url: string | null
  notify: string[] | null
  /** How a route was paid (Task 69): a prepaid Express Route credit, or the cart. */
  paid_with?: 'credit' | 'card' | null
  /** Who is liable for a permit order (Task 75). */
  payer?: 'requester' | 'broker' | 'carrier' | null
  /** The expired permit this permit request re-orders (Task 75). */
  replaces_permit_id?: string | null
  /** Synchron's own order number, when the adapter returned one (Task 84). */
  vendor_order_id?: string | null
  /** Provenance (migration 0017) — e.g. a route imported with a historical order. */
  source_system?: string | null
  source_record_id?: string | null
  created_at: string
  updated_at: string
}

export interface ChatMessage {
  id: string
  trip_id: string
  user_id: string | null
  author_label: string
  author_role: string
  is_ai: boolean
  content: string
  state_code: string | null
  permit_id: string | null
  confidence: string | null
  sources: string[] | null
  feedback: number | null
  /** True = visible only to `private_for_user_id` (2026-09-07 sharing toggle). */
  is_private: boolean
  private_for_user_id: string | null
  /** For an AI message: the participant question it answers. */
  answer_to_message_id: string | null
  created_at: string
}

/** Editable system email template (admin dashboard; sending = email backend). */
export interface EmailTemplate {
  id: string
  key: string
  name: string
  subject: string
  body: string
  recipients_note: string | null
  cc_rules: string | null
  trigger_note: string | null
  internal_notes: string | null
  active: boolean
  updated_by: string | null
  updated_at: string
  created_at: string
}

export interface EmailTemplateVersion {
  id: string
  template_id: string
  subject: string
  body: string
  edited_by: string | null
  reason: string | null
  created_at: string
}

/** Unit profile for one trip: axles + truck info + trailer info (driver feedback 2026-09-04). */
export interface TripUnit {
  id: string
  trip_id: string
  axle_count: number | null
  axle_spacings_in: number[] | null
  axle_weights_lbs: number[] | null
  truck_unit_number: string | null
  truck_vin: string | null
  truck_make: string | null
  truck_model: string | null
  truck_year: number | null
  trailer_unit_number: string | null
  trailer_vin: string | null
  trailer_make: string | null
  trailer_model: string | null
  trailer_year: number | null
  trailer_axle_count: number | null
  /** Kingpin to rear axle (KPTRA), inches — the last spacing (Task 76). */
  kingpin_to_rear_axle_in?: number | null
  created_at: string
  updated_at: string
}

export type TicketStatus =
  | 'new'
  | 'in_review'
  | 'needs_more_context'
  | 'escalated'
  | 'correction_proposed'
  | 'approved_for_knowledge_update'
  | 'knowledge_updated'
  | 'no_change_needed'
  | 'closed'
  | 'duplicate'

/** AI-answer review ticket (moderator dashboard) — feedback is a review trigger, never truth. */
export interface ReviewTicket {
  id: string
  trip_id: string
  message_id: string
  question_message_id: string | null
  user_id: string | null
  user_role: string | null
  state_code: string | null
  permit_id: string | null
  confidence: string | null
  /** What opened the ticket: user 👎, user report, or an AI-side signal (§5). */
  trigger: 'thumbs_down' | 'reported' | 'low_confidence_repeat' | 'no_source'
  feedback_reason: string | null
  user_comment: string | null
  category: string | null
  priority: 'high' | 'medium' | 'low' | null
  status: TicketStatus
  assigned_to: string | null
  moderator_notes: string | null
  decision: string | null
  correction: string | null
  correction_explanation: string | null
  correction_source: string | null
  correction_state: string | null
  correction_topic: string | null
  applies_to: 'this_permit' | 'all_permits' | null
  applies_states: 'one_state' | 'multiple_states' | null
  update_state_notes: boolean
  create_qa: boolean
  update_prompt_logic: boolean
  escalate_developer: boolean
  confidence_review:
    | 'appropriate'
    | 'too_high'
    | 'too_low'
    | 'should_have_escalated'
    | 'missing'
    | null
  source_alignment:
    | 'permit_matches_provision'
    | 'permit_conflicts_provision'
    | 'notes_add_exception'
    | 'internal_qa_used'
    | 'no_permit_available'
    | 'low_source_confidence'
    | null
  request_reference: string | null
  sources: string[] | null
  channel: string
  audience: string | null
  ui_context: string | null
  source_versions: Record<string, string> | null
  /** Asker's chat language at the time (§11 "language used"). */
  language: string | null
  /** Question → answer latency in ms (§11 "response time"). */
  response_ms: number | null
  /** Master ticket this one was merged into (§23). */
  duplicate_of: string | null
  close_reason: string | null
  /** Set on terminal statuses; drives average resolution time (§21). */
  resolved_at: string | null
  /** Knowledge-update routing (§17). */
  update_type:
    | 'state_note'
    | 'qa_entry'
    | 'prompt_logic'
    | 'retrieval'
    | 'ocr_parsing'
    | 'product_ui'
    | null
  /** Visibility class for a Q&A entry born from this correction (§18). */
  qa_visibility:
    | 'internal_only'
    | 'broker_facing'
    | 'carrier_facing'
    | 'driver_facing'
    | 'processing_team_only'
    | 'training_only'
    | 'do_not_use'
    | null
  created_at: string
  updated_at: string
}

/** Technical problem raised from a review ticket with full context (§24). */
export interface DeveloperIssue {
  id: string
  ticket_id: string
  error_category: string
  summary: string | null
  context: Record<string, unknown> | null
  status: 'open' | 'done'
  created_by: string | null
  created_at: string
}

/** Admin-configurable moderation settings: categories, state reviewers (§3, §22). */
export interface ModerationSetting {
  key: string
  value: unknown
  updated_by: string | null
  updated_at: string
}

export interface TicketEvent {
  id: string
  ticket_id: string
  actor: string | null
  action: string
  detail: Record<string, unknown> | null
  created_at: string
}

export interface TripEvent {
  id: string
  trip_id: string
  actor_id: string | null
  actor_label: string
  action: string
  detail: Record<string, unknown> | null
  created_at: string
}

/* ---------------- Company verification & agent approval (Tasks 88–94) ---------------- */

export type CompanyType = 'broker' | 'carrier'
/** Article §23 verification levels 0–4. */
export type CompanyVerificationStatus =
  | 'unverified'
  | 'public_data_matched'
  | 'corporate_contact_confirmed'
  | 'company_admin_approved'
  | 'manual_verified'
/** Article §12 role levels (carrier companies read manager/agent). */
export type CompanyRole =
  | 'company_owner'
  | 'company_admin'
  | 'broker_manager'
  | 'freight_broker'
  | 'billing_admin'
  | 'viewer'
  /** Carrier Dashboard → Company Info (2026-09-19): a dispatcher connected to a carrier. */
  | 'carrier_dispatcher'
export type MembershipStatus =
  | 'pending'
  | 'approved'
  | 'rejected'
  | 'revoked'
  /** Broker historical path (migration 0022): recognised from our records, asked to confirm. */
  | 'historical_pending_confirmation'
  | 'no_longer_current'
  | 'manual_review'
/** Who verified a company / relationship (generic — FMCSA now, Highway later, our own records). */
export type VerificationProvider = 'FMCSA' | 'HIGHWAY' | 'MANUAL_ADMIN' | 'COMPANY_ADMIN' | 'INTERNAL_HISTORICAL_RECORDS'
/** Permission inside the company, independent of role (migration 0021). */
export type CompanyPermissionLevel = 'member' | 'company_admin'
/** Where official company data / the official email was verified (generic — FMCSA first, Highway later). */
export type CompanyVerificationSource = 'FMCSA' | 'HIGHWAY' | 'MANUAL_ADMIN' | 'OTHER_VERIFIED_SOURCE'
export type OfficialEmailStatus = 'unverified' | 'pending' | 'verified' | 'rejected'
/** Article §4 company-relationship statuses (absence of a claim = no company connected). */
export type ClaimStatus =
  | 'company_claimed'
  | 'company_match_found'
  | 'company_verification_pending'
  | 'pending_corporate_approval'
  | 'approved'
  | 'rejected'
  | 'revoked'
  | 'admin_review_required'
/** Article §8 verification methods. */
export type VerificationMethod =
  | 'corporate_email_domain'
  | 'corporate_email_approval'
  | 'company_admin_approval'
  | 'manual_review'

export interface Company {
  id: string
  legal_name: string
  display_name: string
  dba_name: string | null
  company_type: CompanyType
  mc_number: string | null
  dot_number: string | null
  physical_address: string | null
  mailing_address: string | null
  corporate_email: string | null
  corporate_phone: string | null
  website: string | null
  logo_url: string | null
  verification_status: CompanyVerificationStatus
  verification_level: number
  source_fmcsa_id: string | null
  source_sos_id: string | null
  agents_see_all_trips: boolean
  notification_recipients: string[]
  locked: boolean
  merged_into: string | null
  is_placeholder: boolean
  /** Provenance (migration 0017). */
  source_system?: string | null
  source_record_id?: string | null
  ifta_number?: string | null
  /** Company Info (migration 0021). corporate_email is the official company email. */
  official_email_status?: OfficialEmailStatus | null
  official_email_verification_source?: CompanyVerificationSource | null
  official_email_verified_at?: string | null
  verification_source?: CompanyVerificationSource | null
  official_data_synced_at?: string | null
  operations_phone?: string | null
  operations_email?: string | null
  dispatch_contact?: string | null
  preferred_contact?: 'email' | 'phone' | 'operations_email' | 'operations_phone' | null
  description?: string | null
  /** Migration 0022. */
  verification_provider?: VerificationProvider | null
  verified_at?: string | null
  created_at: string
  updated_at: string
}

export interface CompanyMembership {
  id: string
  user_id: string
  company_id: string
  role: CompanyRole
  status: MembershipStatus
  approved_by: string | null
  approved_at: string | null
  revoked_by: string | null
  revoked_at: string | null
  /** Migration 0021 — absent until applied. */
  permission_level?: CompanyPermissionLevel | null
  requested_at?: string | null
  approved_by_user_id?: string | null
  rejected_at?: string | null
  rejected_by?: string | null
  rejected_by_user_id?: string | null
  rejection_reason?: string | null
  rejection_note?: string | null
  revoked_by_user_id?: string | null
  verification_method?: string | null
  verification_provider?: string | null
  updated_at?: string | null
  /** Migration 0022 — broker historical path. */
  confirmed_at?: string | null
  historically_verified?: boolean | null
  historical_verified_at?: string | null
  broker_lead_id?: string | null
  created_at: string
}

/** Pre-verified broker contact from historical business records (migration 0022). Never an account. */
export interface BrokerAgentLead {
  id: string
  first_name: string | null
  last_name: string | null
  email: string
  email_normalized: string
  phone: string | null
  phone_digits: string | null
  broker_company_id: string | null
  broker_company_name: string | null
  mc_number: string | null
  usdot_number: string | null
  historical_relationship_verified: boolean
  historical_verification_source: string
  historical_verified_at: string | null
  claim_status: 'unclaimed' | 'claimed' | 'manual_review'
  relationship_confirmation_status: 'not_confirmed' | 'confirmed_current' | 'no_longer_current'
  invitation_status: 'not_invited' | 'invited' | 'reminded' | 'opted_out'
  invited_at: string | null
  claimed_user_id: string | null
  claimed_at: string | null
  confirmed_at: string | null
  manual_review_reason: string | null
  import_batch: string | null
  source_row: Record<string, unknown> | null
  /** One lead engine, two kinds (migration 0039). Broker rows predate the column and read as 'broker'. */
  lead_kind?: 'broker' | 'carrier'
  /** Carrier leads: what the person did in the source system. */
  lead_type?: 'dispatcher' | 'driver' | 'both' | null
  company_name?: string | null
  source_record_id?: string | null
  source_status_active?: boolean | null
  source_created_at?: string | null
  created_at: string
  updated_at: string
}

/** A Company Admin's invitation to someone without an account yet (migration 0024). Never an account. */
export interface CompanyInvitation {
  id: string
  company_id: string
  company_type: CompanyType
  email: string
  email_normalized: string
  name: string | null
  permission_level: CompanyPermissionLevel
  invited_by_user_id: string | null
  invited_by_label: string
  template_key: string | null
  status: 'invited' | 'claimed' | 'revoked'
  claimed_user_id: string | null
  claimed_at: string | null
  revoked_at: string | null
  revoked_by_label: string | null
  created_at: string
  updated_at: string
}

/** One verification email as sent — the communication log (migration 0022). */
export interface VerificationEmailLog {
  id: string
  relationship_request_id: string | null
  membership_id: string | null
  company_id: string | null
  requester_user_id: string | null
  requester_label: string | null
  recipient: string
  template_key: string
  template_version: number | null
  template_version_id: string | null
  subject_sent: string | null
  kind: 'initial' | 'resend' | 'reminder'
  delivery_status: string
  provider: string | null
  message_id: string | null
  error: string | null
  token_id: string | null
  final_result: 'pending' | 'approved' | 'rejected' | 'expired' | 'cancelled' | 'reported'
  decided_at: string | null
  sent_at: string
  updated_at: string
}

export interface CompanyClaim {
  id: string
  user_id: string
  company_id: string
  requested_role: CompanyRole
  claim_status: ClaimStatus
  verification_method: VerificationMethod
  mc_number: string | null
  approval_sent_to: string | null
  approval_token: string
  expires_at: string
  approver_name: string | null
  approver_email: string | null
  approver_ip: string | null
  decided_at: string | null
  review_reason: string | null
  review_notes: string | null
  info_request: string | null
  created_at: string
  updated_at: string
}

export interface CompanyVerificationRecord {
  id: string
  company_id: string
  source: 'fmcsa' | 'sos' | 'corporate_email' | 'company_admin' | 'manual' | 'local'
  source_data: Record<string, unknown> | null
  match_score: 'high' | 'medium' | 'low' | 'none'
  verified_fields: string[]
  verified_at: string | null
  status: string
  created_at: string
}

/** A dispatcher's or broker's saved person (Tasks 98/99, 2026-09-09). */
export type ContactRole = 'driver' | 'broker' | 'dispatcher'

export interface CarrierContact {
  id: string
  owner_id: string
  name: string
  email: string
  phone: string | null
  phone_ext: string | null
  role: ContactRole
  /** Set once this person has a HeavyHaul Agent account. */
  user_id: string | null
  /** When an account invitation was recorded (email delivery is backend-later). */
  invited_at: string | null
  /** Last time they were added to a trip — orders the picker. */
  last_used_at: string | null
  created_at: string
  updated_at: string
}

export interface CompanyAuditEvent {
  id: string
  actor_user_id: string | null
  actor_label: string
  company_id: string | null
  event_type: string
  old_value: Record<string, unknown> | null
  new_value: Record<string, unknown> | null
  ip_address: string | null
  created_at: string
}

/* ---------------- Fleet registry & import log (migration 0017, 2026-09-14) ---------------- */

export type FleetUnitKind = 'truck' | 'trailer'

/** One axle of a unit's profile: its weight and the spacing to the NEXT axle (last = 0). */
export interface AxleProfileEntry {
  name: string
  weight_lbs: number | null
  spacing_in: number | null
}

/** A carrier's truck or trailer — one record, reused across trips. */
export interface FleetUnit {
  id: string
  company_id: string | null
  kind: FleetUnitKind
  unit_number: string | null
  vin: string | null
  license_plate: string | null
  license_state: string | null
  make: string | null
  model: string | null
  year: number | null
  axle_count: number | null
  trailer_type: string | null
  length_in: number | null
  empty_weight_lbs: number | null
  axle_profile: AxleProfileEntry[] | null
  registration_exp: string | null
  insurance_exp: string | null
  annual_inspection_exp: string | null
  owner_label: string | null
  status: 'active' | 'inactive'
  source_system: string | null
  source_record_id: string | null
  created_at: string
  updated_at: string
}

export interface FleetUnitDocument {
  id: string
  fleet_unit_id: string
  name: string
  expiration_date: string | null
  storage_provider: StorageProvider
  storage_path: string | null
  external_url: string | null
  source_system: string | null
  source_record_id: string | null
  created_at: string
}

export type ImportRunStatus = 'running' | 'completed' | 'failed'
export type ImportAction = 'created' | 'updated' | 'skipped' | 'failed'

/** One import execution (§23: controlled, logged, reversible). */
export interface ImportRun {
  id: string
  source_system: string
  scope: Record<string, unknown>
  dry_run: boolean
  status: ImportRunStatus
  started_at: string
  finished_at: string | null
  stats: Record<string, unknown> | null
  error: string | null
  triggered_by: string
}

export interface ImportRecord {
  id: string
  run_id: string
  source_table: string
  source_id: string
  target_table: string | null
  target_id: string | null
  action: ImportAction
  message: string | null
  created_at: string
}

/* ---------------- Synchron purchasing (migrations 0045–0047, 2026-09-29) ---------------- */

export type PurchaseStatus =
  | 'draft' | 'pending_checkout' | 'pending_payment' | 'paid' | 'payment_failed' | 'expired'
  | 'cancelled' | 'refund_pending' | 'partially_refunded' | 'refunded'

export type FulfillmentStatus =
  | 'awaiting_payment' | 'ready_for_processing' | 'submitted_to_synchron' | 'processing'
  | 'needs_review' | 'completed' | 'failed' | 'cancelled'

export type RouteProductCode = 'express_route' | 'extended_route'

/** HHA-owned routing product catalog. Prices are integer cents. */
export interface RoutingProduct {
  id: string
  product_code: RouteProductCode | string
  product_name: string
  description: string | null
  selling_price_cents: number
  currency: string
  active: boolean
  product_version: number
  created_at: string
  updated_at: string
}

export interface Purchase {
  id: string
  hha_user_id: string
  company_id: string | null
  hha_trip_id: string
  synchron_order_token: string | null
  synchron_user_token: string | null
  purchase_type: 'route'
  subtotal_cents: number
  total_amount_cents: number
  currency: string
  purchase_status: PurchaseStatus
  /** HHA purchase token shown to Synchron — NOT the Synchron order token. */
  purchase_reference: string
  idempotency_key: string
  needs_reconciliation: boolean
  created_at: string
  updated_at: string
}

export interface PurchaseItem {
  id: string
  purchase_id: string
  hha_permit_id: string | null
  synchron_permit_token: string | null
  hha_route_request_token: string | null
  service_request_id: string | null
  product_code: string
  route_type: 'express' | 'extended'
  /** Snapshot at purchase time — never re-read from the catalog. */
  unit_price_cents: number
  quantity: number
  line_total_cents: number
  currency: string
  product_version: number
  fulfillment_status: FulfillmentStatus
  created_at: string
  updated_at: string
}

export interface PaymentReference {
  id: string
  purchase_id: string
  synchron_purchase_token: string | null
  synchron_order_token: string | null
  stripe_checkout_session_id: string | null
  stripe_payment_intent_id: string | null
  stripe_charge_id: string | null
  payment_status: string | null
  payment_confirmed_at: string | null
  source_system: 'synchron' | 'mock'
  checkout_url: string | null
  last_synced_at: string | null
  created_at: string
  updated_at: string
}

export interface PurchaseEvent {
  id: string
  purchase_id: string | null
  purchase_item_id: string | null
  trip_id: string | null
  event: string
  actor_user_id: string | null
  actor_label: string | null
  source_system: 'hha' | 'synchron' | 'mock'
  synchron_order_token: string | null
  purchase_reference: string | null
  external_event_id: string | null
  detail: Record<string, unknown>
  created_at: string
}

export interface TripCart {
  id: string
  trip_id: string
  user_id: string
  status: 'open' | 'checked_out' | 'abandoned'
  purchase_id: string | null
  created_at: string
  updated_at: string
}

export interface TripCartItem {
  id: string
  cart_id: string
  permit_id: string
  product_code: string
  quantity: number
  added_at: string
}

export interface PermitRequestDraft {
  id: string
  trip_id: string
  user_id: string
  state_codes: string[]
  notes: string | null
  document_ids: string[]
  notify: string[] | null
  readiness_status: string | null
  /** Synchron card-setup / confirmation session the draft waits on (migration 0048; may be absent). */
  setup_reference?: string | null
  status: 'pending' | 'resumed' | 'submitted' | 'abandoned'
  created_at: string
  updated_at: string
}
