"use client";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import Link from "next/link";
import { ArrowUpRightSquare, Pencil, Plus, Trash2 } from "lucide-react";
import { Button } from "@open-mercato/ui/primitives/button";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue
} from "@open-mercato/ui/primitives/select";
import { flash } from "@open-mercato/ui/backend/FlashMessages";
import { createCrudFormError } from "@open-mercato/ui/backend/utils/serverErrors";
import { CrudForm } from "@open-mercato/ui/backend/CrudForm";
import { collectCustomFieldValues } from "@open-mercato/ui/backend/utils/customFieldValues";
import { DictionaryEntrySelect } from "@open-mercato/core/modules/dictionaries/components/DictionaryEntrySelect";
import { formatRelativeTime, formatDateTime } from "@open-mercato/shared/lib/time";
import { LoadingMessage, TabEmptyState } from ".//index.js";
import { useT } from "@open-mercato/shared/lib/i18n/context";
import { createTranslatorWithFallback } from "@open-mercato/shared/lib/i18n/translate";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@open-mercato/ui/primitives/dialog";
import { useConfirmDialog } from "../confirm-dialog/index.js";
import { ComponentReplacementHandles } from "@open-mercato/shared/modules/widgets/component-registry";
import { useRegisteredComponent } from "../injection/useRegisteredComponent.js";
const INVALID_DATE_MESSAGE = "invalidDate";
const schema = {
  validate(values) {
    const result = { ok: true };
    const activityType = typeof values.activityType === "string" ? values.activityType.trim() : "";
    if (!activityType) {
      result.ok = false;
      result.errors = [{ path: "activityType", message: "required" }];
      return result;
    }
    const occurredAt = typeof values.occurredAt === "string" ? values.occurredAt.trim() : "";
    if (occurredAt.length) {
      const parsed = new Date(occurredAt);
      if (Number.isNaN(parsed.getTime())) {
        result.ok = false;
        result.errors = [{ path: "occurredAt", message: INVALID_DATE_MESSAGE }];
      }
    }
    return result;
  }
};
function toLocalDateTimeInput(value) {
  if (!value) return "";
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return "";
  const pad = (input) => `${input}`.padStart(2, "0");
  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(
    date.getMinutes()
  )}`;
}
function TimelineItemHeader({
  title,
  subtitle,
  timestamp,
  fallbackTimestampLabel,
  icon,
  color,
  iconSize = "md",
  className,
  renderIcon,
  renderColor
}) {
  const wrapperSize = iconSize === "sm" ? "h-6 w-6" : "h-8 w-8";
  const iconSizeClass = iconSize === "sm" ? "h-3.5 w-3.5" : "h-4 w-4";
  const resolvedTimestamp = React.useMemo(() => {
    if (subtitle) return subtitle;
    if (!timestamp) return fallbackTimestampLabel ?? null;
    const value = typeof timestamp === "string" ? timestamp : timestamp.toISOString();
    const date = new Date(value);
    if (Number.isNaN(date.getTime())) return fallbackTimestampLabel ?? null;
    const now = Date.now();
    const diff = Math.abs(now - date.getTime());
    const THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1e3;
    const relativeLabel = diff <= THIRTY_DAYS_MS ? formatRelativeTime(value) : null;
    const absoluteLabel = formatDateTime(value);
    if (relativeLabel) {
      return /* @__PURE__ */ jsx("span", { title: absoluteLabel ?? void 0, children: relativeLabel });
    }
    return absoluteLabel ?? fallbackTimestampLabel ?? null;
  }, [fallbackTimestampLabel, subtitle, timestamp]);
  const iconNode = icon && renderIcon ? renderIcon(icon, iconSizeClass) : null;
  return /* @__PURE__ */ jsxs("div", { className: ["flex items-start gap-3", className].filter(Boolean).join(" "), children: [
    iconNode ? /* @__PURE__ */ jsx("span", { className: ["inline-flex items-center justify-center rounded border border-border bg-muted/50", wrapperSize].join(" "), children: iconNode }) : null,
    /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
      /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
        /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-foreground", children: title }),
        color && renderColor ? renderColor(color, "h-3 w-3 rounded-full border border-border") : null
      ] }),
      resolvedTimestamp ? /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: resolvedTimestamp }) : null
    ] })
  ] });
}
function normalizeCustomFieldSubmitValue(value) {
  if (Array.isArray(value)) {
    return value.filter((entry) => entry !== void 0);
  }
  if (value === void 0) return null;
  return value;
}
function buildActivityValidationError(errors, translate) {
  const issue = errors[0];
  if (!issue) {
    throw createCrudFormError(translate("error", "Failed to save activity."));
  }
  const message = issue.message === INVALID_DATE_MESSAGE ? translate("invalidDate", "Invalid date") : translate("error", "Failed to save activity.");
  const field = issue.path;
  throw createCrudFormError(message, field ? { [field]: message } : void 0);
}
function ActivityForm({
  mode,
  initialValues,
  onSubmit,
  onCancel,
  submitLabel,
  cancelLabel,
  isSubmitting = false,
  activityTypeLabels,
  loadActivityOptions,
  createActivityOption,
  dealOptions,
  entityOptions,
  defaultEntityId,
  manageHref = "/backend/config/dictionaries",
  customFieldEntityIds,
  labelPrefix = "customers.people.detail.activities",
  appearanceLabels
}) {
  const tHook = useT();
  const t = React.useMemo(() => createTranslatorWithFallback(tHook), [tHook]);
  const translate = React.useCallback(
    (suffix, fallback) => t(`${labelPrefix}.${suffix}`, fallback ?? ""),
    [labelPrefix, t]
  );
  const [pending, setPending] = React.useState(false);
  const normalizedDealOptions = React.useMemo(() => {
    if (!Array.isArray(dealOptions)) return [];
    const seen = /* @__PURE__ */ new Set();
    return dealOptions.map((option) => {
      if (!option || typeof option !== "object") return null;
      const id = typeof option.id === "string" ? option.id.trim() : "";
      if (!id || seen.has(id)) return null;
      const label = typeof option.label === "string" && option.label.trim().length ? option.label.trim() : id;
      seen.add(id);
      return { id, label };
    }).filter((option) => !!option);
  }, [dealOptions]);
  const normalizedEntityOptions = React.useMemo(() => {
    if (!Array.isArray(entityOptions)) return [];
    const seen = /* @__PURE__ */ new Set();
    return entityOptions.map((option) => {
      if (!option || typeof option !== "object") return null;
      const id = typeof option.id === "string" ? option.id.trim() : "";
      if (!id || seen.has(id)) return null;
      const label = typeof option.label === "string" && option.label.trim().length ? option.label.trim() : id;
      seen.add(id);
      return { id, label };
    }).filter((option) => !!option);
  }, [entityOptions]);
  const baseFields = React.useMemo(() => {
    const fields = [];
    if (normalizedEntityOptions.length) {
      fields.push({
        id: "entityId",
        label: translate("fields.entity", "Assign to record"),
        type: "custom",
        layout: "half",
        component: ({ value, setValue }) => {
          const currentValue = typeof value === "string" && value.length ? value : normalizedEntityOptions[0]?.id ?? "";
          return /* @__PURE__ */ jsxs(
            Select,
            {
              value: currentValue || void 0,
              onValueChange: (next) => setValue(next ?? ""),
              children: [
                /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, {}) }),
                /* @__PURE__ */ jsx(SelectContent, { children: normalizedEntityOptions.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.id, children: option.label }, option.id)) })
              ]
            }
          );
        }
      });
    }
    if (normalizedDealOptions.length) {
      fields.push({
        id: "dealId",
        label: translate("fields.deal", "Link to deal (optional)"),
        type: "custom",
        layout: "half",
        component: ({ value, setValue }) => {
          const currentValue = typeof value === "string" ? value : "";
          return /* @__PURE__ */ jsxs(
            Select,
            {
              value: currentValue || void 0,
              onValueChange: (next) => setValue(next ?? ""),
              children: [
                /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: translate("fields.dealPlaceholder", "No linked deal") }) }),
                /* @__PURE__ */ jsx(SelectContent, { children: normalizedDealOptions.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.id, children: option.label }, option.id)) })
              ]
            }
          );
        }
      });
    }
    fields.push({
      id: "activityType",
      label: translate("fields.type", "Activity type"),
      type: "custom",
      required: true,
      layout: "half",
      component: ({ value, setValue }) => /* @__PURE__ */ jsx(
        DictionaryEntrySelect,
        {
          value: typeof value === "string" ? value : void 0,
          onChange: (next) => setValue(next ?? ""),
          fetchOptions: loadActivityOptions,
          createOption: createActivityOption,
          labels: activityTypeLabels,
          allowAppearance: true,
          allowInlineCreate: true,
          appearanceLabels,
          selectClassName: "w-full",
          manageHref
        }
      )
    });
    fields.push({
      id: "subject",
      label: translate("fields.subject", "Subject"),
      type: "text",
      layout: "half",
      placeholder: translate("subjectPlaceholder", "Add a subject (optional)")
    });
    fields.push({
      id: "body",
      label: translate("fields.body", "Details"),
      type: "textarea",
      placeholder: translate("bodyPlaceholder", "Describe the interaction")
    });
    fields.push({
      id: "occurredAt",
      label: translate("fields.occurredAt", "Occurred / will occur at"),
      type: "custom",
      component: ({ value, setValue }) => /* @__PURE__ */ jsx(
        "input",
        {
          type: "datetime-local",
          className: "w-full rounded-md border px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
          value: typeof value === "string" ? value : "",
          onChange: (event) => setValue(event.target.value || ""),
          onFocus: (event) => {
            const target = event.currentTarget;
            if (typeof target.showPicker === "function") {
              try {
                target.showPicker();
              } catch {
              }
            }
          },
          onClick: (event) => {
            const target = event.currentTarget;
            if (typeof target.showPicker === "function") {
              try {
                target.showPicker();
              } catch {
              }
            }
          }
        }
      ),
      layout: "half"
    });
    return fields;
  }, [
    activityTypeLabels,
    appearanceLabels,
    createActivityOption,
    loadActivityOptions,
    manageHref,
    normalizedDealOptions,
    normalizedEntityOptions,
    translate
  ]);
  const baseFieldIds = React.useMemo(() => new Set(baseFields.map((field) => field.id)), [baseFields]);
  const groups = React.useMemo(() => {
    const detailFields = [];
    if (normalizedEntityOptions.length) detailFields.push("entityId");
    if (normalizedDealOptions.length) detailFields.push("dealId");
    detailFields.push("activityType", "subject", "occurredAt", "body");
    const baseGroups = [
      {
        id: "details",
        title: translate("form.details", "Activity details"),
        column: 1,
        fields: detailFields
      }
    ];
    baseGroups.push({
      id: "custom",
      title: translate("form.customFields", "Custom fields"),
      column: 2,
      kind: "customFields"
    });
    return baseGroups;
  }, [normalizedDealOptions.length, normalizedEntityOptions.length, translate]);
  const handleSubmit = React.useCallback(
    async (values) => {
      if (pending || isSubmitting) return;
      setPending(true);
      try {
        const parsed = schema.validate(values);
        if (!parsed.ok) {
          throw buildActivityValidationError(parsed.errors ?? [], translate);
        }
        const rawEntityId = typeof values.entityId === "string" ? values.entityId.trim() : "";
        const resolvedEntityId = rawEntityId || (typeof defaultEntityId === "string" ? defaultEntityId : "");
        const rawDealId = typeof values.dealId === "string" ? values.dealId.trim() : "";
        const base = {
          activityType: typeof values.activityType === "string" ? values.activityType.trim() : "",
          subject: typeof values.subject === "string" && values.subject.trim().length ? values.subject.trim() : void 0,
          body: typeof values.body === "string" && values.body.trim().length ? values.body.trim() : void 0,
          occurredAt: typeof values.occurredAt === "string" && values.occurredAt.trim().length ? new Date(values.occurredAt).toISOString() : void 0,
          dealId: rawDealId.length ? rawDealId : void 0
        };
        const reservedCustomKeys = /* @__PURE__ */ new Set(["entityId", "dealId"]);
        const customEntries = collectCustomFieldValues(values, {
          transform: (value) => normalizeCustomFieldSubmitValue(value),
          accept: (fieldId) => !reservedCustomKeys.has(fieldId)
        });
        Object.entries(values).forEach(([key, value]) => {
          if (key.startsWith("cf_")) return;
          if (!baseFieldIds.has(key) && key !== "id") {
            if (reservedCustomKeys.has(key)) return;
            customEntries[key] = normalizeCustomFieldSubmitValue(value);
          }
        });
        await onSubmit({ base, custom: customEntries, entityId: resolvedEntityId.length ? resolvedEntityId : void 0 });
      } finally {
        setPending(false);
      }
    },
    [baseFieldIds, defaultEntityId, isSubmitting, onSubmit, pending, translate]
  );
  const embeddedInitialValues = React.useMemo(() => {
    const occurredAt = toLocalDateTimeInput(initialValues?.occurredAt ?? null);
    const resolvedEntity = (() => {
      const raw = typeof initialValues?.entityId === "string" ? initialValues.entityId : typeof defaultEntityId === "string" ? defaultEntityId : normalizedEntityOptions[0]?.id ?? "";
      return raw ?? "";
    })();
    const resolvedDeal = typeof initialValues?.dealId === "string" ? initialValues.dealId : "";
    return {
      entityId: resolvedEntity,
      dealId: resolvedDeal,
      activityType: initialValues?.activityType ?? "",
      subject: initialValues?.subject ?? "",
      body: initialValues?.body ?? "",
      occurredAt,
      ...Object.fromEntries(
        Object.entries(initialValues ?? {}).filter(([key]) => {
          if (!key.startsWith("cf_")) return false;
          const trimmed = key.slice(3);
          return trimmed !== "entityId" && trimmed !== "dealId";
        }).map(([key, value]) => [key, value])
      )
    };
  }, [defaultEntityId, initialValues, normalizedEntityOptions]);
  return /* @__PURE__ */ jsx(
    CrudForm,
    {
      embedded: true,
      fields: baseFields,
      groups,
      initialValues: embeddedInitialValues,
      onSubmit: handleSubmit,
      submitLabel: submitLabel ?? (mode === "edit" ? translate("update", "Update activity (\u2318/Ctrl + Enter)") : translate("save", "Save activity (\u2318/Ctrl + Enter)")),
      extraActions: /* @__PURE__ */ jsx(
        Button,
        {
          type: "button",
          variant: "outline",
          onClick: onCancel,
          disabled: pending || isSubmitting,
          children: cancelLabel ?? translate("cancel", "Cancel")
        }
      ),
      entityIds: customFieldEntityIds
    }
  );
}
function ActivityDialog({
  open,
  mode,
  onOpenChange,
  initialValues,
  onSubmit,
  isSubmitting,
  activityTypeLabels,
  loadActivityOptions,
  createActivityOption,
  titles,
  submitLabels,
  cancelLabel,
  dealOptions,
  entityOptions,
  defaultEntityId,
  manageHref,
  customFieldEntityIds,
  labelPrefix = "customers.people.detail.activities",
  appearanceLabels
}) {
  const tHook = useT();
  const t = React.useMemo(() => createTranslatorWithFallback(tHook), [tHook]);
  const translate = React.useCallback(
    (suffix, fallback, params) => t(`${labelPrefix}.${suffix}`, fallback ?? "", params),
    [labelPrefix, t]
  );
  const dialogTitle = mode === "edit" ? titles?.edit ?? translate("editTitle", "Edit activity") : titles?.create ?? translate("addTitle", "Add activity");
  const resolvedSubmitLabel = mode === "edit" ? submitLabels?.edit ?? translate("update", "Update activity (\u2318/Ctrl + Enter)") : submitLabels?.create ?? translate("save", "Save activity (\u2318/Ctrl + Enter)");
  const resolvedCancelLabel = cancelLabel ?? translate("cancel", "Cancel");
  const handleCancel = React.useCallback(() => {
    onOpenChange(false);
  }, [onOpenChange]);
  return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-3xl", children: [
    /* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children: dialogTitle }) }),
    /* @__PURE__ */ jsx(
      ActivityForm,
      {
        mode,
        initialValues,
        onSubmit,
        onCancel: handleCancel,
        submitLabel: resolvedSubmitLabel,
        cancelLabel: resolvedCancelLabel,
        isSubmitting,
        activityTypeLabels,
        loadActivityOptions,
        createActivityOption,
        dealOptions,
        entityOptions,
        defaultEntityId,
        manageHref,
        customFieldEntityIds,
        labelPrefix,
        appearanceLabels
      }
    )
  ] }) });
}
function ActivitiesSectionImpl({
  entityId,
  dealId,
  addActionLabel,
  emptyState,
  onActionChange,
  onLoadingChange,
  dealOptions,
  entityOptions,
  defaultEntityId,
  dataAdapter,
  dataContext,
  activityTypeLabels,
  loadActivityOptions,
  createActivityOption,
  resolveActivityPresentation,
  renderCustomFields,
  customFieldEntityIds,
  labelPrefix = "customers.people.detail.activities",
  renderIcon,
  renderColor,
  appearanceLabels,
  dealLinkHref,
  manageHref
}) {
  const { confirm, ConfirmDialogElement } = useConfirmDialog();
  const tHook = useT();
  const baseTranslator = React.useMemo(() => createTranslatorWithFallback(tHook), [tHook]);
  const translate = React.useCallback(
    (suffix, fallback, params) => baseTranslator(`${labelPrefix}.${suffix}`, fallback ?? "", params),
    [baseTranslator, labelPrefix]
  );
  const resolvedDefaultEntityId = React.useMemo(() => {
    const primary = typeof entityId === "string" ? entityId.trim() : "";
    if (primary.length) return primary;
    const fallback = typeof defaultEntityId === "string" ? defaultEntityId.trim() : "";
    if (fallback.length) return fallback;
    if (Array.isArray(entityOptions)) {
      for (const option of entityOptions) {
        if (!option || typeof option !== "object") continue;
        const id = typeof option.id === "string" ? option.id.trim() : "";
        if (id.length) return id;
      }
    }
    return "";
  }, [defaultEntityId, entityId, entityOptions]);
  const resolveEntityForSubmission = React.useCallback(
    (input) => {
      const candidate = typeof input === "string" ? input.trim() : "";
      if (candidate.length) return candidate;
      return resolvedDefaultEntityId.length ? resolvedDefaultEntityId : null;
    },
    [resolvedDefaultEntityId]
  );
  const [activities, setActivities] = React.useState([]);
  const [isLoading, setIsLoading] = React.useState(() => {
    const entity = typeof entityId === "string" ? entityId.trim() : "";
    const deal = typeof dealId === "string" ? dealId.trim() : "";
    return Boolean(entity || deal || resolvedDefaultEntityId);
  });
  const [loadError, setLoadError] = React.useState(null);
  const [pendingAction, setPendingAction] = React.useState(null);
  const [dialogOpen, setDialogOpen] = React.useState(false);
  const [dialogMode, setDialogMode] = React.useState("create");
  const [editingActivityId, setEditingActivityId] = React.useState(null);
  const [initialValues, setInitialValues] = React.useState(void 0);
  const [visibleCount, setVisibleCount] = React.useState(0);
  const pendingCounterRef = React.useRef(0);
  const onLoadingChangeRef = React.useRef(onLoadingChange);
  React.useEffect(() => {
    onLoadingChangeRef.current = onLoadingChange;
  });
  const t = translate;
  const pushLoading = React.useCallback(() => {
    pendingCounterRef.current += 1;
    if (pendingCounterRef.current === 1) {
      onLoadingChangeRef.current?.(true);
    }
  }, []);
  const popLoading = React.useCallback(() => {
    pendingCounterRef.current = Math.max(0, pendingCounterRef.current - 1);
    if (pendingCounterRef.current === 0) {
      onLoadingChangeRef.current?.(false);
    }
  }, []);
  const updateVisibleCount = React.useCallback((length) => {
    if (!length) {
      setVisibleCount(0);
      return;
    }
    const baseline = Math.min(5, length);
    setVisibleCount((prev) => {
      if (prev >= length) {
        return Math.min(prev, length);
      }
      return Math.min(Math.max(prev, baseline), length);
    });
  }, []);
  const loadActivities = React.useCallback(async () => {
    const queryEntityId = typeof entityId === "string" ? entityId.trim() : "";
    const queryDealId = typeof dealId === "string" ? dealId.trim() : "";
    if (!queryEntityId && !queryDealId) {
      setActivities([]);
      setLoadError(null);
      updateVisibleCount(0);
      return;
    }
    pushLoading();
    setIsLoading(true);
    try {
      const items = await dataAdapter.list({
        entityId: queryEntityId || null,
        dealId: queryDealId || null,
        context: dataContext
      });
      setActivities(items);
      setLoadError(null);
      updateVisibleCount(items.length);
    } catch (err) {
      const message = err instanceof Error ? err.message : t("loadError", "Failed to load activities.");
      setLoadError(message);
    } finally {
      setIsLoading(false);
      popLoading();
    }
  }, [dataAdapter, dataContext, dealId, entityId, popLoading, pushLoading, t, updateVisibleCount]);
  React.useEffect(() => {
    updateVisibleCount(activities.length);
  }, [activities.length, updateVisibleCount]);
  React.useEffect(() => {
    const queryEntityId = typeof entityId === "string" ? entityId.trim() : "";
    const queryDealId = typeof dealId === "string" ? dealId.trim() : "";
    if (!queryEntityId && !queryDealId) {
      setActivities([]);
      setLoadError(null);
      setIsLoading(false);
      pendingCounterRef.current = 0;
      onLoadingChangeRef.current?.(false);
      updateVisibleCount(0);
      return;
    }
    loadActivities().catch(() => {
    });
  }, [dealId, entityId, loadActivities, updateVisibleCount]);
  const openCreateDialog = React.useCallback(() => {
    setDialogMode("create");
    setEditingActivityId(null);
    setInitialValues(void 0);
    setDialogOpen(true);
  }, []);
  const openEditDialog = React.useCallback((activity) => {
    setDialogMode("edit");
    setEditingActivityId(activity.id);
    const baseValues = {
      activityType: activity.activityType,
      subject: activity.subject ?? "",
      body: activity.body ?? "",
      occurredAt: activity.occurredAt ?? activity.createdAt ?? null,
      dealId: activity.dealId ?? "",
      entityId: activity.entityId ?? ""
    };
    const customEntries = Array.isArray(activity.customFields) ? activity.customFields : [];
    customEntries.forEach((entry) => {
      if (entry.key === "entityId" || entry.key === "dealId") return;
      baseValues[`cf_${entry.key}`] = entry.value ?? null;
    });
    setInitialValues(baseValues);
    setDialogOpen(true);
  }, []);
  const closeDialog = React.useCallback(() => {
    setDialogOpen(false);
    setDialogMode("create");
    setEditingActivityId(null);
    setInitialValues(void 0);
  }, []);
  const handleDialogOpenChange = React.useCallback(
    (next) => {
      if (!next) {
        closeDialog();
      } else {
        setDialogOpen(true);
      }
    },
    [closeDialog]
  );
  const handleCreate = React.useCallback(
    async ({ base, custom, entityId: formEntityId }) => {
      const submissionEntityId = resolveEntityForSubmission(formEntityId);
      if (!submissionEntityId) {
        const message = t("entityMissing", "Select a related record before saving.");
        flash(message, "error");
        throw new Error(message);
      }
      setPendingAction({ kind: "create" });
      pushLoading();
      try {
        const payload = {
          entityId: submissionEntityId,
          activityType: base.activityType,
          subject: base.subject ?? void 0,
          body: base.body ?? void 0,
          occurredAt: base.occurredAt ?? void 0,
          dealId: base.dealId ?? void 0,
          customFields: Object.keys(custom).length ? custom : void 0
        };
        await dataAdapter.create({ ...payload, context: dataContext });
        await loadActivities();
        flash(t("success", "Activity saved"), "success");
      } finally {
        setPendingAction(null);
        popLoading();
      }
    },
    [dataAdapter, dataContext, loadActivities, popLoading, pushLoading, resolveEntityForSubmission, t]
  );
  const handleUpdate = React.useCallback(
    async (activityId, { base, custom, entityId: formEntityId }) => {
      const submissionEntityId = resolveEntityForSubmission(formEntityId);
      if (!submissionEntityId) {
        const message = t("entityMissing", "Select a related record before saving.");
        flash(message, "error");
        throw new Error(message);
      }
      setPendingAction({ kind: "update", id: activityId });
      pushLoading();
      try {
        const patch = {
          entityId: submissionEntityId,
          activityType: base.activityType,
          subject: base.subject ?? void 0,
          body: base.body ?? void 0,
          occurredAt: base.occurredAt ?? void 0,
          dealId: base.dealId ?? void 0,
          customFields: Object.keys(custom).length ? custom : void 0
        };
        await dataAdapter.update({ id: activityId, patch, context: dataContext });
        await loadActivities();
        flash(t("updateSuccess", "Activity updated."), "success");
      } finally {
        setPendingAction(null);
        popLoading();
      }
    },
    [dataAdapter, dataContext, loadActivities, popLoading, pushLoading, resolveEntityForSubmission, t]
  );
  const handleDelete = React.useCallback(
    async (activity) => {
      if (!activity.id) return;
      const confirmed = await confirm({
        title: t("deleteConfirm", "Delete this activity? You can restore it using version history."),
        variant: "destructive"
      });
      if (!confirmed) return;
      setPendingAction({ kind: "delete", id: activity.id });
      try {
        await dataAdapter.delete({ id: activity.id, context: dataContext });
        setActivities((prev) => prev.filter((existing) => existing.id !== activity.id));
        flash(t("deleteSuccess", "Activity deleted."), "success");
      } catch (err) {
        const message = err instanceof Error ? err.message : t("deleteError", "Failed to delete activity.");
        flash(message, "error");
      } finally {
        setPendingAction(null);
      }
    },
    [confirm, dataAdapter, dataContext, t]
  );
  const handleDialogSubmit = React.useCallback(
    async (payload) => {
      try {
        if (dialogMode === "edit" && editingActivityId) {
          await handleUpdate(editingActivityId, payload);
        } else {
          await handleCreate(payload);
        }
        closeDialog();
      } catch (err) {
        const message = err instanceof Error ? err.message : t("error", "Failed to save activity");
        flash(message, "error");
      }
    },
    [closeDialog, dialogMode, editingActivityId, handleCreate, handleUpdate, t]
  );
  React.useEffect(() => {
    if (!onActionChange) return;
    if (activities.length === 0) {
      onActionChange(null);
      return () => {
        onActionChange(null);
      };
    }
    const disabled = resolveEntityForSubmission(null) === null || pendingAction !== null || isLoading;
    const action = {
      label: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5", children: [
        /* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" }),
        addActionLabel
      ] }),
      onClick: () => {
        if (!disabled) openCreateDialog();
      },
      disabled
    };
    onActionChange(action);
    return () => {
      onActionChange(null);
    };
  }, [
    activities.length,
    addActionLabel,
    isLoading,
    onActionChange,
    openCreateDialog,
    pendingAction,
    resolveEntityForSubmission
  ]);
  const isFormPending = pendingAction?.kind === "create" || pendingAction?.kind === "update" && pendingAction.id === editingActivityId;
  const visibleActivities = React.useMemo(
    () => activities.slice(0, visibleCount),
    [activities, visibleCount]
  );
  const hasMoreActivities = visibleCount < activities.length;
  const loadMoreLabel = t("loadMore", "Load more activities");
  const handleLoadMore = React.useCallback(() => {
    setVisibleCount((prev) => {
      if (prev >= activities.length) return prev;
      return Math.min(prev + 5, activities.length);
    });
  }, [activities.length]);
  const resolvePresentation = React.useCallback(
    (activity) => {
      if (resolveActivityPresentation) return resolveActivityPresentation(activity);
      return {
        label: activity.activityType,
        icon: activity.appearanceIcon ?? null,
        color: activity.appearanceColor ?? null
      };
    },
    [resolveActivityPresentation]
  );
  const resolveDealHref = React.useCallback(
    (id) => dealLinkHref ? dealLinkHref(id) : `/backend/customers/deals/${encodeURIComponent(id)}`,
    [dealLinkHref]
  );
  return /* @__PURE__ */ jsxs("div", { className: "mt-3 space-y-4", children: [
    loadError ? /* @__PURE__ */ jsx("div", { className: "rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-sm text-destructive", children: loadError }) : null,
    /* @__PURE__ */ jsx("div", { className: "space-y-4", children: isLoading && activities.length === 0 ? /* @__PURE__ */ jsx(
      LoadingMessage,
      {
        label: t("loading", "Loading activities\u2026"),
        className: "border-0 bg-transparent p-0 py-8 justify-center"
      }
    ) : /* @__PURE__ */ jsxs(Fragment, { children: [
      !isLoading && activities.length === 0 && !dialogOpen ? /* @__PURE__ */ jsx(
        TabEmptyState,
        {
          title: emptyState.title,
          action: {
            label: emptyState.actionLabel,
            onClick: openCreateDialog,
            disabled: resolveEntityForSubmission(null) === null || pendingAction !== null
          }
        }
      ) : null,
      visibleActivities.length > 0 ? visibleActivities.map((activity) => {
        const presentation = resolvePresentation(activity);
        const timestampValue = activity.occurredAt ?? activity.createdAt ?? null;
        const occurredLabel = formatDateTime(timestampValue) ?? t("noDate", "No date provided");
        const authorLabel = activity.authorName ?? activity.authorEmail ?? null;
        const loggedByText = authorLabel ? (() => {
          const translated = t("loggedBy", `Logged by ${authorLabel}`, { user: authorLabel });
          if (!translated || translated.includes("{{") || translated.includes("{user")) {
            return `Logged by ${authorLabel}`;
          }
          return translated;
        })() : null;
        const isUpdatePending = pendingAction?.kind === "update" && pendingAction.id === activity.id;
        const isDeletePending = pendingAction?.kind === "delete" && pendingAction.id === activity.id;
        return /* @__PURE__ */ jsxs(
          "div",
          {
            className: "group space-y-3 rounded-lg border bg-card p-4 transition hover:border-border/70 cursor-pointer",
            role: "button",
            tabIndex: 0,
            onClick: () => openEditDialog(activity),
            onKeyDown: (event) => {
              if (event.key === "Enter" || event.key === " ") {
                event.preventDefault();
                openEditDialog(activity);
              }
            },
            children: [
              /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [
                /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
                  /* @__PURE__ */ jsx(
                    TimelineItemHeader,
                    {
                      title: presentation.label,
                      timestamp: timestampValue,
                      fallbackTimestampLabel: occurredLabel,
                      icon: presentation.icon,
                      color: presentation.color,
                      renderIcon,
                      renderColor
                    }
                  ),
                  activity.dealId ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
                    /* @__PURE__ */ jsx(ArrowUpRightSquare, { className: "h-3.5 w-3.5" }),
                    /* @__PURE__ */ jsx(
                      Link,
                      {
                        href: resolveDealHref(activity.dealId),
                        className: "font-medium text-foreground hover:underline",
                        onClick: (event) => event.stopPropagation(),
                        children: activity.dealTitle && activity.dealTitle.length ? activity.dealTitle : t("linkedDeal", "Linked deal")
                      }
                    )
                  ] }) : null
                ] }),
                /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 opacity-100 md:opacity-0 transition-opacity md:group-hover:opacity-100 focus-within:opacity-100", children: [
                  /* @__PURE__ */ jsx(
                    Button,
                    {
                      type: "button",
                      variant: "ghost",
                      size: "icon",
                      onClick: (event) => {
                        event.stopPropagation();
                        openEditDialog(activity);
                      },
                      disabled: pendingAction !== null,
                      children: isUpdatePending ? /* @__PURE__ */ jsx("span", { className: "relative flex h-4 w-4 items-center justify-center", children: /* @__PURE__ */ jsx("span", { className: "absolute h-4 w-4 animate-spin rounded-full border border-primary border-t-transparent" }) }) : /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" })
                    }
                  ),
                  /* @__PURE__ */ jsx(
                    Button,
                    {
                      type: "button",
                      variant: "ghost",
                      size: "icon",
                      onClick: (event) => {
                        event.stopPropagation();
                        handleDelete(activity).catch(() => {
                        });
                      },
                      disabled: pendingAction !== null,
                      children: isDeletePending ? /* @__PURE__ */ jsx("span", { className: "relative flex h-4 w-4 items-center justify-center text-destructive", children: /* @__PURE__ */ jsx("span", { className: "absolute h-4 w-4 animate-spin rounded-full border border-destructive border-t-transparent" }) }) : /* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4" })
                    }
                  )
                ] })
              ] }),
              activity.subject ? /* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: activity.subject }) : null,
              activity.body ? /* @__PURE__ */ jsx("p", { className: "text-sm whitespace-pre-wrap text-muted-foreground", children: activity.body }) : null,
              renderCustomFields ? renderCustomFields(activity) : null,
              loggedByText ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: loggedByText }) : null
            ]
          },
          activity.id
        );
      }) : null,
      hasMoreActivities ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: handleLoadMore, disabled: pendingAction !== null, children: loadMoreLabel }) }) : null
    ] }) }),
    /* @__PURE__ */ jsx(
      ActivityDialog,
      {
        open: dialogOpen,
        mode: dialogMode,
        onOpenChange: handleDialogOpenChange,
        initialValues,
        onSubmit: async (payload) => {
          await handleDialogSubmit(payload);
        },
        isSubmitting: Boolean(isFormPending),
        activityTypeLabels,
        loadActivityOptions,
        createActivityOption,
        dealOptions,
        entityOptions,
        defaultEntityId: resolvedDefaultEntityId || void 0,
        manageHref,
        customFieldEntityIds,
        labelPrefix,
        appearanceLabels
      }
    ),
    ConfirmDialogElement
  ] });
}
function ActivitiesSection(props) {
  const handle = ComponentReplacementHandles.section("ui.detail", "ActivitiesSection");
  const Resolved = useRegisteredComponent(
    handle,
    ActivitiesSectionImpl
  );
  return /* @__PURE__ */ jsx("div", { "data-component-handle": handle, children: /* @__PURE__ */ jsx(Resolved, { ...props }) });
}
var ActivitiesSection_default = ActivitiesSection;
export {
  ActivitiesSection,
  ActivitiesSection_default as default
};
//# sourceMappingURL=ActivitiesSection.js.map
