"use client";
import { jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import { Calendar, X } from "lucide-react";
import { VisuallyHidden } from "@radix-ui/react-visually-hidden";
import { useLocale, useT } from "@open-mercato/shared/lib/i18n/context";
import { apiCallOrThrow } from "@open-mercato/ui/backend/utils/apiCall";
import { extractOptimisticLockConflict } from "@open-mercato/ui/backend/utils/optimisticLock";
import { surfaceRecordConflict } from "@open-mercato/ui/backend/conflicts";
import { createCrudFormError } from "@open-mercato/ui/backend/utils/serverErrors";
import { flash } from "@open-mercato/ui/backend/FlashMessages";
import { CrudForm } from "@open-mercato/ui/backend/CrudForm";
import { collectCustomFieldValues } from "@open-mercato/ui/backend/utils/customFieldValues";
import { Alert, AlertDescription, AlertTitle } from "@open-mercato/ui/primitives/alert";
import { Button } from "@open-mercato/ui/primitives/button";
import { Dialog, DialogContent, DialogTitle } from "@open-mercato/ui/primitives/dialog";
import { IconButton } from "@open-mercato/ui/primitives/icon-button";
import { Input } from "@open-mercato/ui/primitives/input";
import { Textarea } from "@open-mercato/ui/primitives/textarea";
import { useDialogKeyHandler } from "@open-mercato/ui/hooks/useDialogKeyHandler";
import { E } from "../../../../generated/entities.ids.generated.js";
import {
  buildEditorTypeOptions,
  buildInteractionPayload,
  computeDurationMinutes,
  createDefaultFormState,
  defaultRepeatDaysForDateInput,
  editorKindOfInteractionType,
  KIND_CONFIG,
  parseItemToFormState,
  resolveSavedOwnerUserId
} from "../../lib/calendar/editorPayload.js";
import { renderDictionaryIcon } from "@open-mercato/core/modules/dictionaries/components/dictionaryAppearance";
import { normalizeCustomFieldSubmitValue } from "../detail/customFieldUtils.js";
import { EDITOR_SCROLL_EVENT, Field } from "./editor/inputs.js";
import { SegmentGroup } from "./editor/SegmentGroup.js";
import { PriorityField } from "./editor/PriorityField.js";
import { RelatedToField } from "./editor/RelatedToField.js";
import { RepeatField } from "./editor/RepeatField.js";
import { PeopleField } from "./editor/PeopleField.js";
import { ResourcesField } from "./editor/ResourcesField.js";
import { ScheduleSection } from "./editor/ScheduleSection.js";
import { LocationField } from "./editor/LocationField.js";
import { useConflictProbe, useEditorLabelResolution } from "./editor/hooks.js";
const FORM_ID = "customers-calendar-event-editor";
const INTERACTION_ENTITY_IDS = [E.customers.customer_interaction];
const PEOPLE_FIELD_TEXT = {
  attendees: { labelKey: "customers.calendar.editor.attendees", label: "Attendees", placeholderKey: "customers.calendar.editor.addPeoplePlaceholder", placeholder: "Add staff or customer\u2026" },
  participants: { labelKey: "customers.calendar.editor.participants", label: "Participants", placeholderKey: "customers.calendar.editor.addPeoplePlaceholder", placeholder: "Add staff or customer\u2026" },
  to: { labelKey: "customers.calendar.editor.to", label: "To", placeholderKey: "customers.calendar.editor.addRecipientPlaceholder", placeholder: "Add recipient\u2026" }
};
function formStateOfValues(values) {
  return values;
}
function customFieldInitialValues(item) {
  const customValues = item.raw.customValues;
  if (!customValues || typeof customValues !== "object" || Array.isArray(customValues)) return {};
  return Object.fromEntries(
    Object.entries(customValues).map(([key, value]) => [`cf_${key}`, value])
  );
}
function EditorBody({
  ctx,
  open,
  isEdit,
  item,
  typeLabels,
  typeIcons,
  conflictScope,
  currentUserId,
  resourcesEnabled,
  staffEnabled
}) {
  const t = useT();
  const locale = useLocale();
  const { setValue, errors } = ctx;
  const form = formStateOfValues(ctx.values);
  const config = KIND_CONFIG[form.kind];
  const update = React.useCallback(
    (patch) => {
      for (const [key, value] of Object.entries(patch)) setValue(key, value);
    },
    [setValue]
  );
  useEditorLabelResolution(open, form, update);
  const draftOwnerUserId = resolveSavedOwnerUserId(config, form, isEdit, item?.ownerUserId ?? null);
  const conflict = useConflictProbe(open, form, config, isEdit && item ? item.raw.id : null, draftOwnerUserId, conflictScope, currentUserId);
  const kindLabels = React.useMemo(
    () => ({
      meeting: t("customers.calendar.editor.types.meeting", "meeting"),
      call: t("customers.calendar.editor.types.call", "call"),
      email: t("customers.calendar.editor.types.email", "email"),
      note: t("customers.calendar.editor.types.note", "note"),
      event: t("customers.calendar.editor.types.event", "event"),
      task: t("customers.calendar.editor.types.task", "task")
    }),
    [t]
  );
  const selectedType = form.category ?? form.kind;
  const typeOptions = React.useMemo(
    () => buildEditorTypeOptions({ typeLabels, typeIcons, selectedValue: selectedType, kindLabels }),
    [typeLabels, typeIcons, selectedType, kindLabels]
  );
  const typeSwitcherOptions = React.useMemo(
    () => typeOptions.map((option) => ({
      value: option.value,
      label: option.label,
      icon: renderDictionaryIcon(option.icon, "h-4 w-4")
    })),
    [typeOptions]
  );
  const phoneContactIds = React.useMemo(() => {
    const ids = [];
    if (form.relatedTo && form.relatedTo.kind !== "company") ids.push(form.relatedTo.id);
    for (const participant of form.participants) {
      if (participant.isCustomer) ids.push(participant.userId);
    }
    return Array.from(new Set(ids));
  }, [form.relatedTo, form.participants]);
  const titleLabel = form.kind === "email" ? t("customers.calendar.editor.titleLabel.email", "Subject") : form.kind === "note" ? t("customers.calendar.editor.titleLabel.note", "Note") : t("customers.calendar.editor.titleLabel.generic", "Title");
  return (
    // Single column on phones (full-screen sheet). On lg+ the dialog widens and
    // the fields group into two thematic columns: WHEN (schedule + repeat) on
    // the left, CONTEXT (related record, category, location) on the right;
    // people/resources and the task fields pair up below; title, description
    // and the type switcher span both columns.
    /* @__PURE__ */ jsxs("div", { className: "grid w-full grid-cols-1 items-start gap-4 lg:grid-cols-2 lg:gap-x-6", children: [
      conflict ? /* @__PURE__ */ jsxs(Alert, { variant: "warning", className: "rounded-lg lg:col-span-2", children: [
        /* @__PURE__ */ jsx(AlertTitle, { children: t("customers.calendar.editor.conflictTitle", "Calendar conflict") }),
        /* @__PURE__ */ jsx(AlertDescription, { children: conflict })
      ] }) : null,
      /* @__PURE__ */ jsx("div", { className: "w-full lg:col-span-2", children: /* @__PURE__ */ jsx(
        SegmentGroup,
        {
          ariaLabel: t("customers.calendar.editor.typeSwitcher", "Event type"),
          value: selectedType,
          onChange: (type) => update({ kind: editorKindOfInteractionType(type), category: type }),
          options: typeSwitcherOptions
        }
      ) }),
      /* @__PURE__ */ jsx(Field, { label: titleLabel, error: errors.title, className: "lg:col-span-2", children: /* @__PURE__ */ jsx(
        Input,
        {
          type: "text",
          value: form.title,
          onChange: (event) => update({ title: event.target.value }),
          placeholder: t("customers.calendar.editor.titlePlaceholder", "Add a title\u2026"),
          "aria-label": titleLabel,
          autoFocus: true,
          size: "lg"
        }
      ) }),
      /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-4", children: [
        /* @__PURE__ */ jsx(
          ScheduleSection,
          {
            dateLabel: config.dateLabel,
            hasAllDay: config.hasAllDay,
            hasEnd: config.hasEnd,
            allDay: form.allDay,
            date: form.date,
            startTime: form.startTime,
            endDate: form.endDate,
            endTime: form.endTime,
            locale,
            endsError: errors.ends,
            onAllDayChange: (allDay) => update({ allDay }),
            onDateChange: (date) => {
              const untouchedDefault = JSON.stringify(form.repeatDays) === JSON.stringify(defaultRepeatDaysForDateInput(form.date));
              update(
                untouchedDefault ? { date, repeatDays: defaultRepeatDaysForDateInput(date) } : { date }
              );
            },
            onStartTimeChange: (startTime) => update({ startTime }),
            onEndDateChange: (endDate) => update({ endDate }),
            onEndTimeChange: (endTime) => update({ endTime })
          }
        ),
        config.hasRepeat ? /* @__PURE__ */ jsx(
          RepeatField,
          {
            freq: form.repeatFreq,
            days: form.repeatDays,
            endType: form.repeatEndType,
            count: form.repeatCount,
            untilDate: form.repeatUntilDate,
            locale,
            onFreqChange: (repeatFreq) => update(
              repeatFreq === "weekly" ? { repeatFreq, repeatDays: defaultRepeatDaysForDateInput(form.date) } : { repeatFreq }
            ),
            onToggleDay: (index) => update({ repeatDays: form.repeatDays.map((active, dayIndex) => dayIndex === index ? !active : active) }),
            onEndTypeChange: (repeatEndType) => update({ repeatEndType }),
            onCountChange: (repeatCount) => update({ repeatCount }),
            onUntilDateChange: (repeatUntilDate) => update({ repeatUntilDate })
          }
        ) : null,
        config.people && config.people !== "assignee" ? /* @__PURE__ */ jsx(Field, { label: t(PEOPLE_FIELD_TEXT[config.people].labelKey, PEOPLE_FIELD_TEXT[config.people].label), children: /* @__PURE__ */ jsx(
          PeopleField,
          {
            mode: "multi",
            includeCustomers: true,
            includeStaff: staffEnabled,
            placeholder: t(PEOPLE_FIELD_TEXT[config.people].placeholderKey, PEOPLE_FIELD_TEXT[config.people].placeholder),
            ariaLabel: t(PEOPLE_FIELD_TEXT[config.people].labelKey, PEOPLE_FIELD_TEXT[config.people].label),
            value: form.participants,
            onChange: (participants) => update({ participants })
          }
        ) }) : null,
        config.people === "assignee" && staffEnabled ? /* @__PURE__ */ jsx(Field, { label: t("customers.calendar.editor.assignee", "Assignee"), error: errors.assignee, children: /* @__PURE__ */ jsx(
          PeopleField,
          {
            mode: "single",
            includeCustomers: false,
            includeStaff: true,
            placeholder: t("customers.calendar.editor.assigneePlaceholder", "Assign to a team member\u2026"),
            ariaLabel: t("customers.calendar.editor.assignee", "Assignee"),
            value: form.assigneeUserId ? [{ userId: form.assigneeUserId, name: form.assigneeName ?? form.assigneeUserId, isCustomer: false }] : [],
            onChange: (entries) => {
              const next = entries[entries.length - 1] ?? null;
              update({ assigneeUserId: next?.userId ?? null, assigneeName: next?.name ?? null });
            }
          }
        ) }) : null
      ] }),
      /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-4", children: [
        /* @__PURE__ */ jsx(Field, { label: t("customers.calendar.editor.relatedTo", "Related to"), error: errors.relatedTo, children: /* @__PURE__ */ jsx(
          RelatedToField,
          {
            label: t("customers.calendar.editor.relatedTo", "Related to"),
            value: form.relatedTo,
            deal: form.dealId && form.dealLabel ? { id: form.dealId, label: form.dealLabel } : null,
            onChange: (relatedTo) => update({ relatedTo }),
            onDealChange: (deal) => update({ dealId: deal?.id ?? null, dealLabel: deal?.label ?? null }),
            error: errors.relatedTo
          }
        ) }),
        config.location ? /* @__PURE__ */ jsx(
          LocationField,
          {
            variant: config.location,
            value: form.location,
            onChange: (location) => update({ location }),
            phoneContactIds
          }
        ) : null,
        resourcesEnabled ? /* @__PURE__ */ jsx(Field, { label: t("customers.calendar.editor.resources", "Resources"), children: /* @__PURE__ */ jsx(
          ResourcesField,
          {
            placeholder: t("customers.calendar.editor.resourcesPlaceholder", "Add a resource\u2026"),
            ariaLabel: t("customers.calendar.editor.resources", "Resources"),
            value: form.resources,
            onChange: (resources) => update({ resources })
          }
        ) }) : null,
        config.hasPriority ? /* @__PURE__ */ jsx(Field, { label: t("customers.calendar.editor.priority.label", "Priority"), children: /* @__PURE__ */ jsx(
          PriorityField,
          {
            value: form.priority,
            ariaLabel: t("customers.calendar.editor.priority.label", "Priority"),
            labels: {
              low: t("customers.calendar.editor.priority.low", "Low"),
              medium: t("customers.calendar.editor.priority.medium", "Medium"),
              high: t("customers.calendar.editor.priority.high", "High")
            },
            onChange: (priority) => update({ priority })
          }
        ) }) : null
      ] }),
      /* @__PURE__ */ jsx(Field, { label: t("customers.calendar.editor.description", "Description"), className: "lg:col-span-2", children: /* @__PURE__ */ jsx(
        Textarea,
        {
          value: form.description,
          onChange: (event) => update({ description: event.target.value }),
          placeholder: t("customers.calendar.editor.descriptionPlaceholder", "Add details\u2026"),
          "aria-label": t("customers.calendar.editor.description", "Description"),
          className: "h-20 resize-none"
        }
      ) })
    ] })
  );
}
function CalendarEventEditor({
  open,
  mode,
  item,
  defaultDate,
  defaultRange,
  typeLabels,
  typeIcons,
  conflictScope,
  currentUserId,
  resourcesEnabled,
  staffEnabled,
  onOpenChange,
  onSaved
}) {
  const t = useT();
  const [saving, setSaving] = React.useState(false);
  const isEdit = mode === "edit" && Boolean(item?.id);
  const [openSeq, setOpenSeq] = React.useState(0);
  const wasOpenRef = React.useRef(false);
  React.useEffect(() => {
    if (open && !wasOpenRef.current) setOpenSeq((seq) => seq + 1);
    wasOpenRef.current = open;
  }, [open]);
  const formKey = `${mode}:${item?.id ?? "new"}:${openSeq}`;
  const initialValues = React.useMemo(() => {
    if (isEdit && item) {
      return {
        ...parseItemToFormState(item),
        ...customFieldInitialValues(item),
        id: item.id,
        updatedAt: item.updatedAt ?? void 0
      };
    }
    return { ...createDefaultFormState(defaultDate ?? null, void 0, defaultRange ?? null) };
  }, [isEdit, item, defaultDate, defaultRange, openSeq]);
  const handleSubmit = React.useCallback(
    async (values) => {
      const form = formStateOfValues(values);
      const config = KIND_CONFIG[form.kind];
      const fieldErrors = {};
      if (!form.title.trim()) {
        fieldErrors.title = t("customers.calendar.editor.validation.titleRequired", "Title is required");
      }
      if (!form.relatedTo) {
        fieldErrors.relatedTo = t("customers.calendar.editor.validation.relatedToRequired", "Select a person or company to link this event");
      }
      if (config.hasEnd && !form.allDay && computeDurationMinutes(form) === null) {
        fieldErrors.ends = t("customers.calendar.editor.validation.endsBeforeStarts", "End must be after start");
      }
      if (config.people === "assignee" && staffEnabled !== false && !form.assigneeUserId) {
        fieldErrors.assignee = t("customers.calendar.editor.validation.assigneeRequired", "Assign this task to a team member");
      }
      if (Object.keys(fieldErrors).length > 0) {
        throw createCrudFormError(Object.values(fieldErrors)[0], fieldErrors);
      }
      setSaving(true);
      try {
        const payload = buildInteractionPayload(form, {
          mode,
          id: item?.id,
          resourcesEnabled: resourcesEnabled === true,
          staffEnabled: staffEnabled !== false
        });
        const custom = collectCustomFieldValues(values, {
          transform: (value) => normalizeCustomFieldSubmitValue(value)
        });
        for (const [key, value] of Object.entries(custom)) payload[`cf_${key}`] = value;
        await apiCallOrThrow("/api/customers/interactions", {
          method: isEdit ? "PUT" : "POST",
          headers: { "content-type": "application/json" },
          body: JSON.stringify(payload)
        });
        flash(t("customers.calendar.editor.saved", "Event saved"), "success");
        onOpenChange(false);
        requestAnimationFrame(() => {
          onSaved();
        });
      } catch (err) {
        if (extractOptimisticLockConflict(err)) {
          surfaceRecordConflict(err, t);
          onOpenChange(false);
          return;
        }
        throw err;
      } finally {
        setSaving(false);
      }
    },
    [isEdit, item?.id, mode, onOpenChange, onSaved, resourcesEnabled, staffEnabled, t]
  );
  const groups = React.useMemo(
    () => [
      {
        id: "details",
        bare: true,
        component: (ctx) => /* @__PURE__ */ jsx(
          EditorBody,
          {
            ctx,
            open,
            isEdit,
            item,
            typeLabels,
            typeIcons: typeIcons ?? {},
            conflictScope: conflictScope ?? "all",
            currentUserId: currentUserId ?? null,
            resourcesEnabled: resourcesEnabled === true,
            staffEnabled: staffEnabled !== false
          }
        )
      },
      { id: "customFields", kind: "customFields" }
    ],
    [open, isEdit, item, typeLabels, typeIcons, conflictScope, currentUserId, resourcesEnabled, staffEnabled]
  );
  const handleKeyDown = useDialogKeyHandler({
    onConfirm: () => {
      const formElement = document.getElementById(FORM_ID);
      if (formElement instanceof HTMLFormElement) formElement.requestSubmit();
    },
    disabled: saving
  });
  const dialogTitle = isEdit ? t("customers.calendar.editor.title.edit", "Edit event") : t("customers.calendar.editor.title.create", "New event");
  return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(
    DialogContent,
    {
      onKeyDown: handleKeyDown,
      onInteractOutside: (event) => {
        const target = event.detail.originalEvent.target;
        if (target?.closest("[data-dialog-content]") || target?.closest("[data-radix-popper-content-wrapper]")) {
          event.preventDefault();
        }
      },
      "aria-describedby": void 0,
      dismissible: false,
      className: "flex h-dvh max-h-dvh w-screen max-w-none flex-col gap-0 overflow-hidden rounded-none border-0 bg-background p-0 shadow-xl sm:h-auto sm:max-h-[calc(100dvh-4rem)] sm:w-full sm:max-w-lg sm:rounded-2xl sm:border-0 lg:max-w-3xl",
      children: [
        /* @__PURE__ */ jsx(VisuallyHidden, { children: /* @__PURE__ */ jsx(DialogTitle, { children: dialogTitle }) }),
        /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-3 border-b border-border bg-background py-4 pl-5 pr-4", children: [
          /* @__PURE__ */ jsx(Calendar, { "aria-hidden": true, className: "size-6 shrink-0 text-foreground", strokeWidth: 1.75 }),
          /* @__PURE__ */ jsx("p", { className: "min-w-0 flex-1 text-sm font-medium leading-5 text-foreground", children: dialogTitle }),
          /* @__PURE__ */ jsx(
            IconButton,
            {
              variant: "ghost",
              size: "sm",
              onClick: () => onOpenChange(false),
              "aria-label": t("customers.calendar.editor.close", "Close"),
              className: "shrink-0 text-muted-foreground",
              children: /* @__PURE__ */ jsx(X, { "aria-hidden": true, className: "size-5" })
            }
          )
        ] }),
        /* @__PURE__ */ jsx(
          "div",
          {
            className: "flex-1 overflow-y-auto",
            onScroll: () => {
              document.dispatchEvent(new CustomEvent(EDITOR_SCROLL_EVENT));
            },
            children: /* @__PURE__ */ jsx("div", { className: "px-4 py-4 sm:px-6 sm:py-5", children: /* @__PURE__ */ jsx(
              CrudForm,
              {
                formId: FORM_ID,
                embedded: true,
                hideFooterActions: true,
                customFieldsManageMode: "page",
                fields: [],
                groups,
                initialValues,
                entityIds: INTERACTION_ENTITY_IDS,
                onSubmit: handleSubmit
              },
              formKey
            ) })
          }
        ),
        /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center justify-end gap-3 border-t border-border bg-background px-5 py-4", children: [
          /* @__PURE__ */ jsx(
            Button,
            {
              type: "button",
              variant: "outline",
              onClick: () => onOpenChange(false),
              children: t("customers.calendar.editor.cancel", "Cancel")
            }
          ),
          /* @__PURE__ */ jsx(
            Button,
            {
              type: "submit",
              form: FORM_ID,
              disabled: saving,
              children: saving ? t("customers.calendar.editor.saving", "Saving\u2026") : t("customers.calendar.editor.save", "Save event")
            }
          )
        ] })
      ]
    }
  ) });
}
export {
  CalendarEventEditor
};
//# sourceMappingURL=CalendarEventEditor.js.map
