"use client";

import Link from "next/link";
import { Check, Store, Package, MapPin, TriangleAlert } from "lucide-react";
import { useT } from "@/i18n";
import { cn } from "@/lib/cn";
import type { Order, OrderCollectionLeg, OrderStatus } from "@/types/order";

/**
 * A wrapped delivery drawn as the journey it actually is.
 *
 * Suppliers → wrapping shop → customer, in three stops and two legs, with the leg that is
 * moving right now picked out. The badges and cross-links say *that* an order has another half;
 * this says **what the two halves are for**, which is the thing nobody can infer from a status
 * and an address.
 *
 * It reads from either end of the pair, because a dispatcher arrives at one or the other and
 * needs the same picture: from the collection leg the suppliers and the customer's name come
 * from this row and its parent, from the delivery leg they come from this row and its child.
 *
 * Vertical rather than a horizontal rail, deliberately: it has to read identically in Arabic,
 * and a vertical stepper has no direction to get wrong.
 */

type LegState = "done" | "active" | "blocked" | "failed" | "upcoming";

export function WrappedJourney({ order }: { order: Order }) {
  const t = useT();

  const isCollection = order.leg === "collection";
  const parent = order.parent_order ?? null;
  const children = order.collection_legs ?? [];

  if (!order.leg) {
    return null;
  }

  // The collection leg, whichever side we are standing on.
  const collection: OrderCollectionLeg | null = isCollection
    ? {
        uuid: order.uuid,
        order_number: order.order_number,
        status: order.status,
        status_label: order.status_label,
        failed_reason: order.failed_reason ?? null,
      }
    : (children[0] ?? null);

  // And the delivery leg.
  const delivery = isCollection
    ? parent
    : {
        uuid: order.uuid,
        order_number: order.order_number,
        status: order.status,
        status_label: order.status_label,
        customer_name: order.customer_name,
      };

  const wrappingAddress = isCollection ? order.dropoff_address : order.pickup_address;
  const customerName = isCollection ? (parent?.customer_name ?? null) : order.customer_name;
  const supplierCount = isCollection ? (order.pickups?.length ?? null) : null;

  const collectionState = legState(collection?.status);
  // The delivery cannot start until the goods land, so "upcoming" is the honest state for it
  // while the collection is still moving — not "pending", which would read as ready to dispatch.
  const deliveryState: LegState =
    collectionState === "failed"
      ? "blocked"
      : collectionState === "done"
        ? legState(delivery?.status)
        : "upcoming";

  return (
    <ol className="space-y-0">
      <Stop
        icon={Store}
        title={t("orders.journey.suppliers")}
        caption={
          supplierCount !== null
            ? t("orders.journey.supplierCount", { count: supplierCount })
            : (order.pickup_address ?? null)
        }
        state={collectionState === "upcoming" ? "upcoming" : "done"}
      />

      <Leg
        label={t("orders.legs.collection")}
        leg={collection}
        state={collectionState}
        hint={t("orders.journey.collectionHint")}
      />

      <Stop
        icon={Package}
        title={t("orders.journey.wrapper")}
        caption={wrappingAddress}
        state={collectionState === "done" ? "done" : collectionState === "failed" ? "failed" : "upcoming"}
      />

      <Leg
        label={t("orders.legs.delivery")}
        leg={delivery ? { ...delivery, failed_reason: null } : null}
        state={deliveryState}
        hint={t("orders.journey.deliveryHint")}
      />

      <Stop
        icon={MapPin}
        title={t("orders.journey.customer")}
        caption={customerName}
        state={deliveryState === "done" ? "done" : "upcoming"}
        last
      />
    </ol>
  );
}

/** One place the goods stand still. */
function Stop({
  icon: Icon,
  title,
  caption,
  state,
  last = false,
}: {
  icon: React.ComponentType<{ className?: string }>;
  title: string;
  caption?: string | null;
  state: LegState;
  last?: boolean;
}) {
  const reached = state === "done";

  return (
    <li className="flex gap-3">
      <div className="flex flex-col items-center">
        <span
          className={cn(
            "flex h-7 w-7 shrink-0 items-center justify-center rounded-full border",
            reached
              ? "border-success/30 bg-success-soft text-success"
              : state === "failed"
                ? "border-destructive/30 bg-destructive-soft text-destructive"
                : "border-border bg-muted text-muted-foreground",
          )}
        >
          {reached ? <Check className="h-3.5 w-3.5" aria-hidden /> : <Icon className="h-3.5 w-3.5" aria-hidden />}
        </span>
        {!last ? <span className="w-px flex-1 bg-border" aria-hidden /> : null}
      </div>

      <div className={cn("min-w-0 pb-1", last ? "" : "pb-3")}>
        <p className="text-sm font-medium text-foreground">{title}</p>
        {caption ? <p className="truncate text-xs text-muted-foreground">{caption}</p> : null}
      </div>
    </li>
  );
}

/** One captain's drive between two stops — and the order that records it. */
function Leg({
  label,
  leg,
  state,
  hint,
}: {
  label: string;
  leg: { uuid: string; order_number: string; status_label: string; failed_reason?: string | null } | null;
  state: LegState;
  hint: string;
}) {
  const t = useT();

  return (
    <li className="flex gap-3">
      <div className="flex flex-col items-center">
        <span
          className={cn(
            "w-px flex-1",
            state === "done"
              ? "bg-success/40"
              : state === "failed"
                ? "bg-destructive/40"
                : state === "active"
                  ? "bg-primary/50"
                  : "bg-border",
          )}
          aria-hidden
        />
      </div>

      <div className="min-w-0 pb-3">
        <div
          className={cn(
            "rounded-lg border px-3 py-2",
            state === "failed"
              ? "border-destructive/25 bg-destructive-soft/50"
              : state === "active"
                ? "border-primary/25 bg-primary-soft/40"
                : state === "blocked"
                  ? "border-warning/25 bg-warning-soft/40"
                  : "border-border/60",
          )}
        >
          <div className="flex flex-wrap items-center gap-2">
            <span className="text-xs font-medium text-muted-foreground">{label}</span>
            {leg ? (
              <Link href={`/orders/${leg.uuid}`} className="text-sm font-semibold text-primary hover:underline">
                {leg.order_number}
              </Link>
            ) : (
              <span className="text-sm text-muted-foreground">{t("common.notAvailable")}</span>
            )}
            {leg ? (
              <span className="text-xs text-muted-foreground">· {leg.status_label}</span>
            ) : null}
          </div>

          <p className="mt-0.5 text-xs text-muted-foreground">{hint}</p>

          {leg?.failed_reason ? (
            <p className="mt-1 flex items-start gap-1 text-xs text-destructive">
              <TriangleAlert className="mt-0.5 h-3.5 w-3.5 shrink-0" aria-hidden />
              <span>{leg.failed_reason}</span>
            </p>
          ) : null}
        </div>
      </div>
    </li>
  );
}

function legState(status?: OrderStatus | null): LegState {
  if (!status) return "upcoming";
  if (status === "delivered") return "done";
  if (status === "delivery_failed" || status === "cancelled") return "failed";
  if (status === "pending") return "upcoming";

  return "active";
}
