"use client";
import { jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import { DataTable } from "@open-mercato/ui/backend/DataTable";
import { LoadingMessage, ErrorMessage, TabEmptyState } from "@open-mercato/ui/backend/detail";
import { apiCall, withScopedApiRequestHeaders } from "@open-mercato/ui/backend/utils/apiCall";
import { buildOptimisticLockHeader } from "@open-mercato/ui/backend/utils/optimisticLock";
import { deleteCrud } from "@open-mercato/ui/backend/utils/crud";
import { handleSectionMutationError, readRowUpdatedAt } from "./optimisticLock.js";
import { RowActions } from "@open-mercato/ui/backend/RowActions";
import { Button } from "@open-mercato/ui/primitives/button";
import { flash } from "@open-mercato/ui/backend/FlashMessages";
import { useOrganizationScopeDetail } from "@open-mercato/shared/lib/frontend/useOrganizationScope";
import { useT } from "@open-mercato/shared/lib/i18n/context";
import { emitSalesDocumentTotalsRefresh } from "@open-mercato/core/modules/sales/lib/frontend/documentTotalsEvents";
import { PaymentDialog } from "./PaymentDialog.js";
import { extractCustomFieldValues } from "./customFieldHelpers.js";
import { Plus } from "lucide-react";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("sales");
function normalizeNumber(value) {
  if (typeof value === "number" && Number.isFinite(value)) return value;
  if (typeof value === "string" && value.trim().length) {
    const parsed = Number(value);
    if (!Number.isNaN(parsed)) return parsed;
  }
  return 0;
}
function formatMoney(value, currency) {
  if (!currency || currency.trim().length !== 3) return value.toFixed(2);
  try {
    return new Intl.NumberFormat(void 0, { style: "currency", currency }).format(value);
  } catch {
    return `${currency.toUpperCase()} ${value.toFixed(2)}`;
  }
}
function SalesDocumentPaymentsSection({
  orderId,
  currencyCode,
  organizationId: orgFromProps,
  tenantId: tenantFromProps,
  documentUpdatedAt,
  onActionChange,
  onTotalsChange,
  onPaymentsChange
}) {
  const t = useT();
  const { organizationId, tenantId } = useOrganizationScopeDetail();
  const resolvedOrganizationId = orgFromProps ?? organizationId ?? null;
  const resolvedTenantId = tenantFromProps ?? tenantId ?? null;
  const [payments, setPayments] = React.useState([]);
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState(null);
  const [dialogOpen, setDialogOpen] = React.useState(false);
  const [editingPayment, setEditingPayment] = React.useState(null);
  const onPaymentsChangeRef = React.useRef(onPaymentsChange);
  React.useEffect(() => {
    onPaymentsChangeRef.current = onPaymentsChange;
  }, [onPaymentsChange]);
  const addActionLabel = t("sales.documents.payments.add", "Add payment");
  const editActionLabel = t("sales.documents.payments.edit", "Edit payment");
  const deleteActionLabel = t("sales.documents.payments.delete", "Delete payment");
  const loadPayments = React.useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const params = new URLSearchParams({ page: "1", pageSize: "100", orderId });
      const response = await apiCall(
        `/api/sales/payments?${params.toString()}`,
        void 0,
        { fallback: { items: [] } }
      );
      if (response.ok && Array.isArray(response.result?.items)) {
        const mapped = response.result.items.flatMap((item) => {
          if (typeof item.id !== "string") return [];
          const customValues = item && typeof item === "object" ? extractCustomFieldValues(item) : {};
          const record = {
            id: item.id,
            updatedAt: readRowUpdatedAt(item),
            paymentReference: typeof item.payment_reference === "string" ? item.payment_reference : null,
            paymentMethodId: typeof item.payment_method_id === "string" ? item.payment_method_id : null,
            paymentMethodName: typeof item.payment_method_name === "string" ? item.payment_method_name : typeof item.payment_method_code === "string" ? item.payment_method_code : null,
            status: typeof item.status === "string" ? item.status : null,
            statusEntryId: typeof item.status_entry_id === "string" ? item.status_entry_id : typeof item.statusEntryId === "string" ? item.statusEntryId : null,
            statusLabel: typeof item.status_label === "string" ? item.status_label : typeof item.statusLabel === "string" ? item.statusLabel : null,
            amount: normalizeNumber(item.amount),
            currencyCode: typeof item.currency_code === "string" ? item.currency_code : typeof currencyCode === "string" ? currencyCode : null,
            receivedAt: typeof item.received_at === "string" ? item.received_at : null,
            createdAt: typeof item.created_at === "string" ? item.created_at : null,
            customValues: Object.keys(customValues).length ? customValues : null,
            customFieldSetId: typeof item?.custom_field_set_id === "string" ? item.custom_field_set_id : typeof item?.customFieldSetId === "string" ? item.customFieldSetId : null
          };
          return [record];
        });
        setPayments(mapped);
        onPaymentsChangeRef.current?.(mapped);
      } else {
        setPayments([]);
        onPaymentsChangeRef.current?.([]);
      }
    } catch (err) {
      logger.error("sales.payments.list", { err });
      setError(t("sales.documents.payments.errorLoad", "Failed to load payments."));
      onPaymentsChangeRef.current?.([]);
    } finally {
      setLoading(false);
    }
  }, [currencyCode, orderId, t]);
  React.useEffect(() => {
    void loadPayments();
  }, [loadPayments]);
  const openCreate = React.useCallback(() => {
    setEditingPayment(null);
    setDialogOpen(true);
  }, []);
  const handleDialogChange = React.useCallback((nextOpen) => {
    setDialogOpen(nextOpen);
    if (!nextOpen) {
      setEditingPayment(null);
    }
  }, []);
  const openEditPayment = React.useCallback(
    (record) => {
      setEditingPayment({
        id: record.id,
        updatedAt: record.updatedAt ?? null,
        amount: record.amount ?? "",
        paymentMethodId: record.paymentMethodId ?? "",
        paymentReference: record.paymentReference ?? "",
        receivedAt: record.receivedAt ? record.receivedAt.slice(0, 10) : "",
        currencyCode: record.currencyCode ?? currencyCode ?? null,
        statusEntryId: record.statusEntryId ?? null,
        customValues: record.customValues ?? null,
        customFieldSetId: record.customFieldSetId ?? null
      });
      setDialogOpen(true);
    },
    [currencyCode]
  );
  const handlePaymentSaved = React.useCallback(
    async (_totals) => {
      onTotalsChange?.();
      await loadPayments();
      emitSalesDocumentTotalsRefresh({ documentId: orderId, kind: "order" });
      handleDialogChange(false);
    },
    [handleDialogChange, loadPayments, onTotalsChange, orderId]
  );
  const handleDelete = React.useCallback(
    async (row) => {
      try {
        const result = await withScopedApiRequestHeaders(
          // The server guards the PARENT order's aggregate version (Gap A), so
          // send the order's `updated_at`, not the payment row's.
          buildOptimisticLockHeader(documentUpdatedAt ?? void 0),
          () => deleteCrud("sales/payments", {
            body: {
              id: row.id,
              orderId,
              organizationId: resolvedOrganizationId ?? void 0,
              tenantId: resolvedTenantId ?? void 0
            },
            errorMessage: t("sales.documents.payments.errorDelete", "Failed to delete payment.")
          })
        );
        if (result.ok) {
          onTotalsChange?.();
          flash(t("sales.documents.payments.deleted", "Payment deleted."), "success");
          await loadPayments();
          emitSalesDocumentTotalsRefresh({ documentId: orderId, kind: "order" });
        }
      } catch (err) {
        if (handleSectionMutationError(err, t, () => void loadPayments())) {
          return;
        }
        logger.error("sales.payments.delete", { err });
        flash(t("sales.documents.payments.errorDelete", "Failed to delete payment."), "error");
      }
    },
    [documentUpdatedAt, loadPayments, onTotalsChange, orderId, resolvedOrganizationId, resolvedTenantId, t]
  );
  React.useEffect(() => {
    if (!onActionChange) return;
    onActionChange({
      label: addActionLabel,
      onClick: openCreate,
      disabled: false
    });
    return () => onActionChange(null);
  }, [addActionLabel, onActionChange, openCreate]);
  const columns = React.useMemo(
    () => [
      {
        accessorKey: "paymentReference",
        header: t("sales.documents.payments.reference", "Reference"),
        cell: ({ row }) => row.original.paymentReference || "\u2014"
      },
      {
        accessorKey: "paymentMethodName",
        header: t("sales.documents.payments.method", "Method"),
        cell: ({ row }) => row.original.paymentMethodName ?? "\u2014"
      },
      {
        accessorKey: "status",
        header: t("sales.documents.payments.status", "Status"),
        cell: ({ row }) => row.original.statusLabel ?? row.original.status ?? "\u2014"
      },
      {
        accessorKey: "amount",
        header: t("sales.documents.payments.amount", "Amount"),
        cell: ({ row }) => formatMoney(row.original.amount, row.original.currencyCode ?? currencyCode)
      },
      {
        accessorKey: "receivedAt",
        header: t("sales.documents.payments.receivedAt", "Received"),
        cell: ({ row }) => row.original.receivedAt ? new Date(row.original.receivedAt).toLocaleDateString() : "\u2014"
      },
      {
        accessorKey: "createdAt",
        header: t("sales.documents.payments.createdAt", "Created"),
        cell: ({ row }) => row.original.createdAt ? new Date(row.original.createdAt).toLocaleString() : "\u2014",
        meta: {
          tooltipContent: (row) => row.createdAt ? new Date(row.createdAt).toLocaleString() : void 0
        }
      },
      {
        id: "actions",
        header: "",
        cell: ({ row }) => {
          return /* @__PURE__ */ jsx(
            RowActions,
            {
              items: [
                { id: "edit", label: editActionLabel, onSelect: () => openEditPayment(row.original) },
                {
                  id: "delete",
                  label: deleteActionLabel,
                  destructive: true,
                  onSelect: () => void handleDelete(row.original)
                }
              ]
            }
          );
        }
      }
    ],
    [currencyCode, deleteActionLabel, editActionLabel, handleDelete, openEditPayment, t]
  );
  if (loading) {
    return /* @__PURE__ */ jsx(
      LoadingMessage,
      {
        label: t("sales.documents.payments.loading", "Loading payments\u2026"),
        className: "border-0 bg-transparent p-0 py-8 justify-center"
      }
    );
  }
  if (error) {
    return /* @__PURE__ */ jsx(
      ErrorMessage,
      {
        label: error,
        action: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: () => void loadPayments(), children: t("sales.documents.payments.retry", "Retry") })
      }
    );
  }
  return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
    payments.length ? /* @__PURE__ */ jsx(DataTable, { columns, data: payments, onRowClick: openEditPayment }) : /* @__PURE__ */ jsx(
      TabEmptyState,
      {
        title: t("sales.documents.payments.emptyTitle", "No payments yet."),
        description: t(
          "sales.documents.payments.emptyDescription",
          "Track received payments to keep outstanding balances up to date."
        ),
        action: {
          label: addActionLabel,
          onClick: openCreate,
          icon: /* @__PURE__ */ jsx(Plus, { className: "h-4 w-4", "aria-hidden": true }),
          disabled: loading
        }
      }
    ),
    /* @__PURE__ */ jsx(
      PaymentDialog,
      {
        open: dialogOpen,
        onOpenChange: handleDialogChange,
        mode: editingPayment ? "edit" : "create",
        payment: editingPayment,
        currencyCode: editingPayment?.currencyCode ?? currencyCode,
        orderId,
        organizationId: resolvedOrganizationId,
        tenantId: resolvedTenantId,
        documentUpdatedAt: documentUpdatedAt ?? null,
        onSaved: handlePaymentSaved
      }
    )
  ] });
}
export {
  SalesDocumentPaymentsSection
};
//# sourceMappingURL=PaymentsSection.js.map
