"use client";
import { jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import { useRouter } from "next/navigation";
import { Page, PageBody } from "@open-mercato/ui/backend/Page";
import { DataTable } from "@open-mercato/ui/backend/DataTable";
import { BooleanIcon } from "@open-mercato/ui/backend/ValueIcons";
import { RowActions } from "@open-mercato/ui/backend/RowActions";
import { flash } from "@open-mercato/ui/backend/FlashMessages";
import { readApiResultOrThrow, withScopedApiRequestHeaders } from "@open-mercato/ui/backend/utils/apiCall";
import { buildOptimisticLockHeader } from "@open-mercato/ui/backend/utils/optimisticLock";
import { surfaceRecordConflict } from "@open-mercato/ui/backend/conflicts";
import { deleteCrud } from "@open-mercato/ui/backend/utils/crud";
import { useGuardedMutation } from "@open-mercato/ui/backend/injection/useGuardedMutation";
import { useOrganizationScopeVersion } from "@open-mercato/shared/lib/frontend/useOrganizationScope";
import { useT } from "@open-mercato/shared/lib/i18n/context";
import { mapOfferRow, renderOfferPriceSummary } from "@open-mercato/core/modules/sales/components/channels/offerTableUtils";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("sales");
const PAGE_SIZE = 25;
const SAVE_CONTEXT_ID = "sales-channel-offers-list";
function SalesChannelOffersListPage() {
  const t = useT();
  const router = useRouter();
  const { runMutation, retryLastMutation } = useGuardedMutation({
    contextId: SAVE_CONTEXT_ID,
    blockedMessage: t("ui.forms.flash.saveBlocked", "Save blocked by validation")
  });
  const mutationContext = React.useMemo(
    () => ({
      formId: SAVE_CONTEXT_ID,
      resourceKind: "sales.channels.offers",
      retryLastMutation
    }),
    [retryLastMutation]
  );
  const scopeVersion = useOrganizationScopeVersion();
  const channelOptionsRef = React.useRef(/* @__PURE__ */ new Map());
  const [rows, setRows] = React.useState([]);
  const [page, setPage] = React.useState(1);
  const [total, setTotal] = React.useState(0);
  const [totalPages, setTotalPages] = React.useState(1);
  const [sorting, setSorting] = React.useState([{ id: "updatedAt", desc: true }]);
  const [search, setSearch] = React.useState("");
  const [filterValues, setFilterValues] = React.useState({});
  const [isLoading, setLoading] = React.useState(true);
  const [reloadToken, setReloadToken] = React.useState(0);
  const [channelOptions, setChannelOptions] = React.useState(channelOptionsRef.current);
  const selectedChannelIds = React.useMemo(() => {
    if (!Array.isArray(filterValues.channelIds)) return [];
    return filterValues.channelIds.map((value) => typeof value === "string" ? value.trim() : "").filter((value) => value.length > 0);
  }, [filterValues]);
  const upsertChannelOptions = React.useCallback((options) => {
    if (!options.length) return;
    setChannelOptions((prev) => {
      const next = new Map(prev);
      options.forEach((option) => {
        if (!option.value) return;
        next.set(option.value, option);
      });
      channelOptionsRef.current = next;
      return next;
    });
  }, []);
  const loadChannelOptions = React.useCallback(async (term) => {
    try {
      const params = new URLSearchParams({ pageSize: "100", isActive: "true" });
      if (term && term.trim().length) params.set("search", term.trim());
      const payload = await readApiResultOrThrow(
        `/api/sales/channels?${params.toString()}`,
        void 0,
        { errorMessage: t("sales.channels.offers.filters.channelsLoadError", "Failed to load channels") }
      );
      const items = Array.isArray(payload?.items) ? payload.items : [];
      const options = items.map((entry) => {
        const value = typeof entry.id === "string" ? entry.id : null;
        if (!value) return null;
        const label = typeof entry.name === "string" ? entry.name : typeof entry.code === "string" ? entry.code : value;
        const description = typeof entry.code === "string" && entry.code !== label ? entry.code : typeof entry.description === "string" && entry.description.trim().length ? entry.description : null;
        return { value, label, description };
      }).filter((option) => !!option);
      upsertChannelOptions(options);
      return options;
    } catch (err) {
      logger.warn("sales.channels.offers failed to load channel options", { err });
      return [];
    }
  }, [t, upsertChannelOptions]);
  const ensureChannelMetadata = React.useCallback(async (ids) => {
    const missing = ids.filter((id) => !channelOptionsRef.current.has(id));
    if (!missing.length) return;
    try {
      const params = new URLSearchParams({
        ids: missing.join(","),
        pageSize: String(Math.min(Math.max(missing.length, 1), 100))
      });
      const payload = await readApiResultOrThrow(
        `/api/sales/channels?${params.toString()}`,
        void 0,
        { errorMessage: t("sales.channels.offers.filters.channelsLoadError", "Failed to load channels") }
      );
      const items = Array.isArray(payload?.items) ? payload.items : [];
      const options = items.map((entry) => {
        const value = typeof entry.id === "string" ? entry.id : null;
        if (!value) return null;
        const label = typeof entry.name === "string" ? entry.name : typeof entry.code === "string" ? entry.code : value;
        const description = typeof entry.code === "string" && entry.code !== label ? entry.code : typeof entry.description === "string" && entry.description.trim().length ? entry.description : null;
        return { value, label, description };
      }).filter((option) => !!option);
      upsertChannelOptions(options);
    } catch (err) {
      logger.warn("sales.channels.offers failed to hydrate channel metadata", { err });
    }
  }, [t, upsertChannelOptions]);
  const columns = React.useMemo(() => [
    {
      accessorKey: "title",
      header: t("sales.channels.offers.table.offer", "Offer"),
      cell: ({ row }) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
        row.original.productMediaUrl ? /* @__PURE__ */ jsx(
          "img",
          {
            src: row.original.productMediaUrl,
            alt: row.original.productTitle ?? row.original.title,
            className: "h-12 w-12 rounded border object-cover"
          }
        ) : /* @__PURE__ */ jsx("div", { className: "h-12 w-12 rounded border bg-muted" }),
        /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
          /* @__PURE__ */ jsx("span", { className: "font-medium", children: row.original.title }),
          /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: row.original.productTitle ?? t("sales.channels.offers.table.emptyProduct", "Unlinked product") })
        ] }) })
      ] }),
      meta: { sticky: true }
    },
    {
      accessorKey: "pricing",
      header: t("sales.channels.offers.table.pricing", "Prices"),
      cell: ({ row }) => /* @__PURE__ */ jsx("div", { className: "text-sm", children: renderOfferPriceSummary(row.original, t) })
    },
    {
      accessorKey: "channelId",
      header: t("sales.channels.offers.table.channel", "Channel"),
      cell: ({ row }) => {
        const channelId = row.original.channelId;
        if (!channelId) {
          return /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: t("sales.channels.offers.table.channelUnassigned", "Unassigned") });
        }
        const label = channelOptions.get(channelId)?.label ?? channelId;
        const description = channelOptions.get(channelId)?.description ?? null;
        return /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
          /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: label }),
          description ? /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: description }) : null
        ] });
      }
    },
    {
      accessorKey: "isActive",
      header: t("sales.channels.offers.table.active", "Active"),
      cell: ({ row }) => /* @__PURE__ */ jsx(BooleanIcon, { value: row.original.isActive })
    },
    {
      accessorKey: "updatedAt",
      header: t("sales.channels.offers.table.updated", "Updated"),
      cell: ({ row }) => row.original.updatedAt ? /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: new Date(row.original.updatedAt).toLocaleDateString() }) : /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "\u2014" })
    }
  ], [channelOptions, t]);
  const filters = React.useMemo(() => [
    {
      id: "channelIds",
      label: t("sales.channels.offers.filters.channels", "Sales channels"),
      type: "tags",
      placeholder: t("sales.channels.offers.filters.channelsPlaceholder", "Filter by channels\u2026"),
      loadOptions: loadChannelOptions,
      formatValue: (value) => channelOptions.get(value)?.label ?? value,
      formatDescription: (value) => channelOptions.get(value)?.description ?? null
    }
  ], [channelOptions, loadChannelOptions, t]);
  const loadOffers = React.useCallback(async () => {
    setLoading(true);
    try {
      const params = new URLSearchParams({
        page: String(page),
        pageSize: String(PAGE_SIZE)
      });
      if (search.trim().length) {
        params.set("search", search.trim());
      }
      const sort = sorting[0];
      if (sort?.id) {
        params.set("sortField", sort.id);
        params.set("sortDir", sort.desc ? "desc" : "asc");
      }
      if (selectedChannelIds.length) {
        params.set("channelIds", selectedChannelIds.join(","));
      }
      const payload = await readApiResultOrThrow(
        `/api/catalog/offers?${params.toString()}`,
        void 0,
        { errorMessage: t("sales.channels.offers.errors.load", "Failed to load offers.") }
      );
      const items = Array.isArray(payload.items) ? payload.items : [];
      const mapped = items.map(mapOfferRow);
      setRows(mapped);
      setTotal(typeof payload.total === "number" ? payload.total : items.length);
      setTotalPages(typeof payload.totalPages === "number" ? payload.totalPages : Math.max(1, Math.ceil(items.length / PAGE_SIZE)));
      const ids = mapped.map((row) => row.channelId).filter((value) => typeof value === "string" && value.length > 0);
      if (ids.length) void ensureChannelMetadata(Array.from(new Set(ids)));
    } catch (err) {
      logger.error("sales.channels.offers.list", { err });
      flash(t("sales.channels.offers.errors.load", "Failed to load offers."), "error");
    } finally {
      setLoading(false);
    }
  }, [ensureChannelMetadata, page, search, selectedChannelIds, sorting, t]);
  React.useEffect(() => {
    void loadOffers();
  }, [loadOffers, scopeVersion, reloadToken]);
  const handleSearchChange = React.useCallback((value) => {
    setSearch(value);
    setPage(1);
  }, []);
  const handleFiltersApply = React.useCallback((values) => {
    setFilterValues(values);
    setPage(1);
  }, []);
  const handleFiltersClear = React.useCallback(() => {
    setFilterValues({});
    setPage(1);
  }, []);
  const handleRefresh = React.useCallback(() => {
    setReloadToken((token) => token + 1);
  }, []);
  const handleDelete = React.useCallback(async (row) => {
    try {
      await runMutation({
        operation: () => withScopedApiRequestHeaders(
          buildOptimisticLockHeader(row.updatedAt),
          () => deleteCrud("catalog/offers", row.id, {
            errorMessage: t("sales.channels.offers.errors.delete", "Failed to delete offer.")
          })
        ),
        context: mutationContext,
        mutationPayload: { action: "delete", id: row.id }
      });
      flash(t("sales.channels.offers.messages.deleted", "Offer deleted."), "success");
      handleRefresh();
    } catch (err) {
      if (surfaceRecordConflict(err, t)) {
        handleRefresh();
        return;
      }
      logger.error("sales.channels.offers.delete", { err });
    }
  }, [handleRefresh, mutationContext, runMutation, t]);
  const tableTitle = /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
    /* @__PURE__ */ jsx("span", { children: t("sales.channels.offers.listTitle", "Sales channel offers") }),
    /* @__PURE__ */ jsx("span", { className: "text-sm font-normal text-muted-foreground", children: t("sales.channels.offers.listSubtitle", "Review product overrides across every sales channel.") })
  ] });
  return /* @__PURE__ */ jsx(Page, { children: /* @__PURE__ */ jsx(PageBody, { children: /* @__PURE__ */ jsx(
    DataTable,
    {
      title: tableTitle,
      columns,
      data: rows,
      isLoading,
      sorting,
      onSortingChange: setSorting,
      searchValue: search,
      onSearchChange: handleSearchChange,
      searchPlaceholder: t("sales.channels.offers.table.search", "Search offers\u2026"),
      filters,
      filterValues,
      onFiltersApply: handleFiltersApply,
      onFiltersClear: handleFiltersClear,
      pagination: {
        page,
        pageSize: PAGE_SIZE,
        total,
        totalPages,
        onPageChange: setPage
      },
      refreshButton: {
        label: t("sales.channels.offers.table.refresh", "Refresh"),
        onRefresh: handleRefresh,
        isRefreshing: isLoading
      },
      rowActions: (row) => {
        if (!row.channelId) return null;
        return /* @__PURE__ */ jsx(
          RowActions,
          {
            items: [
              {
                id: "edit",
                label: t("sales.channels.offers.actions.edit", "Edit"),
                href: `/backend/sales/channels/${row.channelId}/offers/${row.id}/edit`
              },
              {
                id: "delete",
                label: t("sales.channels.offers.actions.delete", "Delete"),
                onSelect: () => handleDelete(row),
                destructive: true
              }
            ]
          }
        );
      },
      onRowClick: (row) => {
        if (!row.channelId) return;
        router.push(`/backend/sales/channels/${row.channelId}/offers/${row.id}/edit`);
      },
      emptyState: /* @__PURE__ */ jsx("div", { className: "py-10 text-center text-sm text-muted-foreground", children: t("sales.channels.offers.table.emptyAll", "No offers available yet.") })
    }
  ) }) });
}
export {
  SalesChannelOffersListPage as default
};
//# sourceMappingURL=page.js.map
