"use client";

import { Banknote, HandCoins, TriangleAlert } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { useI18n, useT } from "@/i18n";
import { formatCurrency, formatDateTime } from "@/lib/format";
import type { Order } from "@/types/order";

/**
 * The money on one order: what it cost, what it yielded, and every movement behind those figures.
 *
 * **Expected and actual are shown side by side, never one in place of the other.** A captain pays
 * what the supplier asks and takes what the customer hands over, and neither has to match what the
 * order said — a short collection is a real event that somebody has to see, and replacing the
 * expected figure with the actual one hides exactly the case worth looking at.
 *
 * The rows name their captain because the captain who paid and the captain who collected need not
 * be the same person: after a handover, one captain is owed for the goods while another is holding
 * the customer's cash.
 */
export function OrderMoney({ order }: { order: Order }) {
  const t = useT();
  const { locale } = useI18n();

  const settlement = order.settlement ?? null;
  const currency = order.currency;

  // Read from the settlement block when the detail carried it, and from the order otherwise, so
  // the card still says what it knows on an order whose ledger was never loaded.
  const expected = settlement?.expected_goods_cost ?? null;
  const paid = settlement?.amount_paid ?? order.amount_paid ?? null;
  const toCollect = settlement?.amount_to_collect ?? order.amount_to_collect ?? null;
  const collected = settlement?.amount_collected ?? order.amount_collected ?? null;
  const entries = settlement?.entries ?? [];

  // Nothing to show at all: an order nobody has spent or taken money on, with no prices on it.
  if (expected === null && paid === null && toCollect === null && collected === null) {
    return null;
  }

  return (
    <Card className="mt-6">
      <CardHeader>
        <CardTitle className="flex items-center gap-2">
          <HandCoins className="h-4 w-4 text-primary" aria-hidden />
          {t("orders.money.title")}
        </CardTitle>
      </CardHeader>
      <CardContent className="space-y-6">
        <div className="grid gap-4 sm:grid-cols-2">
          <Figure
            label={t("orders.money.goods")}
            expectedLabel={t("orders.money.expected")}
            actualLabel={t("orders.money.paid")}
            expected={expected}
            actual={paid}
            currency={currency}
            locale={locale}
            hint={t("orders.money.goodsHint")}
          />
          <Figure
            label={t("orders.money.cash")}
            expectedLabel={t("orders.money.toCollect")}
            actualLabel={t("orders.money.collected")}
            expected={toCollect}
            actual={collected}
            currency={currency}
            locale={locale}
            hint={t("orders.money.cashHint")}
          />
        </div>

        <div>
          <p className="mb-2 text-sm font-medium text-foreground">
            {t("orders.money.movements")}
          </p>
          {entries.length === 0 ? (
            <p className="text-sm text-muted-foreground">{t("orders.money.noMovements")}</p>
          ) : (
            <div className="overflow-x-auto">
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>{t("orders.money.movement")}</TableHead>
                    <TableHead>{t("orders.captain")}</TableHead>
                    <TableHead>{t("ledger.amount")}</TableHead>
                    <TableHead>{t("orders.money.expected")}</TableHead>
                    <TableHead>{t("common.createdAt")}</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {entries.map((entry) => (
                    <TableRow key={entry.uuid}>
                      <TableCell className="text-sm font-medium text-foreground">
                        {entry.type_label}
                      </TableCell>
                      <TableCell className="text-sm">{entry.captain?.name ?? "—"}</TableCell>
                      <TableCell className="numeric text-sm">
                        {/* Signed from the captain's side: positive means the company owes them. */}
                        <span
                          className={
                            entry.amount < 0 ? "text-warning" : "font-medium text-foreground"
                          }
                        >
                          {formatCurrency(entry.amount, entry.currency, locale)}
                        </span>
                      </TableCell>
                      <TableCell className="numeric text-sm text-muted-foreground">
                        {entry.expected_amount === null
                          ? "—"
                          : formatCurrency(entry.expected_amount, entry.currency, locale)}
                        {entry.variance !== null && entry.variance !== 0 ? (
                          <Badge variant="warning" className="ms-2">
                            <TriangleAlert className="h-3 w-3" aria-hidden />
                            {formatCurrency(entry.variance, entry.currency, locale)}
                          </Badge>
                        ) : null}
                      </TableCell>
                      <TableCell className="text-xs text-muted-foreground">
                        {formatDateTime(entry.created_at, locale)}
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>
          )}
        </div>
      </CardContent>
    </Card>
  );
}

/**
 * One pair of figures — what was expected, and what happened — with the difference named when
 * there is one.
 */
function Figure({
  label,
  expectedLabel,
  actualLabel,
  expected,
  actual,
  currency,
  locale,
  hint,
}: {
  label: string;
  expectedLabel: string;
  actualLabel: string;
  expected: number | null;
  actual: number | null;
  currency: string | null;
  locale: "en" | "ar";
  hint: string;
}) {
  const t = useT();
  // A variance only exists when both halves are known: an order without prices expected nothing,
  // and an undelivered order has not yet produced an actual.
  const variance = expected !== null && actual !== null ? Math.round((actual - expected) * 100) / 100 : null;

  return (
    <div className="rounded-lg border p-4">
      <p className="flex items-center gap-2 text-xs font-medium uppercase tracking-wide text-muted-foreground">
        <Banknote className="h-3.5 w-3.5" aria-hidden />
        {label}
      </p>

      <div className="mt-3 flex flex-wrap items-baseline gap-x-6 gap-y-2">
        <span>
          <span className="block text-[0.7rem] text-muted-foreground">{expectedLabel}</span>
          <span className="numeric text-sm text-foreground">
            {expected === null ? "—" : formatCurrency(expected, currency, locale)}
          </span>
        </span>
        <span>
          <span className="block text-[0.7rem] text-muted-foreground">{actualLabel}</span>
          <span className="numeric text-lg font-semibold text-foreground">
            {actual === null ? "—" : formatCurrency(actual, currency, locale)}
          </span>
        </span>
        {variance !== null && variance !== 0 ? (
          <Badge variant="warning">
            <TriangleAlert className="h-3 w-3" aria-hidden />
            {t("orders.money.variance", {
              amount: formatCurrency(variance, currency, locale),
            })}
          </Badge>
        ) : null}
      </div>

      <p className="mt-2 text-xs text-muted-foreground">{hint}</p>
    </div>
  );
}
