"use client";
import { jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import { Building2, X } from "lucide-react";
import { Avatar } from "@open-mercato/ui/primitives/avatar";
import { Button } from "@open-mercato/ui/primitives/button";
import { IconButton } from "@open-mercato/ui/primitives/icon-button";
import { SearchInput } from "@open-mercato/ui/primitives/search-input";
import { useDealAssociationLookups } from "../DealForm.js";
function sanitizeIdList(input) {
  if (!Array.isArray(input)) return [];
  const set = /* @__PURE__ */ new Set();
  input.forEach((candidate) => {
    if (typeof candidate !== "string") return;
    const trimmed = candidate.trim();
    if (!trimmed.length) return;
    set.add(trimmed);
  });
  return Array.from(set);
}
function DealAssociationsField({
  id,
  kind,
  value,
  onChange,
  disabled = false,
  labels
}) {
  const lookups = useDealAssociationLookups();
  const search = kind === "people" ? lookups.searchPeople : lookups.searchCompanies;
  const fetchByIds = kind === "people" ? lookups.fetchPeopleByIds : lookups.fetchCompaniesByIds;
  const [input, setInput] = React.useState("");
  const [suggestions, setSuggestions] = React.useState([]);
  const [cache, setCache] = React.useState(() => /* @__PURE__ */ new Map());
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState(null);
  const normalizedValue = React.useMemo(() => sanitizeIdList(value), [value]);
  React.useEffect(() => {
    if (!normalizedValue.length) return;
    const missing = normalizedValue.filter((id2) => !cache.has(id2));
    if (!missing.length) return;
    let cancelled = false;
    (async () => {
      try {
        const entries = await fetchByIds(missing);
        if (cancelled) return;
        setCache((prev) => {
          const next = new Map(prev);
          entries.forEach((entry) => {
            if (entry?.id) next.set(entry.id, entry);
          });
          return next;
        });
      } catch {
        if (!cancelled) setError(labels.error);
      }
    })().catch(() => {
    });
    return () => {
      cancelled = true;
    };
  }, [cache, fetchByIds, labels.error, normalizedValue]);
  React.useEffect(() => {
    const query = input.trim();
    if (disabled || query.length === 0) {
      setLoading(false);
      setSuggestions([]);
      return;
    }
    let cancelled = false;
    const handler = window.setTimeout(async () => {
      setLoading(true);
      try {
        const results = await search(query);
        if (cancelled) return;
        setSuggestions(results);
        setCache((prev) => {
          const next = new Map(prev);
          results.forEach((entry) => {
            if (entry?.id) next.set(entry.id, entry);
          });
          return next;
        });
        setError(null);
      } catch {
        if (!cancelled) {
          setError(labels.error);
          setSuggestions([]);
        }
      } finally {
        if (!cancelled) setLoading(false);
      }
    }, 200);
    return () => {
      cancelled = true;
      window.clearTimeout(handler);
    };
  }, [disabled, input, labels.error, search]);
  const filteredSuggestions = React.useMemo(
    () => suggestions.filter((option) => !normalizedValue.includes(option.id)),
    [normalizedValue, suggestions]
  );
  const selectedOptions = React.useMemo(
    () => normalizedValue.map((id2) => cache.get(id2) ?? { id: id2, label: id2 }),
    [cache, normalizedValue]
  );
  const addOption = React.useCallback(
    (option) => {
      if (!option?.id) return;
      if (normalizedValue.includes(option.id)) return;
      onChange([...normalizedValue, option.id]);
      setCache((prev) => {
        const next = new Map(prev);
        next.set(option.id, option);
        return next;
      });
      setInput("");
      setSuggestions([]);
    },
    [normalizedValue, onChange]
  );
  const removeOption = React.useCallback(
    (id2) => {
      onChange(normalizedValue.filter((candidate) => candidate !== id2));
    },
    [normalizedValue, onChange]
  );
  const renderLeading = React.useCallback(
    (option) => kind === "people" ? /* @__PURE__ */ jsx(Avatar, { label: option.label, size: "xs" }) : /* @__PURE__ */ jsx(Building2, { className: "size-3.5 text-muted-foreground", "aria-hidden": "true" }),
    [kind]
  );
  return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
    /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 rounded-md border border-input bg-background p-2", children: [
      selectedOptions.length ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: selectedOptions.map((option) => /* @__PURE__ */ jsxs(
        "span",
        {
          className: "inline-flex items-center gap-1.5 rounded-md bg-muted px-2 py-1 text-xs text-foreground",
          children: [
            renderLeading(option),
            /* @__PURE__ */ jsx("span", { className: "truncate", children: option.label }),
            /* @__PURE__ */ jsx(
              IconButton,
              {
                type: "button",
                variant: "ghost",
                size: "xs",
                "aria-label": `${labels.remove} ${option.label}`,
                onClick: () => removeOption(option.id),
                disabled,
                children: /* @__PURE__ */ jsx(X, { className: "size-3" })
              }
            )
          ]
        },
        option.id
      )) }) : null,
      /* @__PURE__ */ jsx(
        SearchInput,
        {
          id,
          size: "default",
          value: input,
          onChange: setInput,
          placeholder: labels.placeholder,
          disabled,
          onKeyDown: (event) => {
            if (event.key === "Enter") {
              event.preventDefault();
              const nextOption = filteredSuggestions[0];
              if (nextOption) addOption(nextOption);
            } else if (event.key === "Backspace" && !input.length && normalizedValue.length) {
              removeOption(normalizedValue[normalizedValue.length - 1]);
            }
          }
        }
      )
    ] }),
    loading ? /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: labels.loading }) : null,
    !loading && input.trim().length > 0 && filteredSuggestions.length ? /* @__PURE__ */ jsx("div", { className: "flex max-h-72 flex-col gap-1 overflow-y-auto rounded-md border border-border bg-popover p-1 shadow-md", children: filteredSuggestions.slice(0, 8).map((option) => /* @__PURE__ */ jsxs(
      Button,
      {
        type: "button",
        variant: "ghost",
        size: "sm",
        className: "h-auto justify-start px-2 py-1 text-left font-normal",
        onMouseDown: (event) => event.preventDefault(),
        onClick: () => addOption(option),
        disabled,
        "aria-label": option.label,
        children: [
          renderLeading(option),
          /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-col items-start", children: [
            /* @__PURE__ */ jsx("span", { className: "truncate text-sm", children: option.label }),
            option.subtitle ? /* @__PURE__ */ jsx("span", { className: "truncate text-xs text-muted-foreground", children: option.subtitle }) : null
          ] })
        ]
      },
      option.id
    )) }) : null,
    !loading && input.trim().length > 0 && !filteredSuggestions.length ? /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: labels.noResults }) : null,
    error ? /* @__PURE__ */ jsx("div", { className: "text-xs text-status-error-text", children: error }) : null
  ] });
}
var DealAssociationsField_default = DealAssociationsField;
export {
  DealAssociationsField,
  DealAssociationsField_default as default
};
//# sourceMappingURL=DealAssociationsField.js.map
