import { Badge, Box, Group, Text } from "@mantine/core";
import { Link } from "react-router-dom";
import type { Freight } from "@edr/types";

import { STATUS_CONFIG } from "@/pages/MyPortalPage/constants";

/**
 * Shared presentation helpers for booking-like rows (one-time bookings AND
 * general contracts). Kept in one place so the bookings list, contracts list,
 * and detail page render type/freight/mode/payment consistently.
 */

/**
 * The parent contract's reference, rendered small under a booking reference and
 * linking to that contract's detail page.
 *
 * Renders nothing when either field is missing: `contractId` is nullable on the
 * booking, and only the bookings list/detail endpoints join `contractReference`
 * — other endpoints (warehouse, fleet, payments) return booking rows without it,
 * and a link with no id would be a dead one.
 *
 * `stopPropagation` matters: booking rows are click-to-navigate, so without it a
 * click here would race the row handler and land on the booking instead.
 */
export function ContractReferenceLink({
  booking,
}: {
  booking: Pick<Freight.IBooking, "contractId" | "contractReference">;
}) {
  if (!booking.contractId || !booking.contractReference) return null;

  return (
    <Text
      component={Link}
      to={`/contracts/${booking.contractId}`}
      onClick={(e) => e.stopPropagation()}
      fz={11}
      c="edr-muted"
      truncate
      style={{ display: "block", textDecoration: "underline" }}
    >
      {booking.contractReference}
    </Text>
  );
}

/** Title-case an unmapped enum as a readable fallback ("FOO_BAR" → "Foo Bar"). */
export function titleCaseStatus(status: string): string {
  return status
    .replace(/_/g, " ")
    .toLowerCase()
    .replace(/\b\w/g, (m) => m.toUpperCase());
}

/**
 * Human label for a booking status. Single source of truth is the booking
 * list's `STATUS_CONFIG` badge labels; anything not mapped there falls back to
 * a readable title-cased form (never the raw SCREAMING_SNAKE enum).
 */
export function bookingStatusLabel(status?: string | null): string {
  if (!status) return "—";
  return STATUS_CONFIG[status]?.badgeLabel ?? titleCaseStatus(status);
}

type BookingLike = Freight.IBooking & {
  bookingType?: string;
  freightType?: string;
  tradeDirection?: string;
  paymentStatus?: string;
};

/** One-Time vs General Contract (or a drawdown under a GENERAL contract). */
export function BookingTypeBadge({ booking }: { booking: BookingLike }) {
  const isContract = booking.bookingType === "GENERAL_CONTRACT";
  // Drawdown bookings keep bookingType = ONE_TIME; the parent contract's kind
  // (denormalized onto the booking) is what makes them "General".
  const isGeneralDrawdown = !isContract && booking.contractKind === "GENERAL";
  return (
    <Badge
      variant="light"
      radius="sm"
      color={isContract || isGeneralDrawdown ? "violet" : "gray"}
      styles={{ root: { textTransform: "none", fontWeight: 600, letterSpacing: 0 } }}
    >
      {isContract ? "General Contract" : isGeneralDrawdown ? "General" : "One-Time"}
    </Badge>
  );
}

/** Containerised vs Bulk, plus the trade direction (Import/Export/Domestic). */
export function CargoModeCell({ booking }: { booking: BookingLike }) {
  const freight =
    booking.freightType === "BULK" ? "Bulk" : "Container";
  const dir = booking.tradeDirection
    ? booking.tradeDirection.charAt(0) + booking.tradeDirection.slice(1).toLowerCase()
    : null;
  return (
    <Group gap={6} wrap="nowrap">
      <Badge
        variant="light"
        radius="sm"
        color={booking.freightType === "BULK" ? "orange" : "teal"}
        styles={{ root: { textTransform: "none", fontWeight: 600, letterSpacing: 0 } }}
      >
        {freight}
      </Badge>
      {dir && (
        <Text fz={12} c="edr-muted">
          {dir}
        </Text>
      )}
    </Group>
  );
}

const PAYMENT_COLORS: Record<string, string> = {
  PAID: "green",
  PENDING: "gray",
  PNR_GENERATED: "blue",
  // Backend emits the long form on some flows; keep the short alias too.
  VERIFICATION_IN_PROGRESS: "yellow",
  PAYMENT_VERIFICATION_IN_PROGRESS: "yellow",
  OVERDUE: "red",
  REFUNDED: "blue",
  CANCELLED: "gray",
  FAILED: "red",
};

const PAYMENT_LABELS: Record<string, string> = {
  PAID: "Paid",
  PENDING: "Pending",
  PNR_GENERATED: "PNR generated",
  VERIFICATION_IN_PROGRESS: "Verifying",
  PAYMENT_VERIFICATION_IN_PROGRESS: "Verifying",
  OVERDUE: "Overdue",
  REFUNDED: "Refunded",
  CANCELLED: "Cancelled",
  FAILED: "Failed",
};

/** Human label for a payment status (plain text, no badge). */
export function paymentStatusLabel(status?: string | null): string {
  if (!status) return "—";
  return PAYMENT_LABELS[status] ?? titleCaseStatus(status);
}

/** Payment status pill. */
export function PaymentBadge({ status }: { status?: string | null }) {
  if (!status) return <Text fz={13} c="dimmed">—</Text>;
  return (
    <Badge
      variant="light"
      radius="sm"
      color={PAYMENT_COLORS[status] ?? "gray"}
      styles={{ root: { textTransform: "none", fontWeight: 600, letterSpacing: 0 } }}
    >
      {PAYMENT_LABELS[status] ?? titleCaseStatus(status)}
    </Badge>
  );
}

/** Booking status pill (dot + label) driven by the shared STATUS_CONFIG. */
export function BookingStatusBadge({ status }: { status: string }) {
  const cfg = STATUS_CONFIG[status];
  const label = cfg?.badgeLabel ?? titleCaseStatus(status);
  const bg = cfg ? `var(--mantine-color-${cfg.badgeBg}-0, #F1F4F7)` : "#F1F4F7";
  const text = cfg
    ? `var(--mantine-color-${cfg.badgeText}-7, #475569)`
    : "#475569";
  const dot = cfg
    ? `var(--mantine-color-${cfg.badgeDot}-6, #94A3B8)`
    : "#94A3B8";
  return (
    <Group
      gap={6}
      align="center"
      wrap="nowrap"
      style={{
        display: "inline-flex",
        borderRadius: 999,
        backgroundColor: bg,
        padding: "5px 11px",
      }}
    >
      <Box
        style={{
          width: 6,
          height: 6,
          borderRadius: "50%",
          backgroundColor: dot,
          flexShrink: 0,
        }}
      />
      <Text fz={11} fw={700} style={{ color: text, whiteSpace: "nowrap" }}>
        {label}
      </Text>
    </Group>
  );
}

/** Whether a booking is assigned to a train yet (scheduling progress). */
export function SchedulingCell({ booking }: { booking: BookingLike & { trainScheduleId?: string | null; schedulingStatus?: string } }) {
  const assigned = !!booking.trainScheduleId;
  const label = assigned
    ? "Assigned"
    : booking.schedulingStatus === "HOLDING"
      ? "Holding"
      : booking.schedulingStatus === "ELIGIBLE"
        ? "Eligible"
        : "Not scheduled";
  return (
    <Badge
      variant="dot"
      radius="sm"
      color={assigned ? "green" : "gray"}
      styles={{ root: { textTransform: "none", fontWeight: 600, letterSpacing: 0 } }}
    >
      {label}
    </Badge>
  );
}
