"use client";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import Link from "next/link";
import { Loader2, Pencil, Trash2 } from "lucide-react";
import { Button } from "@open-mercato/ui/primitives/button";
import { IconButton } from "@open-mercato/ui/primitives/icon-button";
import { StatusBadge } from "@open-mercato/ui/primitives/status-badge";
import { mapDictionaryColorToTone } from "@open-mercato/shared/lib/query/advanced-filter";
import { useOrganizationScopeVersion } from "@open-mercato/shared/lib/frontend/useOrganizationScope";
import { flash } from "@open-mercato/ui/backend/FlashMessages";
import { LoadingMessage, TabEmptyState } from "@open-mercato/ui/backend/detail";
import { cn } from "@open-mercato/shared/lib/utils";
import { useT } from "@open-mercato/shared/lib/i18n/context";
import { createTranslatorWithFallback } from "@open-mercato/shared/lib/i18n/translate";
import { formatDate, resolveTodoHref } from "./utils.js";
import { formatDateTime } from "@open-mercato/shared/lib/time";
import { TimelineItemHeader } from "./TimelineItemHeader.js";
import { TaskDialog } from "./TaskDialog.js";
import { usePersonTasks } from "./hooks/usePersonTasks.js";
import { useCustomerDictionary } from "./hooks/useCustomerDictionary.js";
import { useInteractions } from "./hooks/useInteractions.js";
import { mapInteractionRecordToTodoSummary } from "../../lib/interactionCompatibility.js";
const RESERVED_TASK_CUSTOM_KEYS = /* @__PURE__ */ new Set(["priority", "description", "due_at", "dueAt"]);
function toTimestamp(value) {
  if (!value) return null;
  const timestamp = new Date(value).getTime();
  return Number.isNaN(timestamp) ? null : timestamp;
}
function sortTaskSummaries(tasks) {
  return [...tasks].sort((left, right) => {
    const leftDue = toTimestamp(left.dueAt);
    const rightDue = toTimestamp(right.dueAt);
    if (leftDue !== null || rightDue !== null) {
      if (leftDue === null) return 1;
      if (rightDue === null) return -1;
      if (leftDue !== rightDue) return leftDue - rightDue;
    }
    const leftCreated = toTimestamp(left.createdAt) ?? 0;
    const rightCreated = toTimestamp(right.createdAt) ?? 0;
    if (leftCreated !== rightCreated) return rightCreated - leftCreated;
    return left.id.localeCompare(right.id);
  });
}
const STATUS_BADGE_VARIANTS = /* @__PURE__ */ new Set(["success", "warning", "error", "info", "neutral"]);
function coerceStatusBadgeVariant(tone) {
  return tone && STATUS_BADGE_VARIANTS.has(tone) ? tone : "neutral";
}
function buildInitialFormValues(task) {
  if (!task) return void 0;
  const values = {
    title: task.title ?? "",
    is_done: task.isDone ?? false,
    status: task.status ?? "planned",
    description: task.description ?? "",
    priority: task.priority ?? "",
    scheduledAt: task.dueAt ?? ""
  };
  if (task.customValues) {
    for (const [key, value] of Object.entries(task.customValues)) {
      if (RESERVED_TASK_CUSTOM_KEYS.has(key)) continue;
      const formKey = `cf_${key}`;
      if (values[formKey] === void 0) values[formKey] = value;
    }
  }
  return values;
}
function TasksSection({
  entityId,
  initialTasks,
  emptyLabel,
  addActionLabel,
  emptyState,
  onActionChange,
  onLoadingChange,
  onDataRefresh,
  translator,
  entityName,
  dialogContextKey,
  dialogContextFallback,
  useCanonicalInteractions = false,
  runGuardedMutation
}) {
  const tHook = useT();
  const fallbackTranslator = React.useMemo(() => createTranslatorWithFallback(tHook), [tHook]);
  const t = React.useMemo(() => translator ?? fallbackTranslator, [translator, fallbackTranslator]);
  const runWriteMutation = React.useCallback(
    async (operation, mutationPayload) => {
      if (!runGuardedMutation) {
        return operation();
      }
      return runGuardedMutation(operation, mutationPayload);
    },
    [runGuardedMutation]
  );
  const scopeVersion = useOrganizationScopeVersion();
  const statusDictionary = useCustomerDictionary("interaction-statuses", scopeVersion);
  const statusMap = statusDictionary.data?.map ?? null;
  const legacyResult = usePersonTasks({ entityId, initialTasks });
  const canonicalResult = useInteractions({
    entityId: useCanonicalInteractions ? entityId : null,
    typeFilter: "task"
  });
  const canonicalTasks = React.useMemo(
    () => useCanonicalInteractions ? canonicalResult.interactions.map(mapInteractionRecordToTodoSummary) : [],
    [useCanonicalInteractions, canonicalResult.interactions]
  );
  const canonicalCreateTask = React.useCallback(
    async (payload) => {
      if (!entityId) throw new Error("Task creation requires an entity id");
      const interactionPayload = {
        entityId,
        interactionType: "task",
        title: payload.base.title,
        status: payload.base.status ?? (payload.base.is_done ? "done" : "planned"),
        priority: payload.base.priority ?? null,
        body: payload.base.description ?? null,
        scheduledAt: payload.base.scheduledAt ?? null,
        customValues: payload.custom
      };
      await canonicalResult.createInteraction(interactionPayload);
    },
    [canonicalResult, entityId]
  );
  const canonicalUpdateTask = React.useCallback(
    async (task, payload) => {
      await canonicalResult.updateInteraction(task.todoId, {
        title: payload.base.title,
        status: payload.base.status ?? (payload.base.is_done ? "done" : "planned"),
        priority: payload.base.priority ?? null,
        body: payload.base.description ?? null,
        scheduledAt: payload.base.scheduledAt ?? null,
        customValues: payload.custom
      });
    },
    [canonicalResult]
  );
  const canonicalToggleTask = React.useCallback(
    async (task, nextIsDone) => {
      if (nextIsDone) {
        await canonicalResult.completeInteraction(task.todoId);
      } else {
        await canonicalResult.updateInteraction(task.todoId, { status: "planned" });
      }
    },
    [canonicalResult]
  );
  const canonicalUnlinkTask = React.useCallback(
    async (task) => {
      await canonicalResult.deleteInteraction(task.todoId);
    },
    [canonicalResult]
  );
  const tasks = useCanonicalInteractions ? canonicalTasks : legacyResult.tasks;
  const isInitialLoading = useCanonicalInteractions ? canonicalResult.isInitialLoading : legacyResult.isInitialLoading;
  const isLoadingMore = useCanonicalInteractions ? canonicalResult.isLoadingMore : legacyResult.isLoadingMore;
  const isMutating = useCanonicalInteractions ? canonicalResult.isMutating : legacyResult.isMutating;
  const hasMore = useCanonicalInteractions ? canonicalResult.hasMore : legacyResult.hasMore;
  const loadMore = useCanonicalInteractions ? canonicalResult.loadMore : legacyResult.loadMore;
  const refresh = useCanonicalInteractions ? canonicalResult.refresh : legacyResult.refresh;
  const createTask = useCanonicalInteractions ? canonicalCreateTask : legacyResult.createTask;
  const updateTask = useCanonicalInteractions ? canonicalUpdateTask : legacyResult.updateTask;
  const toggleTask = useCanonicalInteractions ? canonicalToggleTask : legacyResult.toggleTask;
  const unlinkTask = useCanonicalInteractions ? canonicalUnlinkTask : legacyResult.unlinkTask;
  const pendingTaskId = useCanonicalInteractions ? canonicalResult.pendingId : legacyResult.pendingTaskId;
  const error = useCanonicalInteractions ? canonicalResult.error : legacyResult.error;
  const sortedTasks = React.useMemo(() => sortTaskSummaries(tasks), [tasks]);
  const [dialogOpen, setDialogOpen] = React.useState(false);
  const [dialogMode, setDialogMode] = React.useState("create");
  const [editingTask, setEditingTask] = React.useState(null);
  const sentinelRef = React.useRef(null);
  const dialogContextMessage = React.useMemo(() => {
    if (!dialogContextKey || !entityName) return void 0;
    return t(dialogContextKey, dialogContextFallback ?? "This task will be linked to {{name}}", { name: entityName });
  }, [dialogContextFallback, dialogContextKey, entityName, t]);
  const openCreateDialog = React.useCallback(() => {
    setEditingTask(null);
    setDialogMode("create");
    setDialogOpen(true);
  }, []);
  const openEditDialog = React.useCallback((task) => {
    setEditingTask(task);
    setDialogMode("edit");
    setDialogOpen(true);
  }, []);
  const closeDialog = React.useCallback(() => {
    setDialogOpen(false);
    setEditingTask(null);
  }, []);
  React.useEffect(() => {
    if (!onActionChange) return;
    if (!entityId) {
      onActionChange(null);
      return;
    }
    onActionChange({
      label: addActionLabel,
      onClick: openCreateDialog,
      disabled: isMutating
    });
    return () => {
      onActionChange(null);
    };
  }, [addActionLabel, entityId, isMutating, onActionChange, openCreateDialog]);
  React.useEffect(() => {
    if (!onLoadingChange) return;
    onLoadingChange(isInitialLoading || isMutating);
  }, [isInitialLoading, isMutating, onLoadingChange]);
  React.useEffect(() => {
    if (!hasMore) return;
    if (typeof IntersectionObserver === "undefined") return;
    const el = sentinelRef.current;
    if (!el) return;
    const observer = new IntersectionObserver(
      (entries) => {
        if (entries.some((entry) => entry.isIntersecting)) {
          loadMore().catch(() => {
          });
        }
      },
      { rootMargin: "200px 0px 200px 0px" }
    );
    observer.observe(el);
    return () => {
      observer.disconnect();
    };
  }, [hasMore, loadMore]);
  const handleCreate = React.useCallback(
    async (payload) => {
      try {
        await runWriteMutation(
          () => createTask(payload),
          {
            entityId,
            title: payload.base.title,
            isDone: payload.base.is_done ?? void 0
          }
        );
        flash(t("customers.people.detail.tasks.createSuccess", "Task created"), "success");
        await Promise.resolve(onDataRefresh?.());
      } catch (err) {
        const message = err instanceof Error ? err.message : t("customers.people.detail.tasks.error", "Failed to create task");
        flash(message, "error");
        throw err;
      }
    },
    [createTask, entityId, onDataRefresh, runWriteMutation, t]
  );
  const handleUpdate = React.useCallback(
    async (task, payload) => {
      try {
        await runWriteMutation(
          () => updateTask(task, payload),
          {
            id: task.id,
            todoId: task.todoId,
            title: payload.base.title,
            isDone: payload.base.is_done ?? void 0
          }
        );
        flash(t("customers.people.detail.tasks.updateSuccess", "Task updated"), "success");
        await Promise.resolve(onDataRefresh?.());
      } catch (err) {
        const message = err instanceof Error ? err.message : t("customers.people.detail.tasks.updateError", "Failed to update task");
        flash(message, "error");
        throw err;
      }
    },
    [onDataRefresh, runWriteMutation, t, updateTask]
  );
  const handleToggle = React.useCallback(
    async (task, nextIsDone) => {
      try {
        await runWriteMutation(
          () => toggleTask(task, nextIsDone),
          {
            id: task.id,
            todoId: task.todoId,
            isDone: nextIsDone
          }
        );
        flash(
          nextIsDone ? t("customers.people.detail.tasks.completeSuccess", "Task marked as done") : t("customers.people.detail.tasks.reopenSuccess", "Task reopened"),
          "success"
        );
        await Promise.resolve(onDataRefresh?.());
      } catch (err) {
        const message = err instanceof Error ? err.message : t("customers.people.detail.tasks.toggleError", "Failed to update task status");
        flash(message, "error");
      }
    },
    [onDataRefresh, runWriteMutation, t, toggleTask]
  );
  const handleDelete = React.useCallback(
    async (task) => {
      try {
        await runWriteMutation(
          () => unlinkTask(task),
          {
            id: task.id,
            todoId: task.todoId
          }
        );
        flash(t("customers.people.detail.tasks.deleteSuccess", "Task removed"), "success");
        await Promise.resolve(onDataRefresh?.());
        await refresh();
      } catch (err) {
        const message = err instanceof Error ? err.message : t("customers.people.detail.tasks.deleteError", "Failed to remove task");
        flash(message, "error");
      }
    },
    [onDataRefresh, refresh, runWriteMutation, t, unlinkTask]
  );
  const handleCancel = React.useCallback(
    async (task) => {
      if (!useCanonicalInteractions) return;
      try {
        await runWriteMutation(
          () => canonicalResult.cancelInteraction(task.todoId),
          { id: task.todoId }
        );
        flash(t("customers.people.detail.tasks.cancelSuccess", "Task canceled"), "success");
        await Promise.resolve(onDataRefresh?.());
      } catch (err) {
        const message = err instanceof Error ? err.message : t("customers.people.detail.tasks.cancelError", "Failed to cancel task");
        flash(message, "error");
      }
    },
    [canonicalResult, onDataRefresh, runWriteMutation, t, useCanonicalInteractions]
  );
  const renderTaskMeta = React.useCallback(
    (task) => {
      const meta = [];
      if (task.status === "canceled") {
        meta.push(t("customers.people.detail.tasks.status.canceled", "Canceled"));
      }
      if (typeof task.priority === "number") {
        meta.push(t("customers.people.detail.tasks.priorityLabel", "Priority {{priority}}", { priority: task.priority }));
      }
      if (task.severity) {
        meta.push(
          t(
            `customers.people.detail.tasks.severity.${task.severity}`,
            task.severity.charAt(0).toUpperCase() + task.severity.slice(1)
          )
        );
      }
      if (task.dueAt) {
        const dueLabel = formatDate(task.dueAt) ?? formatDateTime(task.dueAt) ?? t("customers.people.detail.tasks.dueLabel", "Due {{date}}", { date: task.dueAt });
        meta.push(t("customers.people.detail.tasks.dueLabel", "Due {{date}}", { date: dueLabel }));
      }
      return meta;
    },
    [t]
  );
  const handleDialogSubmit = React.useCallback(
    async (payload) => {
      if (dialogMode === "edit" && editingTask) {
        await handleUpdate(editingTask, payload);
      } else {
        await handleCreate(payload);
      }
    },
    [dialogMode, editingTask, handleCreate, handleUpdate]
  );
  const hasTasks = sortedTasks.length > 0;
  return /* @__PURE__ */ jsxs("div", { className: "mt-0 space-y-6", children: [
    /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
      isInitialLoading ? /* @__PURE__ */ jsx(
        LoadingMessage,
        {
          label: t("customers.people.detail.tasks.loading", "Loading tasks\u2026"),
          className: "border-0 bg-transparent p-0 py-8 justify-center"
        }
      ) : null,
      !isInitialLoading && !hasTasks ? /* @__PURE__ */ jsx(TabEmptyState, { title: emptyState.title, children: /* @__PURE__ */ jsx(Button, { asChild: true, variant: "outline", size: "sm", className: "mt-2", children: /* @__PURE__ */ jsx(Link, { href: "/backend/customer-tasks", children: t("customers.people.detail.tasks.viewAll", "View all tasks") }) }) }) : null,
      !isInitialLoading && hasTasks ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
        error ? /* @__PURE__ */ jsx("div", { className: "rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-sm text-destructive", children: error }) : null,
        sortedTasks.map((task) => {
          const todoHref = task.externalHref ?? resolveTodoHref(task.todoSource, task.todoId);
          const createdLabel = formatDateTime(task.createdAt) ?? emptyLabel;
          const meta = renderTaskMeta(task);
          const title = task.title ?? t("customers.people.detail.tasks.untitled", "Untitled task");
          const isDone = task.isDone === true;
          const isCanceled = task.status === "canceled";
          const checkboxId = `person-task-${task.id}`;
          const isPendingToggle = pendingTaskId === task.todoId;
          return /* @__PURE__ */ jsxs("article", { className: "group space-y-3 rounded-lg border bg-card p-4 transition hover:border-border/70", children: [
            /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [
              /* @__PURE__ */ jsx(
                TimelineItemHeader,
                {
                  title: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-2", children: [
                    /* @__PURE__ */ jsx(
                      "input",
                      {
                        id: checkboxId,
                        type: "checkbox",
                        checked: isDone,
                        onChange: (event) => {
                          const next = event.target.checked;
                          void handleToggle(task, next);
                        },
                        disabled: isMutating || isPendingToggle || isCanceled,
                        className: "h-4 w-4 rounded border"
                      }
                    ),
                    /* @__PURE__ */ jsx(
                      "span",
                      {
                        className: cn(
                          "text-sm font-semibold",
                          isDone ? "line-through text-muted-foreground" : void 0,
                          isCanceled ? "text-muted-foreground" : void 0
                        ),
                        children: title
                      }
                    ),
                    task.status ? /* @__PURE__ */ jsx(
                      StatusBadge,
                      {
                        variant: coerceStatusBadgeVariant(
                          mapDictionaryColorToTone(statusMap?.[task.status]?.color ?? null)
                        ),
                        dot: true,
                        children: statusMap?.[task.status]?.label ?? task.status
                      }
                    ) : null
                  ] }),
                  timestamp: task.createdAt,
                  fallbackTimestampLabel: createdLabel
                }
              ),
              /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 opacity-0 transition-opacity group-hover:opacity-100 focus-within:opacity-100", children: [
                /* @__PURE__ */ jsx(
                  IconButton,
                  {
                    type: "button",
                    variant: "ghost",
                    size: "sm",
                    onClick: () => openEditDialog(task),
                    disabled: isMutating,
                    "aria-label": t("ui.actions.edit", "Edit"),
                    children: isMutating && editingTask?.id === task.id && dialogMode === "edit" ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" })
                  }
                ),
                /* @__PURE__ */ jsx(
                  IconButton,
                  {
                    type: "button",
                    variant: "ghost",
                    size: "sm",
                    onClick: () => handleDelete(task),
                    disabled: isMutating,
                    "aria-label": t("ui.actions.delete", "Delete"),
                    children: isMutating ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin text-destructive" }) : /* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4" })
                  }
                )
              ] })
            ] }),
            meta.length ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-3 text-xs text-muted-foreground", children: meta.map((entry) => /* @__PURE__ */ jsx("span", { className: "rounded bg-muted px-2 py-1 text-xs font-medium text-muted-foreground", children: entry }, `${task.id}-${entry}`)) }) : null,
            task.description ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground whitespace-pre-wrap", children: task.description }) : null,
            /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3 text-xs", children: [
              useCanonicalInteractions && !isDone && !isCanceled ? /* @__PURE__ */ jsx(
                Button,
                {
                  type: "button",
                  variant: "ghost",
                  size: "sm",
                  className: "h-auto px-0 text-xs font-medium text-muted-foreground hover:bg-transparent hover:text-foreground",
                  onClick: () => void handleCancel(task),
                  disabled: isMutating || isPendingToggle,
                  children: t("customers.people.detail.tasks.cancelAction", "Cancel task")
                }
              ) : null,
              todoHref ? /* @__PURE__ */ jsx(Link, { href: todoHref, className: "text-primary hover:underline", children: t("customers.people.detail.tasks.openTask", "Open task") }) : null
            ] })
          ] }, task.id);
        }),
        /* @__PURE__ */ jsx("div", { ref: sentinelRef }),
        hasMore ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => loadMore().catch(() => {
        }), disabled: isLoadingMore, children: isLoadingMore ? /* @__PURE__ */ jsxs(Fragment, { children: [
          /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
          t("customers.people.detail.tasks.loadingMore", "Loading\u2026")
        ] }) : t("customers.people.detail.tasks.loadMore", "Load more") }) }) : null,
        isLoadingMore ? /* @__PURE__ */ jsxs("div", { className: "flex justify-center text-xs text-muted-foreground", children: [
          /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-3 w-3 animate-spin" }),
          t("customers.people.detail.tasks.loadingMore", "Loading\u2026")
        ] }) : null
      ] }) : null,
      !isInitialLoading && hasTasks ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(Button, { asChild: true, variant: "outline", size: "sm", children: /* @__PURE__ */ jsx(Link, { href: "/backend/customer-tasks", children: t("customers.people.detail.tasks.viewAll", "View all tasks") }) }) }) : null
    ] }),
    /* @__PURE__ */ jsx(
      TaskDialog,
      {
        open: dialogOpen,
        mode: dialogMode,
        onOpenChange: (next) => {
          if (!next) closeDialog();
          else setDialogOpen(true);
        },
        initialValues: buildInitialFormValues(editingTask),
        onSubmit: handleDialogSubmit,
        isSubmitting: isMutating,
        contextMessage: dialogContextMessage,
        useCanonicalInteractions
      }
    )
  ] });
}
var TasksSection_default = TasksSection;
export {
  TasksSection,
  TasksSection_default as default
};
//# sourceMappingURL=TasksSection.js.map
