import { Badge, Box, Text } from "@mantine/core";
import { Check } from "lucide-react";

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

import {
  CONTRACT_PROGRESS_STAGES,
  PROGRESS_STAGES,
  resolveContractStage,
  resolveStage,
} from "../constants";
import { isNegative } from "../utils";

type StepState = "done" | "active" | "idle" | "skipped";

interface JourneyStep {
  key: string;
  label: string;
  state: StepState;
  /** Milestone owner region (customs flow only) — rendered as a tiny badge. */
  owner?: string;
}

const OWNER_LABELS: Record<string, string> = {
  CUST: "You",
  ET: "GL Ethiopia",
  DJ: "GL Djibouti",
  OPS: "Operations",
};

/**
 * The single source for the booking-journey wizard steps.
 *
 * Customs (Path B) bookings: the backend GL milestone catalog IS the
 * end-to-end process — documents → review → customs declaration → duty/tax →
 * wagon & freight payment → loading → transit → arrival → release. Those rows
 * are rendered directly (post-booking milestones appear once GL seeds them),
 * framed by the booking-level steps the catalog does not carry: the prepaid
 * clearance service fee gate at the start and final delivery at the end.
 *
 * Non-customs bookings: the existing lifecycle stage sets (direct vs
 * contract-drawdown) — no customs steps ever show up.
 */
export function buildJourneySteps(
  booking: Freight.IBooking,
  milestones: Freight.IClearanceMilestone[],
): JourneyStep[] {
  const status = booking.status as string;
  const isCustoms = Boolean(booking.customsClearingEnabled);

  if (isCustoms && milestones.length > 0) {
    const sorted = [...milestones].sort((a, b) => a.sortOrder - b.sortOrder);
    const firstPendingId = sorted.find((m) => m.status === "PENDING")?.id;
    const delivered = ["COMPLETED", "DELIVERED"].includes(status);

    const steps: JourneyStep[] = [
      { key: "booked", label: "Booking initiated", state: "done" },
      ...sorted.map<JourneyStep>((m) => ({
        key: m.id,
        label: m.milestoneLabel,
        owner: m.ownerRegion ?? undefined,
        state:
          m.status === "COMPLETED"
            ? "done"
            : m.status === "SKIPPED"
              ? "skipped"
              : m.id === firstPendingId
                ? "active"
                : "idle",
      })),
      { key: "delivered", label: "Delivered", state: delivered ? "done" : "idle" },
    ];
    // Every known milestone is done but the booking hasn't closed yet — the
    // delivery step is what's in progress.
    if (!firstPendingId && !delivered) {
      steps[steps.length - 1].state = "active";
    }
    return steps;
  }

  const contractFlow = Boolean(booking.contractId) && !isNegative(status);
  const stages = contractFlow ? CONTRACT_PROGRESS_STAGES : PROGRESS_STAGES;
  const current = contractFlow
    ? resolveContractStage(booking)
    : resolveStage(booking);
  return stages.map((s, idx) => ({
    key: s.label,
    label: s.label,
    state: idx < current ? "done" : idx === current ? "active" : "idle",
  }));
}

/**
 * One large wizard for the whole booking journey. Steps flow left→right and
 * wrap onto the next row when the process is long (customs imports run ~20
 * steps → 2–3 rows) — no sideways scrolling, everything visible at once.
 */
export function JourneyWizard({
  booking,
  milestones = [],
}: {
  booking: Freight.IBooking;
  milestones?: Freight.IClearanceMilestone[];
}) {
  const steps = buildJourneySteps(booking, milestones);
  const last = steps.length - 1;

  return (
    <Box
      style={{
        display: "grid",
        gridTemplateColumns: "repeat(auto-fill, minmax(104px, 1fr))",
        rowGap: 22,
      }}
    >
      {steps.map((s, idx) => {
        const done = s.state === "done";
        const active = s.state === "active";
        const skipped = s.state === "skipped";
        // A connector segment turns green once the step to its left completed
        // (skipped steps pass progress through).
        const prev = idx > 0 ? steps[idx - 1] : undefined;
        const leftOn =
          !!prev && (prev.state === "done" || prev.state === "skipped");
        const rightOn = done || skipped;
        const ownerLabel = s.owner ? OWNER_LABELS[s.owner] : undefined;

        return (
          <Box key={s.key} miw={0}>
            {/* rail: left connector · circle · right connector */}
            <Box style={{ display: "flex", alignItems: "center" }}>
              <Box
                style={{
                  height: 3,
                  flex: 1,
                  borderRadius: 999,
                  backgroundColor:
                    idx === 0 ? "transparent" : leftOn ? "#0EA371" : "#E1E7EE",
                }}
              />
              <Box
                style={{
                  width: 26,
                  height: 26,
                  borderRadius: 999,
                  display: "flex",
                  alignItems: "center",
                  justifyContent: "center",
                  flexShrink: 0,
                  fontSize: 11,
                  fontWeight: 700,
                  backgroundColor: done
                    ? "#0EA371"
                    : active
                      ? "#0C1A2B"
                      : "#EEF2F6",
                  color: done || active ? "#fff" : "#9AA8B5",
                  border: done || active ? undefined : "1px solid #E1E7EE",
                  boxShadow: active ? "0 0 0 4px #D9E0E7" : undefined,
                }}
              >
                {done ? <Check size={14} strokeWidth={3} /> : idx + 1}
              </Box>
              <Box
                style={{
                  height: 3,
                  flex: 1,
                  borderRadius: 999,
                  backgroundColor:
                    idx === last ? "transparent" : rightOn ? "#0EA371" : "#E1E7EE",
                }}
              />
            </Box>
            {/* label (+ owner badge) centered under the circle */}
            <Box mt={7} px={4} style={{ textAlign: "center" }}>
              <Text
                fz="11.5px"
                fw={active ? 800 : 700}
                lh={1.25}
                c={done || active ? "#10202F" : "#9AA8B5"}
                td={skipped ? "line-through" : undefined}
                lineClamp={2}
              >
                {s.label}
              </Text>
              {ownerLabel && (
                <Badge
                  size="xs"
                  variant="light"
                  color={s.owner === "CUST" ? "orange" : "gray"}
                  radius="sm"
                  tt="none"
                  mt={3}
                >
                  {ownerLabel}
                </Badge>
              )}
            </Box>
          </Box>
        );
      })}
    </Box>
  );
}
