"use client";

import { Check, CircleDashed, MapPin, TriangleAlert } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { useI18n, useT } from "@/i18n";
import { formatCurrency, formatDateTime } from "@/lib/format";
import { OrderItemLine } from "@/features/orders/order-item-line";
import type { Order, OrderPickupStop } from "@/types/order";

/**
 * The counters an order is collected from, each with what happened there.
 *
 * The order already carries one `amount_paid` and one `items_mismatch`, and on an order gathered
 * from three shops those say an errand went wrong without saying where. A desk ringing the captain
 * to ask which shop was short is a phone call that this screen exists to avoid.
 *
 * Drawn for a single-supplier order too. Almost every order has exactly one stop, and a list of
 * one is still the honest shape — hiding it below a threshold would mean the screen changes form
 * depending on data, which is harder to learn than a list that is sometimes short.
 */
export function OrderPickupStops({ order }: { order: Order }) {
  const t = useT();
  const { locale } = useI18n();

  const stops = order.pickups ?? [];

  if (stops.length === 0) {
    return null;
  }

  const outstanding = stops.filter((stop) => !stop.collected).length;

  return (
    <Card className="mt-6">
      <CardHeader>
        <CardTitle className="flex flex-wrap items-center gap-2">
          <MapPin className="h-4 w-4 text-muted-foreground" aria-hidden />
          {t("orders.stops.title")}
          <Badge variant="secondary" className="font-normal">
            {outstanding === 0
              ? t("orders.stops.allCollected")
              : t("orders.stops.outstanding", { count: outstanding })}
          </Badge>
        </CardTitle>
      </CardHeader>

      <CardContent className="space-y-3">
        {stops.map((stop, index) => (
          <Stop key={stop.uuid} stop={stop} position={index + 1} currency={order.currency} locale={locale} t={t} />
        ))}
      </CardContent>
    </Card>
  );
}

function Stop({
  stop,
  position,
  currency,
  locale,
  t,
}: {
  stop: OrderPickupStop;
  position: number;
  currency: string | null;
  locale: Parameters<typeof formatCurrency>[2];
  t: ReturnType<typeof useT>;
}) {
  const items = stop.items ?? [];

  return (
    <div className="rounded-lg border p-3">
      <div className="flex flex-wrap items-start justify-between gap-2">
        <div className="flex items-start gap-3">
          <span
            className={
              stop.collected
                ? "flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-success-soft text-success"
                : "flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground"
            }
          >
            {stop.collected ? <Check className="h-4 w-4" aria-hidden /> : <CircleDashed className="h-4 w-4" aria-hidden />}
          </span>

          <div className="min-w-0">
            <p className="font-medium text-foreground">
              <span className="text-muted-foreground">{stop.sequence ?? position}.</span>{" "}
              {stop.store_name ?? t("orders.stops.unnamedStore")}
            </p>
            <p className="text-sm text-muted-foreground">{stop.address}</p>
            {stop.collected_at ? (
              <p className="mt-1 text-xs text-muted-foreground">
                {t("orders.stops.collectedAt", { at: formatDateTime(stop.collected_at, locale) })}
              </p>
            ) : null}
          </div>
        </div>

        {stop.items_mismatch ? (
          <Badge variant="warning" className="gap-1">
            <TriangleAlert className="h-3 w-3" aria-hidden />
            {t("orders.stops.mismatch")}
          </Badge>
        ) : null}
      </div>

      {/*
        The money at this counter: expected beside paid, never one in place of the other. A figure
        on its own cannot say whether a captain was short, and the gap is the whole reason for
        recording it per stop.
      */}
      <dl className="mt-3 grid grid-cols-2 gap-x-4 gap-y-2 text-sm sm:grid-cols-4">
        <Figure label={t("orders.stops.expected")} value={formatCurrency(stop.expected_goods_cost, currency, locale)} />
        <Figure label={t("orders.stops.paid")} value={formatCurrency(stop.amount_paid, currency, locale)} />
        <Figure
          label={t("orders.stops.variance")}
          value={formatCurrency(stop.amount_variance, currency, locale)}
          tone={stop.amount_variance !== null && stop.amount_variance !== 0 ? "warning" : undefined}
        />
        <Figure
          label={t("orders.stops.itemsCollected")}
          value={stop.items_collected === null ? t("orders.stops.oneTap") : String(stop.items_collected)}
        />
      </dl>

      {items.length > 0 ? (
        <div className="mt-3 space-y-2 border-t pt-3">
          {items.map((item) => (
            <div key={item.uuid} className="flex items-start justify-between gap-3">
              <OrderItemLine item={item} />
              <span className="numeric shrink-0 text-sm text-muted-foreground">×{item.quantity}</span>
            </div>
          ))}
        </div>
      ) : null}
    </div>
  );
}

function Figure({ label, value, tone }: { label: string; value: string; tone?: "warning" }) {
  return (
    <div>
      <dt className="text-xs text-muted-foreground">{label}</dt>
      <dd className={tone === "warning" ? "numeric font-medium text-warning" : "numeric font-medium text-foreground"}>
        {value}
      </dd>
    </div>
  );
}
