import { lt as __exportAll } from "./translation-adapter-B-Vhfzbz.mjs";
import { i as useOptionalStore } from "./use-optional-store-DzThbXJh.mjs";
import { n as useDataSourceRegistryConfig } from "./registry-context-Rn7c5X_k.mjs";
import { r as useWidgetsApi, t as ErrorState } from "./error-state-CmesiiXJ.mjs";
import { i as getBorderColorField, l as getColorField, m as getPaddingField, n as borderWidthClasses, o as getBorderRadiusField, s as getBorderWidthField, t as borderColorClasses, u as getFontSizeField } from "./registries-BZVov8GL.mjs";
import { t as useWidgetPreviewContext } from "./preview-context-BeRbfntP.mjs";
import { useId, useMemo, useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { jsx, jsxs } from "react/jsx-runtime";
import { ChevronDown, Coins } from "lucide-react";
//#region ../core/src/format/title-case.ts
/**
* Turn a snake_case value into Title Case words, e.g. `order_redemption` ->
* `Order Redemption`. Only the first character of each word is upper-cased; the
* rest is left verbatim.
*
* Shared by the portal points-history surfaces (PointsWidget, ProfileLayout) so
* they render labels like points-ledger transaction types identically. The
* standalone apps (fluid-pay, fluid-checkout) and profile-ui intentionally keep
* their own transaction-type formatters — they live in separate translation
* domains and aren't consolidated here.
*/
function titleCaseFromSnake(value) {
	return value.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
}
//#endregion
//#region ../widgets/src/hooks/use-points-ledger.preview.ts
const now = /* @__PURE__ */ new Date();
function daysAgo(days) {
	return (/* @__PURE__ */ new Date(now.getTime() - days * 864e5)).toISOString();
}
const PREVIEW_DATA = {
	balance: 25,
	entries: [
		{
			id: 1,
			amount: 20,
			createdAt: daysAgo(3),
			transactionType: "new_order",
			hasSource: true
		},
		{
			id: 2,
			amount: 50,
			createdAt: daysAgo(14),
			transactionType: "referral_bonus",
			hasSource: true
		},
		{
			id: 3,
			amount: -75,
			createdAt: daysAgo(60),
			transactionType: null,
			hasSource: true
		},
		{
			id: 4,
			amount: 30,
			createdAt: daysAgo(90),
			transactionType: "welcome_reward",
			hasSource: true
		}
	]
};
//#endregion
//#region ../widgets/src/hooks/use-points-ledger.ts
const POINTS_LEDGER_QUERY_KEY = "points-ledger";
function usePointsLedger() {
	const widgetsApi = useWidgetsApi();
	const { isPreview } = useWidgetPreviewContext();
	const registryConfig = useDataSourceRegistryConfig();
	const { baseUrl } = registryConfig;
	const customerId = registryConfig.variables?.customer_id;
	return useQuery({
		queryKey: [
			"portal-widget-use",
			POINTS_LEDGER_QUERY_KEY,
			isPreview ? "preview" : baseUrl,
			customerId ?? null
		],
		queryFn: ({ signal }) => widgetsApi.fetchPointsLedger(customerId ?? "", signal),
		enabled: !isPreview,
		...isPreview && { placeholderData: PREVIEW_DATA }
	});
}
//#endregion
//#region ../react/src/hooks/use-points-label.ts
/**
* Platform defaults, mirroring the backend column defaults. Used whenever the
* store is unavailable (preview/builder) or a company hasn't overridden the
* label.
*/
const DEFAULT_POINTS_LABEL = {
	singular: "point",
	plural: "points"
};
/**
* Resolves the per-company reward-points label for use across portal surfaces
* (widgets, order details, etc.).
*
* Reads the store via `useOptionalStore()`, which is preview-safe: the widget
* palette / drag-preview mounts widgets without a StoreApiProvider, so the
* underlying query is disabled and we fall back to the platform defaults. The
* shared hook reuses `useStore()`'s cache key, so the result is deduped with
* the rest of the app's store cache.
*/
function usePointsLabel() {
	const { data } = useOptionalStore();
	const singular = data?.reward_points_label_singular?.trim() || DEFAULT_POINTS_LABEL.singular;
	const plural = data?.reward_points_label_plural?.trim() || DEFAULT_POINTS_LABEL.plural;
	return useMemo(() => ({
		singular,
		plural
	}), [singular, plural]);
}
//#endregion
//#region ../widgets/src/widgets/PointsWidget.tsx
var PointsWidget_exports = /* @__PURE__ */ __exportAll({
	PointsWidget: () => PointsWidget,
	pointsWidgetPropertySchema: () => pointsWidgetPropertySchema
});
const formatBalance = (balance) => {
	return balance.toLocaleString("en-US");
};
/** Capitalize the first letter for display in headings / sentence-leading copy. */
const capitalize = (value) => value.charAt(0).toUpperCase() + value.slice(1);
function formatTransactionType(entry, pluralLabel) {
	if (entry.transactionType) return titleCaseFromSnake(entry.transactionType);
	if (entry.hasSource) return entry.amount > 0 ? `${pluralLabel} Awarded` : `${pluralLabel} Redeemed`;
	return "Transaction";
}
function formatEntryDate(dateString) {
	if (!dateString) return "";
	return new Date(dateString).toLocaleDateString(void 0, {
		month: "short",
		day: "numeric",
		year: "numeric"
	});
}
function PointsEntryRow({ entry, isLast, textColor, accentColor, backgroundColor, pointsLabelPlural }) {
	const isPositive = entry.amount >= 0;
	const prefix = isPositive ? "+" : "";
	return /* @__PURE__ */ jsxs("div", {
		className: "flex flex-row items-stretch gap-3",
		children: [/* @__PURE__ */ jsxs("div", {
			className: "relative flex w-2 flex-col items-center",
			children: [!isLast && /* @__PURE__ */ jsx("div", { className: `bg-${textColor}/40 absolute top-3 -bottom-3 left-1/2 w-px -translate-x-1/2` }), /* @__PURE__ */ jsx("div", { className: `border-${textColor}/60 bg-${backgroundColor} relative mt-3 h-2 w-2 shrink-0 rounded-full border` })]
		}), /* @__PURE__ */ jsxs("div", {
			className: "flex flex-1 flex-row items-start justify-between py-1.5",
			children: [/* @__PURE__ */ jsxs("div", {
				className: "flex min-w-0 flex-col",
				children: [/* @__PURE__ */ jsx("div", {
					className: `text-sm font-medium text-${textColor} truncate`,
					children: formatTransactionType(entry, pointsLabelPlural)
				}), /* @__PURE__ */ jsx("div", {
					className: `text-sm text-${textColor} opacity-70`,
					children: formatEntryDate(entry.createdAt)
				})]
			}), /* @__PURE__ */ jsxs("div", {
				className: `text-sm font-medium ${isPositive ? `text-${accentColor}` : "text-destructive"}`,
				children: [prefix, entry.amount.toLocaleString("en-US")]
			})]
		})]
	});
}
function PointsWidget({ titleEnabled = true, title, titleFontSize = "md", titleColor = "foreground", balanceColor = "primary", historyEnabled = true, historyTitle = "History", background = {
	type: "solid",
	color: "background"
}, textColor = "foreground", accentColor = "primary", padding = 4, borderRadius = "md", borderWidth = "none", borderColor = "muted", className, ...props }) {
	const [historyOpen, setHistoryOpen] = useState(false);
	const historyPanelId = useId();
	const { plural } = usePointsLabel();
	const pointsLabelPlural = capitalize(plural);
	const backgroundColor = background.color || "background";
	const backgroundImage = (background.resource?.image_url || background.resource?.imageUrl) && background.type === "image" ? `url(${background.resource.image_url || background.resource.imageUrl})` : "none";
	const { data, isLoading, isError } = usePointsLedger();
	return /* @__PURE__ */ jsx("div", {
		className: `@container overflow-hidden rounded-${borderRadius} bg-${backgroundColor} ${borderWidthClasses[borderWidth]} ${borderWidth !== "none" ? borderColorClasses[borderColor] : ""} ${className ?? ""}`,
		style: { backgroundImage },
		...props,
		children: /* @__PURE__ */ jsxs("div", {
			className: `p-${padding} flex flex-col gap-2.5`,
			children: [
				titleEnabled && /* @__PURE__ */ jsx("h2", {
					className: `text-${titleFontSize} font-header font-bold text-${titleColor}`,
					children: title?.trim() ? title : pointsLabelPlural
				}),
				!isLoading && data && /* @__PURE__ */ jsx("span", {
					className: `text-3xl font-semibold text-${balanceColor} font-header leading-snug`,
					children: formatBalance(data.balance)
				}),
				isLoading ? /* @__PURE__ */ jsx("div", {
					className: "flex min-h-[60px] items-center justify-center",
					children: /* @__PURE__ */ jsx("div", { className: "h-8 w-8 animate-spin rounded-full border-2 border-current border-t-transparent" })
				}) : isError ? /* @__PURE__ */ jsx(ErrorState, {}) : historyEnabled && (!data || data.entries.length === 0) ? /* @__PURE__ */ jsxs("div", {
					className: "flex min-h-[60px] flex-col items-center justify-center gap-2",
					children: [/* @__PURE__ */ jsx(Coins, { className: `size-10 text-${textColor} opacity-30` }), /* @__PURE__ */ jsxs("p", {
						className: `text-sm font-semibold text-${textColor} opacity-50`,
						children: [
							"No ",
							pointsLabelPlural,
							" Activity"
						]
					})]
				}) : historyEnabled && data && data.entries.length > 0 ? /* @__PURE__ */ jsxs("div", {
					className: "flex flex-col gap-2",
					children: [
						/* @__PURE__ */ jsxs("button", {
							type: "button",
							"aria-expanded": historyOpen,
							"aria-controls": historyPanelId,
							onClick: () => setHistoryOpen((prev) => !prev),
							className: `flex w-full items-center text-xs font-semibold text-${textColor} cursor-pointer`,
							children: [/* @__PURE__ */ jsx("span", {
								className: "flex-1 text-left",
								children: historyTitle
							}), /* @__PURE__ */ jsx(ChevronDown, { className: `size-4 transition-transform duration-200 ${historyOpen ? "rotate-180" : ""}` })]
						}),
						/* @__PURE__ */ jsx("div", { className: `bg-${textColor}/20 h-px w-full` }),
						/* @__PURE__ */ jsx("div", {
							id: historyPanelId,
							className: `flex flex-col ${!historyOpen ? "hidden" : ""}`,
							children: data.entries.map((entry, index) => /* @__PURE__ */ jsx(PointsEntryRow, {
								entry,
								isLast: index === data.entries.length - 1,
								textColor,
								accentColor,
								backgroundColor,
								pointsLabelPlural
							}, entry.id))
						})
					]
				}) : null
			]
		})
	});
}
const pointsWidgetPropertySchema = {
	widgetType: "PointsWidget",
	displayName: "Points",
	fields: [
		{
			key: "titleEnabled",
			label: "Show Title",
			type: "boolean",
			description: "Toggle title visibility",
			defaultValue: true,
			group: "Title"
		},
		{
			key: "title",
			label: "Title",
			type: "text",
			description: "Title text displayed above the balance. Leave blank to use the company's configured points label.",
			defaultValue: "",
			group: "Title",
			requiresKeyToBeTrue: "titleEnabled"
		},
		getFontSizeField({
			key: "titleFontSize",
			label: "Title Font Size",
			description: "Font size for the title",
			defaultValue: "md",
			group: "Title",
			requiresKeyToBeTrue: "titleEnabled"
		}),
		getColorField({
			key: "titleColor",
			label: "Title Color",
			description: "Color for the title",
			defaultValue: "foreground",
			group: "Title",
			requiresKeyToBeTrue: "titleEnabled"
		}),
		getColorField({
			key: "balanceColor",
			label: "Balance Color",
			description: "Color for the points balance number",
			defaultValue: "primary",
			group: "Balance"
		}),
		{
			key: "historyEnabled",
			label: "Show History",
			type: "boolean",
			description: "Show a collapsible history dropdown below the balance",
			defaultValue: true,
			group: "History"
		},
		{
			key: "historyTitle",
			label: "History Title",
			type: "text",
			description: "Title for the history dropdown",
			defaultValue: "History",
			group: "History",
			requiresKeyToBeTrue: "historyEnabled"
		},
		{
			type: "background",
			key: "background",
			label: "Background",
			description: "Background for the widget",
			defaultValue: "background",
			group: "Design"
		},
		getColorField({
			key: "textColor",
			label: "Text Color",
			description: "Default text color",
			defaultValue: "foreground",
			group: "Design"
		}),
		getColorField({
			key: "accentColor",
			label: "Accent Color",
			description: "Color for positive points amounts",
			defaultValue: "primary",
			group: "Design"
		}),
		{
			key: "separator",
			type: "separator",
			label: "Separator",
			group: "Design"
		},
		getPaddingField({
			key: "padding",
			label: "Padding",
			description: "Widget padding",
			defaultValue: 4,
			group: "Design"
		}),
		getBorderRadiusField({
			key: "borderRadius",
			label: "Border Radius",
			description: "Widget border radius",
			defaultValue: "md",
			group: "Design"
		}),
		getBorderWidthField({
			key: "borderWidth",
			label: "Border Width",
			description: "Widget border width",
			defaultValue: "none",
			group: "Design"
		}),
		getBorderColorField({
			key: "borderColor",
			label: "Border Color",
			description: "Widget border color",
			defaultValue: "muted",
			group: "Design"
		})
	]
};
//#endregion
export { titleCaseFromSnake as a, usePointsLabel as i, PointsWidget_exports as n, pointsWidgetPropertySchema as r, PointsWidget as t };

//# sourceMappingURL=PointsWidget-Bvnj_7Ck.mjs.map