"use client";
import { jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import { z } from "zod";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle
} from "@open-mercato/ui/primitives/dialog";
import { Button } from "@open-mercato/ui/primitives/button";
import { CrudForm } from "@open-mercato/ui/backend/CrudForm";
import { createCrud } from "@open-mercato/ui/backend/utils/crud";
import { createCrudFormError } from "@open-mercato/ui/backend/utils/serverErrors";
import { useGuardedMutation } from "@open-mercato/ui/backend/injection/useGuardedMutation";
import { flash } from "@open-mercato/ui/backend/FlashMessages";
import { useT } from "@open-mercato/shared/lib/i18n/context";
import { translateWithFallback } from "@open-mercato/shared/lib/i18n/translate";
const ADD_STAGE_CONTEXT_ID = "customers-deals-kanban:add-stage";
const TONE_OPTIONS = [
  {
    value: "",
    swatchClass: "border border-dashed border-border",
    labelKey: "customers.deals.kanban.addStage.color.none",
    labelFallback: "No color"
  },
  {
    value: "success",
    swatchClass: "bg-status-success-icon",
    labelKey: "customers.deals.kanban.addStage.color.success",
    labelFallback: "Green"
  },
  {
    value: "warning",
    swatchClass: "bg-status-warning-icon",
    labelKey: "customers.deals.kanban.addStage.color.warning",
    labelFallback: "Amber"
  },
  {
    value: "info",
    swatchClass: "bg-status-info-icon",
    labelKey: "customers.deals.kanban.addStage.color.info",
    labelFallback: "Blue"
  },
  {
    value: "error",
    swatchClass: "bg-status-error-icon",
    labelKey: "customers.deals.kanban.addStage.color.error",
    labelFallback: "Red"
  },
  {
    value: "neutral",
    swatchClass: "bg-status-neutral-icon",
    labelKey: "customers.deals.kanban.addStage.color.neutral",
    labelFallback: "Gray"
  },
  {
    value: "brand",
    swatchClass: "bg-brand-violet",
    labelKey: "customers.deals.kanban.addStage.color.brand",
    labelFallback: "Violet"
  },
  {
    value: "pink",
    swatchClass: "bg-status-pink-icon",
    labelKey: "customers.deals.kanban.addStage.color.pink",
    labelFallback: "Pink"
  }
];
const POSITION_END = "end";
const POSITION_START = "start";
const POSITION_AFTER_PREFIX = "after:";
function resolveInsertOrder(position, existingStages) {
  if (position === POSITION_END || position === "") return void 0;
  if (position === POSITION_START) return 0;
  if (position.startsWith(POSITION_AFTER_PREFIX)) {
    const afterId = position.slice(POSITION_AFTER_PREFIX.length);
    const idx = existingStages.findIndex((stage) => stage.id === afterId);
    if (idx < 0) return void 0;
    return existingStages[idx].order + 1;
  }
  return void 0;
}
function AddStageDialog({
  open,
  context,
  onClose,
  onCreated
}) {
  const t = useT();
  const [formInstanceKey, setFormInstanceKey] = React.useState(0);
  React.useEffect(() => {
    if (open) setFormInstanceKey((current) => current + 1);
  }, [open]);
  const { runMutation, retryLastMutation } = useGuardedMutation({
    contextId: ADD_STAGE_CONTEXT_ID,
    blockedMessage: translateWithFallback(t, "ui.forms.flash.saveBlocked", "Save blocked by validation")
  });
  const labelRequiredMessage = translateWithFallback(
    t,
    "customers.deals.kanban.addStage.label.required",
    "Stage name is required."
  );
  const formSchema = React.useMemo(
    () => z.object({
      label: z.string().trim().min(1, labelRequiredMessage),
      color: z.string().optional(),
      position: z.string().optional()
    }),
    [labelRequiredMessage]
  );
  const positionOptions = React.useMemo(() => {
    const existingStages = context?.existingStages ?? [];
    const opts = [
      {
        value: POSITION_END,
        label: translateWithFallback(
          t,
          "customers.deals.kanban.addStage.position.end",
          "At the end (default)"
        )
      },
      {
        value: POSITION_START,
        label: translateWithFallback(
          t,
          "customers.deals.kanban.addStage.position.start",
          "At the start"
        )
      }
    ];
    for (const stage of existingStages) {
      opts.push({
        value: `${POSITION_AFTER_PREFIX}${stage.id}`,
        label: translateWithFallback(
          t,
          "customers.deals.kanban.addStage.position.after",
          "After {label}",
          { label: stage.label }
        )
      });
    }
    return opts;
  }, [context?.existingStages, t]);
  const fields = React.useMemo(
    () => [
      {
        // CrudForm auto-focuses the first field of the first group on mount, so we don't
        // need an explicit `autoFocus: true` here — and adding one would be a type error
        // because `autoFocus` is only valid on CrudCustomFieldRenderProps.
        id: "label",
        label: translateWithFallback(t, "customers.deals.kanban.addStage.label", "Stage name"),
        type: "text",
        required: true,
        placeholder: translateWithFallback(
          t,
          "customers.deals.kanban.addStage.label.placeholder",
          "e.g. Discovery"
        )
      },
      {
        // Custom inline radio-style list instead of a Radix Select — when the dialog sits
        // near the bottom of the viewport, Radix's Select dropdown clips to the available
        // vertical space (`--radix-select-content-available-height`), which can leave only
        // 1–2 visible options and hide the rest behind a small scroll affordance the
        // operator doesn't notice. Rendering the picker inline inside the dialog body
        // gives it a deterministic max-height + clearly scrollable area, and "After {label}"
        // entries are always visible without portal clipping.
        id: "position",
        label: translateWithFallback(
          t,
          "customers.deals.kanban.addStage.position",
          "Position in pipeline"
        ),
        type: "custom",
        description: translateWithFallback(
          t,
          "customers.deals.kanban.addStage.position.help",
          "Choose where the new stage appears on the kanban. Existing stages after the chosen position shift one step to the right."
        ),
        component: ({ value, setValue }) => {
          const current = typeof value === "string" && value.length > 0 ? value : POSITION_END;
          return /* @__PURE__ */ jsx("div", { className: "flex max-h-52 flex-col gap-1 overflow-y-auto rounded-md border border-input bg-card p-1", children: positionOptions.map((option) => {
            const selected = current === option.value;
            return /* @__PURE__ */ jsxs(
              Button,
              {
                variant: "ghost",
                size: "sm",
                type: "button",
                onClick: () => setValue(option.value),
                "aria-pressed": selected,
                className: `flex items-center justify-between gap-2 rounded-sm px-3 py-2 text-left text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ${selected ? "bg-muted font-medium text-foreground" : "text-muted-foreground hover:bg-muted/60 hover:text-foreground"}`,
                children: [
                  /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: option.label }),
                  /* @__PURE__ */ jsx(
                    "span",
                    {
                      className: `inline-flex size-4 shrink-0 items-center justify-center rounded-full border ${selected ? "border-primary bg-primary" : "border-input"}`,
                      "aria-hidden": "true",
                      children: selected ? /* @__PURE__ */ jsx("span", { className: "size-1.5 rounded-full bg-primary-foreground" }) : null
                    }
                  )
                ]
              },
              option.value
            );
          }) });
        }
      },
      {
        // Custom render — built-in `select` can't render a swatch alongside each label.
        // Each swatch uses the same DS class the lane bar renders, so the picker is a
        // true preview of the kanban appearance instead of a separate hex translation.
        id: "color",
        label: translateWithFallback(t, "customers.deals.kanban.addStage.color", "Color"),
        type: "custom",
        component: ({ value, setValue }) => {
          const current = typeof value === "string" ? value : "";
          return /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: TONE_OPTIONS.map((option) => {
            const selected = current === option.value;
            const label = translateWithFallback(t, option.labelKey, option.labelFallback);
            return /* @__PURE__ */ jsxs(
              Button,
              {
                variant: "outline",
                size: "sm",
                type: "button",
                onClick: () => setValue(option.value),
                "aria-pressed": selected,
                title: label,
                className: `inline-flex items-center gap-2 rounded-md border px-3 py-1.5 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ${selected ? "border-primary bg-muted text-foreground" : "border-input bg-card text-muted-foreground hover:bg-muted hover:text-foreground"}`,
                children: [
                  /* @__PURE__ */ jsx(
                    "span",
                    {
                      className: `size-3 rounded-sm ${option.swatchClass}`,
                      "aria-hidden": "true"
                    }
                  ),
                  /* @__PURE__ */ jsx("span", { children: label })
                ]
              },
              option.value || "none"
            );
          }) });
        }
      }
    ],
    [positionOptions, t]
  );
  const initialValues = React.useMemo(
    () => ({ label: "", color: "", position: POSITION_END }),
    []
  );
  const handleSubmit = React.useCallback(
    async (values) => {
      if (!context) return;
      const trimmedLabel = values.label.trim();
      if (!trimmedLabel.length) {
        throw createCrudFormError(labelRequiredMessage, { label: labelRequiredMessage });
      }
      const payload = {
        pipelineId: context.pipelineId,
        label: trimmedLabel
      };
      if (values.color) payload.color = values.color;
      const insertOrder = resolveInsertOrder(values.position ?? POSITION_END, context.existingStages);
      if (insertOrder !== void 0) payload.order = insertOrder;
      const operation = () => createCrud("customers/pipeline-stages", payload, {
        errorMessage: translateWithFallback(
          t,
          "customers.deals.kanban.addStage.error",
          "Failed to add stage."
        )
      });
      await runMutation({
        operation,
        context: {
          formId: ADD_STAGE_CONTEXT_ID,
          resourceKind: "customers.pipeline_stage",
          retryLastMutation
        }
      });
      flash(translateWithFallback(t, "customers.deals.kanban.addStage.success", "Stage added."), "success");
      onCreated();
      onClose();
    },
    [context, labelRequiredMessage, onClose, onCreated, retryLastMutation, runMutation, t]
  );
  if (!context) return null;
  return /* @__PURE__ */ jsx(
    Dialog,
    {
      open,
      onOpenChange: (next) => {
        if (!next) onClose();
      },
      children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-md", children: [
        /* @__PURE__ */ jsxs(DialogHeader, { children: [
          /* @__PURE__ */ jsx(DialogTitle, { children: translateWithFallback(t, "customers.deals.kanban.addStage.title", "New stage") }),
          /* @__PURE__ */ jsx(DialogDescription, { children: translateWithFallback(
            t,
            "customers.deals.kanban.addStage.context",
            "Pipeline: {pipeline}",
            { pipeline: context.pipelineName }
          ) })
        ] }),
        /* @__PURE__ */ jsx(
          CrudForm,
          {
            embedded: true,
            fields,
            initialValues,
            schema: formSchema,
            submitLabel: translateWithFallback(
              t,
              "customers.deals.kanban.addStage.submit",
              "Add stage"
            ),
            onSubmit: handleSubmit
          },
          `${context.pipelineId}:${formInstanceKey}`
        )
      ] })
    }
  );
}
var AddStageDialog_default = AddStageDialog;
export {
  AddStageDialog,
  AddStageDialog_default as default
};
//# sourceMappingURL=AddStageDialog.js.map
