"use client";

import Link from "next/link";
import { useParams } from "next/navigation";
import { useQuery } from "@tanstack/react-query";
import { AlertTriangle, ArrowLeft, ArrowRight, Package } from "lucide-react";
import { PageHeader } from "@/components/shared/page-header";
import { EmptyState, ErrorState } from "@/components/shared/states";
import { OrderStatusBadge } from "@/components/shared/status-badges";
import { Card } from "@/components/ui/card";
import { Skeleton } from "@/components/ui/skeleton";
import { OrderTimeline } from "@/features/portal/orders/order-timeline";
import { PortalPaymentBadge } from "@/features/portal/orders/payment-badge";
import { useI18n, useT } from "@/i18n";
import { friendlyErrorMessage } from "@/lib/errors";
import { formatCurrency, formatDateTime, formatPhone, formatVariant } from "@/lib/format";
import { queryKeys } from "@/lib/query-keys";
import { getPortalOrder } from "@/services/portal";
import { isApiError } from "@/services/http";

/** How often an order that is still moving asks again. A finished one stops: nothing will change. */
const REFRESH_MS = 15_000;
const FINAL = ["delivered", "delivery_failed", "cancelled"];

/**
 * One order: where it is, who has it, what is owed on it, and everything that has happened to it.
 *
 * The timeline answers the question a store actually asks a support desk - "what happened to my
 * order?" - without anyone having to look it up. A failed or cancelled order puts its reason at
 * the top, because that is the first thing the store needs to act on.
 */
