import { jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import { Pencil } from "lucide-react";
import { cn } from "../../lib/utils.js";
import { Input } from "../Input/input.js";
import { Textarea } from "../Textarea/textarea.js";
import { NumberInput } from "../NumberInput/number-input.js";
import { Select } from "../Select/select.js";
import { Combobox } from "../Combobox/combobox.js";
import { DatePicker as DatePickerWithRange } from "../DatePicker/date-picker.js";
import { TimePicker } from "../TimePicker/time-picker.js";
import { PeoplePicker } from "../PeoplePicker/people-picker.js";
import { LinkInput } from "../LinkInput/link-input.js";
import { Checkbox } from "../Checkbox/checkbox.js";
import { Button } from "../Button/button.js";
import { FieldSurfaceProvider, FieldSurfaceSizeProvider } from "../Field/field-context.js";
function makeKeyHandler(onCommit, onCancel, parseValue) {
  return (e) => {
    if (e.key === "Escape") {
      e.preventDefault();
      onCancel == null ? void 0 : onCancel();
    }
    if (e.key === "Enter") {
      e.preventDefault();
      const raw = e.target.value;
      onCommit == null ? void 0 : onCommit(raw);
    }
  };
}
const sizeForInput = (size) => size;
const displayOrDisabled = (isDisabled) => isDisabled ? "disabled" : "display";
function StringCell({ value, meta, mode, size, isDisabled, autoRowHeight, onCommit, onCancel, onDraft }) {
  const maxLines = meta == null ? void 0 : meta.maxLines;
  const clampClass = maxLines && autoRowHeight ? `line-clamp-[${maxLines}]` : void 0;
  const v = value != null ? String(value) : "";
  if (mode === "display") {
    return autoRowHeight ? /* @__PURE__ */ jsx(Textarea, { variant: "naked", mode: displayOrDisabled(isDisabled), value: v, size, className: clampClass }) : /* @__PURE__ */ jsx(Input, { variant: "naked", mode: displayOrDisabled(isDisabled), value: v, size });
  }
  if (autoRowHeight) {
    const newlineRows = (v.match(/\n/g) || []).length + 1;
    const wrapRows = Math.ceil(v.length / 40);
    const estimateRows = Math.min(10, Math.max(1, newlineRows, wrapRows));
    return /* @__PURE__ */ jsx(
      Textarea,
      {
        autoFocus: true,
        variant: "naked",
        size: sizeForInput(size),
        rows: estimateRows,
        defaultValue: v,
        style: { fieldSizing: "content" },
        onChange: (e) => onDraft == null ? void 0 : onDraft(e.target.value),
        onBlur: (e) => onCommit == null ? void 0 : onCommit(e.target.value),
        onKeyDown: (e) => {
          if (e.key === "Escape") {
            e.preventDefault();
            onCancel == null ? void 0 : onCancel();
          }
          if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
            e.preventDefault();
            onCommit == null ? void 0 : onCommit(e.target.value);
          }
        }
      }
    );
  }
  return /* @__PURE__ */ jsx(
    Input,
    {
      autoFocus: true,
      variant: "naked",
      size: sizeForInput(size),
      defaultValue: v,
      onChange: (e) => onDraft == null ? void 0 : onDraft(e.target.value),
      onBlur: (e) => onCommit == null ? void 0 : onCommit(e.target.value),
      onKeyDown: makeKeyHandler(onCommit, onCancel)
    }
  );
}
function NumberCell({ value, meta, mode, size, isDisabled, onCommit, onCancel, onDraft }) {
  const isCurrency = (meta == null ? void 0 : meta.type) === "currency";
  const prefix = isCurrency ? (meta == null ? void 0 : meta.prefix) ?? "$" : meta == null ? void 0 : meta.prefix;
  if (mode === "display") {
    return /* @__PURE__ */ jsx(
      NumberInput,
      {
        variant: "naked",
        mode: displayOrDisabled(isDisabled),
        value,
        size,
        prefix,
        suffix: meta == null ? void 0 : meta.suffix,
        precision: meta == null ? void 0 : meta.precision,
        locale: meta == null ? void 0 : meta.locale
      }
    );
  }
  const initial = typeof value === "number" ? value : null;
  const [localValue, setLocalValue] = React.useState(initial);
  return /* @__PURE__ */ jsx(
    NumberInput,
    {
      autoFocus: true,
      variant: "naked",
      size: sizeForInput(size),
      value: localValue,
      onChange: (v) => {
        setLocalValue(v);
        onDraft == null ? void 0 : onDraft(v);
      },
      prefix,
      suffix: meta == null ? void 0 : meta.suffix,
      precision: meta == null ? void 0 : meta.precision,
      onBlur: () => onCommit == null ? void 0 : onCommit(localValue),
      onKeyDown: (e) => {
        if (e.key === "Escape") {
          e.preventDefault();
          onCancel == null ? void 0 : onCancel();
        }
        if (e.key === "Enter") {
          e.preventDefault();
          onCommit == null ? void 0 : onCommit(localValue);
        }
      }
    }
  );
}
const dismissOnClose = (onCancel) => (open) => {
  if (!open) onCancel == null ? void 0 : onCancel();
};
function DateCell({ value, meta, mode, size, isDisabled, isEditable, onCommit, onCancel }) {
  if (mode === "display") {
    return /* @__PURE__ */ jsx(
      DatePickerWithRange,
      {
        variant: "naked",
        mode: displayOrDisabled(isDisabled),
        value,
        size,
        formatOptions: meta == null ? void 0 : meta.formatOptions,
        locale: meta == null ? void 0 : meta.locale,
        showDisplayEndIcon: isEditable === true
      },
      "display"
    );
  }
  return /* @__PURE__ */ jsx(
    DatePickerWithRange,
    {
      autoFocus: true,
      variant: "naked",
      size: sizeForInput(size),
      value: typeof value === "string" ? value : null,
      showTime: (meta == null ? void 0 : meta.includeTime) === true,
      onChange: (v) => onCommit == null ? void 0 : onCommit(v),
      defaultOpen: true,
      onOpenChange: dismissOnClose(onCancel)
    },
    "edit"
  );
}
function TimeCell({ value, meta, mode, size, isDisabled, isEditable, onCommit, onCancel }) {
  if (mode === "display") {
    return /* @__PURE__ */ jsx(
      TimePicker,
      {
        variant: "naked",
        mode: displayOrDisabled(isDisabled),
        value,
        size,
        formatOptions: meta == null ? void 0 : meta.formatOptions,
        locale: meta == null ? void 0 : meta.locale,
        showDisplayEndIcon: isEditable === true
      },
      "display"
    );
  }
  return /* @__PURE__ */ jsx(
    TimePicker,
    {
      variant: "naked",
      size: sizeForInput(size),
      value: typeof value === "string" ? value : null,
      showSeconds: (meta == null ? void 0 : meta.showSeconds) === true,
      minuteStep: meta == null ? void 0 : meta.minuteStep,
      secondStep: meta == null ? void 0 : meta.secondStep,
      onChange: (v) => onCommit == null ? void 0 : onCommit(v),
      defaultOpen: true,
      onOpenChange: dismissOnClose(onCancel)
    },
    "edit"
  );
}
function SelectCell({ value, meta, mode, size, isDisabled, isEditable, onCommit, onCancel }) {
  const displayMode = (meta == null ? void 0 : meta.display) ?? "plain";
  if (mode === "display") {
    return /* @__PURE__ */ jsx(
      Select,
      {
        variant: "naked",
        mode: displayOrDisabled(isDisabled),
        value,
        options: (meta == null ? void 0 : meta.options) ?? [],
        size,
        display: displayMode,
        showDisplayEndIcon: isEditable === true
      },
      "display"
    );
  }
  return /* @__PURE__ */ jsx(
    Select,
    {
      autoFocus: true,
      variant: "naked",
      size: sizeForInput(size),
      options: (meta == null ? void 0 : meta.options) ?? [],
      value,
      onChange: (v) => onCommit == null ? void 0 : onCommit(v),
      searchable: (meta == null ? void 0 : meta.searchable) === true,
      display: displayMode,
      defaultOpen: true,
      onOpenChange: dismissOnClose(onCancel)
    },
    "edit"
  );
}
function MultiSelectCell({ value, meta, mode, size, isDisabled, autoRowHeight, isEditable, onCommitLive, onCancel }) {
  const wrap = autoRowHeight && (meta == null ? void 0 : meta.wrap) === true;
  if (mode === "display") {
    return /* @__PURE__ */ jsx(
      Combobox,
      {
        variant: "naked",
        mode: displayOrDisabled(isDisabled),
        value: value ?? [],
        options: (meta == null ? void 0 : meta.options) ?? [],
        wrap,
        size,
        showDisplayEndIcon: isEditable === true
      },
      "display"
    );
  }
  return /* @__PURE__ */ jsx(
    Combobox,
    {
      variant: "naked",
      size: sizeForInput(size),
      options: (meta == null ? void 0 : meta.options) ?? [],
      value: Array.isArray(value) ? value : [],
      onChange: (v) => onCommitLive == null ? void 0 : onCommitLive(v),
      defaultOpen: true,
      onOpenChange: dismissOnClose(onCancel)
    },
    "edit"
  );
}
function PersonCell({ value, mode, size, isDisabled, isEditable, onCommit, onCancel, meta }) {
  if (mode === "display") {
    return /* @__PURE__ */ jsx(PeoplePicker, { variant: "naked", mode: displayOrDisabled(isDisabled), value, size, showDisplayEndIcon: isEditable === true }, "display");
  }
  return /* @__PURE__ */ jsx(
    PeoplePicker,
    {
      variant: "naked",
      size: sizeForInput(size),
      value,
      people: (meta == null ? void 0 : meta.people) ?? [],
      onChange: (next) => onCommit == null ? void 0 : onCommit(next[0] ?? null),
      defaultOpen: true,
      onOpenChange: dismissOnClose(onCancel)
    },
    "edit"
  );
}
function MultiPersonCell({ value, mode, size, isDisabled, isEditable, onCommitLive, onCancel, meta }) {
  if (mode === "display") {
    return /* @__PURE__ */ jsx(PeoplePicker, { variant: "naked", mode: displayOrDisabled(isDisabled), value: value ?? [], size, showDisplayEndIcon: isEditable === true }, "display");
  }
  return /* @__PURE__ */ jsx(
    PeoplePicker,
    {
      variant: "naked",
      size: sizeForInput(size),
      value: Array.isArray(value) ? value : [],
      people: (meta == null ? void 0 : meta.people) ?? [],
      onChange: (next) => onCommitLive == null ? void 0 : onCommitLive(next),
      defaultOpen: true,
      onOpenChange: dismissOnClose(onCancel)
    },
    "edit"
  );
}
function BooleanCell({ value, mode, meta, size, isEditable, isDisabled, onCommit }) {
  if (mode === "display" && (!isEditable || isDisabled)) {
    return /* @__PURE__ */ jsx(Checkbox, { variant: "naked", mode: displayOrDisabled(isDisabled), checked: value === true });
  }
  return /* @__PURE__ */ jsx(
    Checkbox,
    {
      size: size === "lg" ? "lg" : "md",
      checked: value === true,
      onCheckedChange: (checked) => onCommit == null ? void 0 : onCommit(checked === true),
      "aria-label": (meta == null ? void 0 : meta.ariaLabel) ?? "切換"
    }
  );
}
function UrlCell({ value, meta, mode, size, isDisabled, isEditable, onRequestEdit, onCommit, onCancel }) {
  if (mode === "display") {
    const display = /* @__PURE__ */ jsx(LinkInput, { variant: "naked", mode: displayOrDisabled(isDisabled), value, label: meta == null ? void 0 : meta.linkLabel, size, showDisplayEndIcon: true });
    if (!isEditable || isDisabled) return display;
    return /* @__PURE__ */ jsxs("span", { className: "group/cell relative flex items-center w-full", children: [
      " ",
      /* @__PURE__ */ jsx("span", { className: "flex-1 min-w-0", children: display }),
      /* @__PURE__ */ jsx(
        Button,
        {
          variant: "tertiary",
          size: "xs",
          iconOnly: true,
          startIcon: Pencil,
          "aria-label": "編輯連結",
          className: cn("ml-1 opacity-0 group-hover/cell:opacity-100 transition-opacity"),
          onClick: (e) => {
            e.stopPropagation();
            onRequestEdit == null ? void 0 : onRequestEdit();
          }
        }
      )
    ] });
  }
  return /* @__PURE__ */ jsx(
    Input,
    {
      autoFocus: true,
      variant: "naked",
      size: sizeForInput(size),
      defaultValue: value != null ? String(value) : "",
      onBlur: (e) => onCommit == null ? void 0 : onCommit(e.target.value),
      onKeyDown: makeKeyHandler(onCommit, onCancel)
    }
  );
}
const cellRegistry = {
  string: StringCell,
  number: NumberCell,
  currency: NumberCell,
  // 共用 NumberCell — currency-ness 走 meta.type 判 prefix='$'
  date: DateCell,
  time: TimeCell,
  select: SelectCell,
  multiSelect: MultiSelectCell,
  person: PersonCell,
  multiPerson: MultiPersonCell,
  boolean: BooleanCell,
  url: UrlCell
};
const cellWithSurfaceCache = /* @__PURE__ */ new Map();
function buildCellWithSurface(Inner, key) {
  const CellWithSurface = React.memo(function CellWithSurface2(props) {
    return /* @__PURE__ */ jsx(FieldSurfaceProvider, { surface: "table-cell", children: /* @__PURE__ */ jsx(FieldSurfaceSizeProvider, { size: props.size, children: /* @__PURE__ */ jsx(Inner, { ...props }) }) });
  });
  CellWithSurface.displayName = `CellWithSurface(${key})`;
  return CellWithSurface;
}
for (const type of Object.keys(cellRegistry)) {
  cellWithSurfaceCache.set(type, buildCellWithSurface(cellRegistry[type], type));
}
cellWithSurfaceCache.set("_default_", buildCellWithSurface(StringCell, "StringCell-fallback"));
function resolveCellComponent(type) {
  return cellWithSurfaceCache.get(type ?? "_default_") ?? cellWithSurfaceCache.get("_default_");
}
export {
  cellRegistry,
  resolveCellComponent
};
//# sourceMappingURL=cell-registry.js.map
