import type { Freight } from "@edr/types";

/**
 * The customer-actionable clearance/operation steps a booking can be sitting on.
 * These are the statuses where the *customer* must do something next — upload
 * documents, re-upload a queried document, or pick a shipment day and proceed
 * to operation.
 */
export type BookingActionKind =
  | "UPLOAD_DOCUMENTS" // AWAITING_DOCUMENTS — upload the required clearance docs
  | "FIX_DOCUMENTS" // DOCUMENTS_UNDER_REVIEW — some docs queried, re-upload them
  | "SCHEDULE_OPERATION" // CLEARANCE_READY (legacy with cargo) — pick a day and proceed
  | "BOOK"; // CLEARANCE_READY bare instance — navigate to the booking form

export interface BookingNextAction {
  kind: BookingActionKind;
  /** Button label shown on the My Shipments row. */
  label: string;
  /** Modal title. */
  title: string;
  /** Set for navigation actions (BOOK) — the button navigates instead of opening the modal. */
  to?: string;
}

const ACTION_BY_STATUS: Record<string, BookingNextAction> = {
  AWAITING_DOCUMENTS: {
    kind: "UPLOAD_DOCUMENTS",
    label: "Upload documents",
    title: "Upload clearance documents",
  },
  DOCUMENTS_UNDER_REVIEW: {
    kind: "FIX_DOCUMENTS",
    label: "Review documents",
    title: "Clearance documents",
  },
  CLEARANCE_READY: {
    kind: "SCHEDULE_OPERATION",
    label: "Schedule & proceed",
    title: "Schedule your shipment",
  },
};

type ActionBooking = Pick<
  Freight.IBooking,
  "id" | "status" | "contractId" | "totalAmount" | "customsClearingEnabled"
>;

/** Initiated instance still carrying no cargo/price (clearance-first flow). */
function isBareInstance(booking: ActionBooking): boolean {
  return (
    Boolean(booking.contractId) && !(Number(booking.totalAmount ?? 0) > 0)
  );
}

/**
 * Resolve the customer's next clearance/operation action for a booking, or
 * `null` when there's nothing for them to do at this stage. Pure + cheap so it
 * can be called inline while rendering a list row.
 *
 * Note: `DOCUMENTS_UNDER_REVIEW` always surfaces an action because the customer
 * may need to re-upload a queried document; the modal itself shows a read-only
 * "under review" state when nothing is actually queried.
 */
export function getBookingNextAction(
  booking: ActionBooking,
): BookingNextAction | null {
  if (booking.status === "CLEARANCE_READY" && isBareInstance(booking)) {
    // Customs (Path B): GL completes the booking — the customer can only view
    // the finished clearance in the modal.
    if (booking.customsClearingEnabled) {
      return {
        kind: "SCHEDULE_OPERATION",
        label: "View clearance",
        title: "Clearance complete",
      };
    }
    // Non-customs (Path A): straight to the booking form — cargo + shipment
    // day + window check, the same page a one-time booking uses.
    return {
      kind: "BOOK",
      label: "Book",
      title: "Book your shipment",
      to: `/contracts/${booking.contractId}/bookings/${booking.id}/complete`,
    };
  }
  return ACTION_BY_STATUS[booking.status as string] ?? null;
}

/**
 * Whether a booking has an in-place action the customer can take from a list
 * row via a modal — either a clearance/operation step, or a CHANGES_REQUESTED
 * booking that needs documents updated and resubmitting. Used to decide whether
 * to render {@link BookingActionButton}.
 */
export function bookingHasInlineAction(booking: ActionBooking): boolean {
  return (
    booking.status === "CHANGES_REQUESTED" ||
    getBookingNextAction(booking) !== null
  );
}
