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

/**
 * Trip status machine (from the meeting + analysis doc §3):
 * draft → waiting_for_permits → active → completed
 * Any non-terminal state may be cancelled. Completed/cancelled are terminal
 * except completed → active (reopen, per "maybe they had an accident and you
 * go back in time and look into it").
 */
const TRANSITIONS: Record<TripStatus, TripStatus[]> = {
  draft: ['waiting_for_permits', 'active', 'cancelled'],
  waiting_for_permits: ['active', 'completed', 'cancelled'],
  active: ['completed', 'cancelled'],
  completed: ['active'],
  cancelled: [],
}

/** Roles allowed to change trip status manually. */
const STATUS_MANAGER_ROLES: TripRole[] = ['broker', 'dispatcher', 'admin']

export function canTransition(from: TripStatus, to: TripStatus): boolean {
  return TRANSITIONS[from]?.includes(to) ?? false
}

export function canManageStatus(role: TripRole): boolean {
  return STATUS_MANAGER_ROLES.includes(role)
}

/**
 * Trip-wide ACTIVATION is open to every working role on the trip, including
 * the driver (2026-09-07, Task 67). Nash: "the carrier should have the ability
 * to change the status of the order into active, and it will be activated for
 * all users… The same thing with the driver… And the same thing should be done
 * for the broker. This is not per user, this is for the entire trip."
 *
 * Deliberately separate from canManageStatus: completing-for-everyone and
 * cancelling stay broker / dispatcher / admin only.
 */
const TRIP_ACTIVATOR_ROLES: TripRole[] = ['broker', 'dispatcher', 'driver', 'admin']
const PRE_ACTIVE_STATUSES: TripStatus[] = ['draft', 'waiting_for_permits']

export function canActivateTrip(role: TripRole, current: TripStatus): boolean {
  return TRIP_ACTIVATOR_ROLES.includes(role) && PRE_ACTIVE_STATUSES.includes(current)
}

/** First processed permit activates a waiting trip (MVP default). */
export function statusAfterPermitProcessed(current: TripStatus): TripStatus {
  if (current === 'draft' || current === 'waiting_for_permits') return 'active'
  return current
}

export const STATUS_LABELS: Record<TripStatus, string> = {
  draft: 'Draft',
  waiting_for_permits: 'Waiting for Permits',
  active: 'Active',
  completed: 'Completed',
  cancelled: 'Cancelled',
}

/**
 * How a trip is bucketed in the driver's "My Trips" list. Shared so the server
 * (which must know WHICH trip to load chat for) and the client render the same
 * split.
 */
export const ACTIVE_STATUSES: TripStatus[] = ['active', 'waiting_for_permits', 'draft']
export const PREVIOUS_STATUSES: TripStatus[] = ['completed', 'cancelled']

export function isActiveStatus(status: TripStatus): boolean {
  return ACTIVE_STATUSES.includes(status)
}

/* ---------------- Per-participant completion (2026-09-07) ---------------- */

/**
 * Nash: "this marks it complete for me as the user… any other users on their
 * dashboard, they could probably see that somebody marked it as completed, and
 * do you wish to complete also? But don't complete it by default for everybody
 * else… I don't want to force close, force complete for all users this trip."
 *
 * Only the active↔completed axis is per person. `draft`, `waiting_for_permits`
 * and `cancelled` describe permit processing and the trip as a whole, not one
 * person's involvement, so they stay trip-wide and still come from
 * `trips.status`.
 */
export type TripCompletion = {
  /** This user's own participant row id, when they are on the trip. */
  myParticipantId: string | null
  /** Set once this user marked the trip complete for themselves. */
  completedAt: string | null
  /** Set once they answered the "someone else completed this" prompt. */
  promptDismissedAt: string | null
  /** Other participants who completed it for themselves. */
  othersCompleted: Array<{ name: string; role: string; completedAt: string }>
}

export const EMPTY_COMPLETION: TripCompletion = {
  myParticipantId: null,
  completedAt: null,
  promptDismissedAt: null,
  othersCompleted: [],
}

/** The status THIS user should see for a trip. */
export function resolveStatusForUser(
  tripStatus: TripStatus,
  completion: TripCompletion | undefined,
): TripStatus {
  // A cancelled trip is cancelled for everyone — a personal completion never
  // overrides it.
  if (tripStatus === 'cancelled') return 'cancelled'
  return completion?.completedAt ? 'completed' : tripStatus
}

/**
 * Show the "somebody marked this completed — is that correct?" prompt when
 * someone else completed it, this user has not, and has not already answered.
 */
export function shouldPromptCompletion(completion: TripCompletion | undefined): boolean {
  if (!completion?.myParticipantId) return false
  if (completion.completedAt || completion.promptDismissedAt) return false
  return completion.othersCompleted.length > 0
}
