"use client";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import { Button } from "../primitives/button.js";
import { ComboboxInput } from "./inputs/ComboboxInput.js";
import { TagsInput } from "./inputs/TagsInput.js";
import { useT } from "@open-mercato/shared/lib/i18n/context";
const EMPTY_FILTER_VALUES = {};
function isPlainObject(value) {
  return value != null && typeof value === "object" && !Array.isArray(value);
}
function normalizeKeys(source) {
  if (!source) return [];
  return Object.keys(source).filter((key) => source[key] !== void 0);
}
function areFieldValuesEqual(a, b) {
  if (a === b) return true;
  if (Array.isArray(a) && Array.isArray(b)) {
    if (a.length !== b.length) return false;
    for (let i = 0; i < a.length; i += 1) {
      if (!areFieldValuesEqual(a[i], b[i])) return false;
    }
    return true;
  }
  if (isPlainObject(a) && isPlainObject(b)) {
    const keysA = normalizeKeys(a);
    const keysB = normalizeKeys(b);
    if (keysA.length !== keysB.length) return false;
    for (const key of keysA) {
      if (!keysB.includes(key)) return false;
      if (!areFieldValuesEqual(a[key], b[key])) return false;
    }
    return true;
  }
  return false;
}
function areFilterValuesEqual(a, b) {
  if (a === b) return true;
  const keysA = normalizeKeys(a || EMPTY_FILTER_VALUES);
  const keysB = normalizeKeys(b || EMPTY_FILTER_VALUES);
  if (keysA.length !== keysB.length) return false;
  for (const key of keysA) {
    if (!keysB.includes(key)) return false;
    if (!areFieldValuesEqual(a?.[key], b?.[key])) return false;
  }
  return true;
}
function FilterOverlay({
  title,
  filters,
  initialValues,
  open,
  onOpenChange,
  onApply,
  onClear,
  extraContent
}) {
  const t = useT();
  const defaultTitle = title ?? t("ui.filters.title", "Filters");
  const [values, setValues] = React.useState(initialValues);
  React.useEffect(() => {
    setValues((prev) => areFilterValuesEqual(prev, initialValues) ? prev : initialValues);
  }, [initialValues]);
  const filtersSignature = React.useMemo(
    () => filters.map((f) => `${f.id}:${f.type}:${Boolean(f.loadOptions)}:${(f.options || []).length}`).join("|"),
    [filters]
  );
  const lastLoadedSignatureRef = React.useRef(null);
  const stableFilters = React.useMemo(() => filters, [filtersSignature]);
  const [dynamicOptions, setDynamicOptions] = React.useState({});
  React.useEffect(() => {
    if (!open) return;
    if (lastLoadedSignatureRef.current === filtersSignature) return;
    lastLoadedSignatureRef.current = filtersSignature;
    setDynamicOptions({});
    let cancelled = false;
    const loadAll = async () => {
      const loaders = filters.filter((f) => f.loadOptions != null).map(async (f) => {
        try {
          const opts = await f.loadOptions();
          if (!cancelled) setDynamicOptions((prev) => ({ ...prev, [f.id]: opts }));
        } catch {
        }
      });
      await Promise.all(loaders);
    };
    loadAll();
    return () => {
      cancelled = true;
    };
  }, [filters, filtersSignature, open]);
  React.useEffect(() => {
    if (!open) {
      lastLoadedSignatureRef.current = null;
    }
  }, [open]);
  const setValue = (id, v) => setValues((prev) => ({ ...prev, [id]: v }));
  const handleApply = () => {
    onApply(values);
    onOpenChange(false);
  };
  const handleClear = () => {
    setValues({});
    onClear?.();
  };
  const tagLoaders = React.useMemo(() => {
    const map = /* @__PURE__ */ new Map();
    for (const f of stableFilters) {
      if (f.type === "tags" && typeof f.loadOptions === "function") {
        const fieldId = f.id;
        const load = f.loadOptions;
        map.set(fieldId, async (q) => {
          const query = (q ?? "").trim();
          if (!query.length) return [];
          try {
            const opts = await load(query);
            setDynamicOptions((prev) => ({ ...prev, [fieldId]: opts }));
            return opts.map((o) => ({ value: o.value, label: o.label, description: o.description ?? null }));
          } catch {
            return [];
          }
        });
      }
    }
    return map;
  }, [stableFilters]);
  const comboboxLoaders = React.useMemo(() => {
    const map = /* @__PURE__ */ new Map();
    for (const f of stableFilters) {
      if (f.type === "combobox" && typeof f.loadOptions === "function") {
        map.set(f.id, async (query) => {
          try {
            const opts = await f.loadOptions?.(query);
            setDynamicOptions((prev) => ({ ...prev, [f.id]: opts ?? [] }));
            return opts ?? [];
          } catch {
            return [];
          }
        });
      }
    }
    return map;
  }, [stableFilters]);
  return /* @__PURE__ */ jsx(Fragment, { children: open && /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50", children: [
    /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black/30", onClick: () => onOpenChange(false), role: "presentation" }),
    /* @__PURE__ */ jsxs("div", { className: "absolute left-0 top-0 h-full w-full sm:w-[380px] bg-background shadow-xl border-r flex flex-col", children: [
      /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between p-4 border-b", children: [
        /* @__PURE__ */ jsx("h2", { className: "text-base font-semibold", children: defaultTitle }),
        /* @__PURE__ */ jsx(Button, { variant: "muted", size: "sm", onClick: () => onOpenChange(false), children: t("common.close") })
      ] }),
      /* @__PURE__ */ jsxs("div", { className: "px-4 py-2 border-b flex items-center justify-between gap-2", children: [
        /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: handleClear, children: t("ui.filters.actions.clear", "Clear") }),
        /* @__PURE__ */ jsxs(Button, { size: "sm", onClick: handleApply, children: [
          /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": "true", className: "opacity-80", children: [
            /* @__PURE__ */ jsx("path", { d: "M3 4h18" }),
            /* @__PURE__ */ jsx("path", { d: "M6 8h12l-3 8H9L6 8z" })
          ] }),
          t("ui.filters.actions.apply", "Apply")
        ] })
      ] }),
      /* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-auto p-4 space-y-4", children: [
        extraContent ? /* @__PURE__ */ jsx("div", { className: "space-y-2 rounded-md border bg-muted/30 p-3", children: extraContent }) : null,
        filters.map((f) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
          /* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: f.label }),
          f.type === "text" && /* @__PURE__ */ jsx(
            "input",
            {
              type: "text",
              className: "w-full h-11 rounded border px-2 text-sm",
              placeholder: f.placeholder,
              value: values[f.id] ?? "",
              onChange: (e) => setValue(f.id, e.target.value || void 0)
            }
          ),
          f.type === "dateRange" && /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-2", children: [
            /* @__PURE__ */ jsxs("div", { children: [
              /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground mb-1", children: t("ui.filters.dateRange.from", "From") }),
              /* @__PURE__ */ jsx(
                "input",
                {
                  type: "date",
                  className: "w-full h-11 rounded border px-2 text-sm",
                  value: values[f.id]?.from ?? "",
                  onChange: (e) => setValue(f.id, { ...values[f.id] ?? {}, from: e.target.value || void 0 })
                }
              )
            ] }),
            /* @__PURE__ */ jsxs("div", { children: [
              /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground mb-1", children: t("ui.filters.dateRange.to", "To") }),
              /* @__PURE__ */ jsx(
                "input",
                {
                  type: "date",
                  className: "w-full h-11 rounded border px-2 text-sm",
                  value: values[f.id]?.to ?? "",
                  onChange: (e) => setValue(f.id, { ...values[f.id] ?? {}, to: e.target.value || void 0 })
                }
              )
            ] })
          ] }),
          f.type === "select" && /* @__PURE__ */ jsx("div", { className: "space-y-1", children: f.multiple ? /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1", children: (f.options || dynamicOptions[f.id] || []).map((opt) => {
            const arr = Array.isArray(values[f.id]) ? values[f.id] : [];
            const checked = arr.includes(opt.value);
            return /* @__PURE__ */ jsxs("label", { className: "inline-flex items-center gap-2", children: [
              /* @__PURE__ */ jsx(
                "input",
                {
                  type: "checkbox",
                  checked,
                  onChange: (e) => {
                    const next = new Set(arr);
                    if (e.target.checked) next.add(opt.value);
                    else next.delete(opt.value);
                    setValue(f.id, Array.from(next));
                  }
                }
              ),
              /* @__PURE__ */ jsx("span", { className: "text-sm", children: opt.label })
            ] }, opt.value);
          }) }) : /* @__PURE__ */ jsxs(
            "select",
            {
              className: "w-full h-11 rounded border px-2 text-sm",
              value: values[f.id] ?? "",
              onChange: (e) => setValue(f.id, e.target.value || void 0),
              children: [
                /* @__PURE__ */ jsx("option", { value: "", children: t("ui.forms.select.emptyOption", "\u2014") }),
                (f.options || dynamicOptions[f.id] || []).map((opt) => /* @__PURE__ */ jsx("option", { value: opt.value, children: opt.label }, opt.value))
              ]
            }
          ) }),
          f.type === "combobox" && (() => {
            const staticOptions = f.options || [];
            const dynamic = dynamicOptions[f.id] || [];
            const optionMap = /* @__PURE__ */ new Map();
            staticOptions.forEach((opt) => optionMap.set(opt.value, opt));
            dynamic.forEach((opt) => optionMap.set(opt.value, opt));
            const currentValue = typeof values[f.id] === "string" ? values[f.id] : "";
            const suggestions = Array.from(optionMap.values()).map((opt) => ({
              value: opt.value,
              label: opt.label,
              description: opt.description ?? null
            }));
            const loadSuggestions = comboboxLoaders.get(f.id);
            return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
              /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx(
                ComboboxInput,
                {
                  value: currentValue,
                  onChange: (next) => setValue(f.id, next.trim().length ? next : void 0),
                  suggestions,
                  loadSuggestions,
                  resolveLabel: (value) => f.formatValue?.(value) ?? optionMap.get(value)?.label ?? value,
                  resolveDescription: (value) => optionMap.get(value)?.description ?? null,
                  placeholder: f.placeholder,
                  allowCustomValues: false
                }
              ) }),
              currentValue ? /* @__PURE__ */ jsx(
                Button,
                {
                  type: "button",
                  variant: "outline",
                  size: "sm",
                  className: "shrink-0",
                  onClick: () => setValue(f.id, void 0),
                  children: t("ui.filters.actions.clear", "Clear")
                }
              ) : null
            ] });
          })(),
          f.type === "tags" && (() => {
            const arr = Array.isArray(values[f.id]) ? values[f.id] : [];
            const staticOptions = f.options || [];
            const dynamic = dynamicOptions[f.id] || [];
            const optionMap = /* @__PURE__ */ new Map();
            staticOptions.forEach((opt) => optionMap.set(opt.value, opt));
            dynamic.forEach((opt) => optionMap.set(opt.value, opt));
            const loadSuggestions = tagLoaders.get(f.id);
            const resolveTagLabel = f.formatValue ? (val) => f.formatValue(val) : (val) => optionMap.get(val)?.label ?? val;
            const resolveTagDescription = f.formatDescription ? (val) => f.formatDescription(val) ?? null : (val) => optionMap.get(val)?.description ?? null;
            const suggestionList = Array.from(optionMap.values()).map((opt) => ({
              value: opt.value,
              label: opt.label,
              description: opt.description ?? null
            }));
            return /* @__PURE__ */ jsx(
              TagsInput,
              {
                value: arr,
                suggestions: suggestionList,
                loadSuggestions,
                allowCustomValues: false,
                resolveLabel: resolveTagLabel,
                resolveDescription: resolveTagDescription,
                placeholder: f.placeholder,
                onChange: (next) => setValue(f.id, next.length ? next : void 0)
              }
            );
          })(),
          f.type === "checkbox" && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
            "select",
            {
              className: "w-full h-11 rounded border px-2 text-sm",
              value: values[f.id] === true ? "true" : values[f.id] === false ? "false" : "",
              onChange: (e) => {
                const v = e.target.value;
                if (v === "") setValue(f.id, void 0);
                else if (v === "true") setValue(f.id, true);
                else if (v === "false") setValue(f.id, false);
              },
              children: [
                /* @__PURE__ */ jsx("option", { value: "", children: t("ui.forms.select.emptyOption", "\u2014") }),
                /* @__PURE__ */ jsx("option", { value: "true", children: t("common.yes", "Yes") }),
                /* @__PURE__ */ jsx("option", { value: "false", children: t("common.no", "No") })
              ]
            }
          ) })
        ] }, f.id))
      ] }),
      /* @__PURE__ */ jsxs("div", { className: "p-4 border-t flex items-center justify-between gap-2", children: [
        /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: handleClear, children: t("ui.filters.actions.clear", "Clear") }),
        /* @__PURE__ */ jsxs(Button, { onClick: handleApply, children: [
          /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": "true", className: "opacity-80", children: [
            /* @__PURE__ */ jsx("path", { d: "M3 4h18" }),
            /* @__PURE__ */ jsx("path", { d: "M6 8h12l-3 8H9L6 8z" })
          ] }),
          t("ui.filters.actions.apply", "Apply")
        ] })
      ] })
    ] })
  ] }) });
}
export {
  FilterOverlay
};
//# sourceMappingURL=FilterOverlay.js.map