export default function PortalOrderDetailPage() {
  const t = useT();
  const { locale, dir } = useI18n();
  const params = useParams<{ uuid: string }>();
  const uuid = params.uuid;
  const Back = dir === "rtl" ? ArrowRight : ArrowLeft;

  const { data, isLoading, isError, error, refetch } = useQuery({
    queryKey: queryKeys.portal.order(uuid),
    queryFn: async () => (await getPortalOrder(uuid)).Model,
    refetchInterval: (query) => (query.state.data && FINAL.includes(query.state.data.status) ? false : REFRESH_MS),
    // Said rather than left to the library's default: a hidden tab does not poll, and a finished order stops polling altogether (above).
    refetchIntervalInBackground: false,
    // A 404 will not become a 200 by asking again; anything else deserves another try.
    retry: (count, failure) => !(isApiError(failure) && failure.status === 404) && count < 2,
  });

  const back = (
    <Link href="/portal/orders" className="mb-2 inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-primary">
      <Back className="h-3 w-3" aria-hidden />
      {t("portal.orders.back")}
    </Link>
  );

  if (isLoading) {
    return (
      <div>
        {back}
        <Skeleton className="mb-6 h-8 w-64" />
        <div className="grid gap-4 lg:grid-cols-3">
          <Skeleton className="h-56 lg:col-span-2" />
          <Skeleton className="h-56" />
        </div>
      </div>
    );
  }

  if (isError && isApiError(error) && error.status === 404) {
    return (
      <div>
        {back}
        <Card>
          <EmptyState title={t("portal.orders.notFound")} description={t("portal.orders.notFoundHint")} icon={Package} />
        </Card>
      </div>
    );
  }

  if (isError || !data) {
    return (
      <div>
        {back}
        <Card>
          <ErrorState message={friendlyErrorMessage(error, t)} onRetry={() => void refetch()} />
        </Card>
      </div>
    );
  }

  const order = data;
  const prepaid = order.cash?.method === "prepaid";
  /*
   * Keyed on the reason columns, not the live status: a failed or cancelled order carries straight
   * on to `awaiting_return` and then `returned` the moment its goods-return tracking starts, so by
   * the time anyone reads it `order.status` is neither `delivery_failed` nor `cancelled` any more —
   * while `failure_reason`/`cancel_reason` are written once and never cleared. Checking the status
   * made this box vanish from under a store the moment the office started chasing the parcel back,
   * which is exactly the order a store most wants an explanation still showing on.
   */
  const problem = order.failure_reason
    ? { label: t("portal.orders.detail.failure"), text: order.failure_reason }
    : order.cancel_reason
      ? { label: t("portal.orders.detail.cancel"), text: order.cancel_reason }
      : null;

  return (
    <div>
      <PageHeader
        breadcrumbs={back}
        title={
          <span className="flex flex-wrap items-center gap-3">
            <span dir="ltr">{order.order_number}</span>
            <OrderStatusBadge status={order.status} label={order.status_label} />
          </span>
        }
        subtitle={order.external_order_id ? `${t("portal.orders.detail.reference")}: ${order.external_order_id}` : undefined}
      />

      {problem ? (
        <div
          role="alert"
          className={
            // Matches which branch of `problem` actually fired, not the live status — see the comment above it.
            order.failure_reason
              ? "mb-6 flex items-start gap-3 rounded-lg border border-destructive/30 bg-destructive/5 p-4 text-sm text-destructive"
              : "mb-6 flex items-start gap-3 rounded-lg border bg-muted/40 p-4 text-sm text-foreground"
          }
        >
          <AlertTriangle className="mt-0.5 h-4 w-4 shrink-0" aria-hidden />
          <div className="min-w-0">
            <p className="font-medium">{problem.label}</p>
            <p className="text-muted-foreground">{problem.text}</p>
          </div>
        </div>
      ) : null}

      <div className="grid gap-4 lg:grid-cols-3">
        <div className="space-y-4 lg:col-span-2">
          <Card className="p-5 sm:p-6">
            <h2 className="mb-4 text-sm font-semibold text-foreground">{t("portal.orders.detail.summary")}</h2>
            <dl className="grid gap-4 sm:grid-cols-2">
              <Field label={t("portal.orders.detail.number")}>
                <span dir="ltr">{order.order_number}</span>
              </Field>
              <Field label={t("portal.orders.detail.reference")}>
                <span dir="ltr">{order.external_order_id ?? "—"}</span>
              </Field>
              <Field label={t("portal.orders.detail.received")}>{formatDateTime(order.timestamps?.received_at, locale)}</Field>
              <Field label={t("portal.orders.detail.eta")}>{formatDateTime(order.eta_at, locale)}</Field>
              <Field label={t("portal.orders.detail.promised")}>{formatDateTime(order.promised_at, locale)}</Field>
              {order.timestamps?.picked_up_at ? (
                <Field label={t("portal.orders.detail.pickedUp")}>{formatDateTime(order.timestamps?.picked_up_at, locale)}</Field>
              ) : null}
              {order.timestamps?.on_the_way_at ? (
                <Field label={t("portal.orders.detail.onTheWay")}>{formatDateTime(order.timestamps?.on_the_way_at, locale)}</Field>
              ) : null}
              {order.timestamps?.delivered_at ? (
                <Field label={t("portal.orders.detail.delivered")}>{formatDateTime(order.timestamps?.delivered_at, locale)}</Field>
              ) : null}
            </dl>
          </Card>

          <Card className="p-5 sm:p-6">
            <h2 className="mb-4 text-sm font-semibold text-foreground">{t("portal.orders.detail.itemsTitle")}</h2>
            {Array.isArray(order.items) && order.items.length > 0 ? (
              <div className="overflow-x-auto">
                <table className="w-full text-sm">
                  <thead>
                    <tr className="border-b border-border text-xs text-muted-foreground">
                      <th className="py-2 text-start font-medium">{t("portal.orders.detail.product")}</th>
                      <th className="px-2 py-2 text-end font-medium">{t("portal.orders.detail.qty")}</th>
                      <th className="px-2 py-2 text-end font-medium">{t("portal.orders.detail.unitPrice")}</th>
                      <th className="py-2 text-end font-medium">{t("portal.orders.detail.lineTotal")}</th>
                    </tr>
                  </thead>
                  <tbody>
                    {order.items.map((item, index) => (
                      <tr key={index} className="border-b border-border/60 last:border-0">
                        <td className="py-2 text-foreground">
                          {item.name}
                          {formatVariant(item.variant) ? <span className="ms-1 text-xs text-muted-foreground">({formatVariant(item.variant)})</span> : null}
                        </td>
                        <td className="numeric px-2 py-2 text-end">{item.quantity}</td>
                        <td className="numeric px-2 py-2 text-end">{formatCurrency(item.unit_price, order.totals?.currency ?? order.cash?.currency, locale)}</td>
                        <td className="numeric py-2 text-end">{formatCurrency(item.line_total, order.totals?.currency ?? order.cash?.currency, locale)}</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            ) : (
              <p className="text-sm text-muted-foreground">{t("portal.orders.detail.noItems")}</p>
            )}
            {order.totals ? (
              <dl className="mt-4 space-y-2 border-t border-border pt-4 text-sm">
                <div className="flex items-center justify-between">
                  <dt className="text-muted-foreground">{t("portal.orders.detail.productsTotal")}</dt>
                  <dd className="numeric">{formatCurrency(order.totals.products_total, order.totals.currency, locale)}</dd>
                </div>
                <div className="flex items-center justify-between">
                  <dt className="text-muted-foreground">
                    {t("portal.orders.detail.deliveryFee")}
                    {order.totals.fee_bearer === "store" || order.totals.fee_bearer === "shared" ? (
                      <span className="ms-2 rounded bg-warning/10 px-1.5 py-0.5 text-xs font-medium text-warning">
                        {t("portal.orders.detail.feeOnYou")}
                      </span>
                    ) : null}
                  </dt>
                  <dd className="numeric">{formatCurrency(order.totals.delivery_fee, order.totals.currency, locale)}</dd>
                </div>
                <div className="flex items-center justify-between border-t border-border pt-2 text-base font-semibold">
                  <dt>{t("portal.orders.detail.orderTotal")}</dt>
                  <dd className="numeric">
                    {formatCurrency(order.totals.calculated_total ?? order.totals.total, order.totals.currency, locale)}
                  </dd>
                </div>
                {order.totals.total != null ? (
                  <div className="flex items-center justify-between text-muted-foreground">
                    <dt>{t("portal.orders.detail.customerPays")}</dt>
                    <dd className="numeric">{formatCurrency(order.totals.total, order.totals.currency, locale)}</dd>
                  </div>
                ) : null}
                {order.totals.fee_bearer_reason ? (
                  <p className="text-xs font-medium text-foreground">
                    {t(`portal.orders.detail.feeReason.${order.totals.fee_bearer_reason}`)}
                  </p>
                ) : null}
                {order.totals.mismatch != null &&
                Number(order.totals.mismatch) !== 0 &&
                (!order.totals.fee_bearer || order.totals.fee_bearer === "customer") ? (
                  <p className="text-xs text-warning">
                    {t("portal.orders.detail.mismatch", {
                      amount: formatCurrency(Math.abs(Number(order.totals.mismatch)), order.totals.currency, locale),
                    })}
                  </p>
                ) : null}
              </dl>
            ) : null}
          </Card>

          <Card className="p-5 sm:p-6">
            <h2 className="mb-4 text-sm font-semibold text-foreground">{t("portal.orders.detail.cash")}</h2>
            <dl className="grid gap-4 sm:grid-cols-3">
              <Field label={t("portal.orders.detail.method")}>{t(`portal.orders.method.${order.cash?.method}`)}</Field>
              <Field label={t("portal.orders.detail.paymentStatus")}>
                <PortalPaymentBadge
                  status={order.cash?.status ?? null}
                  label={order.cash?.status ? t(`portal.orders.payment.${order.cash?.status}`) : ""}
                />
              </Field>
              <Field label={t("portal.orders.detail.toCollect")}>
                {prepaid ? (
                  <span className="text-muted-foreground">{t("portal.orders.nothingToCollect")}</span>
                ) : (
                  <span className="numeric text-base font-semibold">
                    {formatCurrency(order.cash?.amount_to_collect, order.cash?.currency, locale)}
                  </span>
                )}
              </Field>
            </dl>
          </Card>
        </div>

        <div className="space-y-6">
          <Card className="p-5 sm:p-6">
            <h2 className="mb-4 text-sm font-semibold text-foreground">{t("portal.orders.detail.captain")}</h2>
            {order.captain?.name ? (
              <div>
                <p className="text-sm font-medium text-foreground">{order.captain.name}</p>
                {order.captain.phone ? (
                  <a href={`tel:${order.captain.phone}`} dir="ltr" className="numeric mt-1 inline-block text-sm text-primary hover:underline">
                    {formatPhone(order.captain.phone)}
                  </a>
                ) : null}
              </div>
            ) : (
              <p className="text-sm text-muted-foreground">{t("portal.orders.detail.captainNone")}</p>
            )}
          </Card>

          <Card className="p-5 sm:p-6">
            <h2 className="mb-4 text-sm font-semibold text-foreground">{t("portal.orders.detail.timeline")}</h2>
            <OrderTimeline steps={Array.isArray(order.timeline) ? order.timeline : []} locale={locale} emptyText={t("portal.orders.detail.timelineEmpty")} />
          </Card>
        </div>
      </div>
    </div>
  );
}

function Field({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <div className="min-w-0">
      <dt className="text-[0.7rem] text-muted-foreground">{label}</dt>
      <dd className="numeric mt-0.5 text-sm text-foreground">{children}</dd>
    </div>
  );
}
