"use client";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import * as React from "react";
import { Loader2, Pencil, Plus, Trash2, X } from "lucide-react";
import { Button } from "@open-mercato/ui/primitives/button";
import { flash } from "@open-mercato/ui/backend/FlashMessages";
import { TabEmptyState } from "@open-mercato/ui/backend/detail";
import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
import { useOrganizationScopeVersion } from "@open-mercato/shared/lib/frontend/useOrganizationScope";
import { AddressView, formatAddressJson, formatAddressString } from "../utils/addressFormat.js";
import { normalizeCoordinateInput, validateCoordinateInput } from "@open-mercato/shared/lib/location/coordinates";
import AddressEditor from "./AddressEditor.js";
import { useAddressTypes } from "./detail/hooks/useAddressTypes.js";
import { useQueryClient } from "@tanstack/react-query";
const defaultDraft = {
  name: "",
  purpose: "",
  companyName: "",
  addressLine1: "",
  addressLine2: "",
  buildingNumber: "",
  flatNumber: "",
  city: "",
  region: "",
  postalCode: "",
  country: "",
  latitude: "",
  longitude: "",
  isPrimary: false
};
const serverFieldMap = {
  name: "name",
  purpose: "purpose",
  companyName: "companyName",
  addressLine1: "addressLine1",
  addressLine2: "addressLine2",
  buildingNumber: "buildingNumber",
  flatNumber: "flatNumber",
  city: "city",
  region: "region",
  postalCode: "postalCode",
  country: "country",
  latitude: "latitude",
  longitude: "longitude",
  isPrimary: "isPrimary"
};
function normalizeOptional(value) {
  const trimmed = value.trim();
  return trimmed.length ? trimmed : void 0;
}
function extractValidationDetails(error) {
  if (!error || typeof error !== "object") return [];
  const candidate = error.details;
  if (!Array.isArray(candidate)) return [];
  return candidate.map((entry) => entry && typeof entry === "object" ? entry : null).filter((entry) => entry !== null);
}
function resolveFieldMessage(detail, fieldLabel, t) {
  switch (detail.code) {
    case "invalid_type":
      return t("customers.people.detail.addresses.validation.invalid", void 0, { field: fieldLabel });
    case "too_small":
      if (detail.minimum === 1 && detail.type === "string") {
        return t("customers.people.detail.addresses.validation.required", void 0, { field: fieldLabel });
      }
      return t("customers.people.detail.addresses.validation.generic", void 0, { field: fieldLabel });
    case "too_big":
      if (typeof detail.maximum === "number") {
        return t(
          "customers.people.detail.addresses.validation.tooLong",
          void 0,
          {
            field: fieldLabel,
            max: detail.maximum
          }
        );
      }
      return t("customers.people.detail.addresses.validation.generic", void 0, { field: fieldLabel });
    default:
      return t("customers.people.detail.addresses.validation.generic", void 0, { field: fieldLabel });
  }
}
function CustomerAddressTiles({
  addresses,
  onCreate,
  onUpdate,
  onDelete,
  t,
  emptyLabel,
  isSubmitting = false,
  gridClassName = "grid gap-4 min-[480px]:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4",
  hideAddButton = false,
  onAddActionChange,
  emptyStateTitle,
  emptyStateActionLabel,
  showCoordinateFields = false
}) {
  const scopeVersion = useOrganizationScopeVersion();
  const queryClient = useQueryClient();
  const [isFormOpen, setIsFormOpen] = React.useState(false);
  const [editingId, setEditingId] = React.useState(null);
  const [draft, setDraft] = React.useState(defaultDraft);
  const [saving, setSaving] = React.useState(false);
  const [deletingId, setDeletingId] = React.useState(null);
  const [generalError, setGeneralError] = React.useState(null);
  const [fieldErrors, setFieldErrors] = React.useState({});
  const [format, setFormat] = React.useState("line_first");
  const [formatLoading, setFormatLoading] = React.useState(false);
  const { map: addressTypeMap } = useAddressTypes(t);
  const fieldLabels = React.useMemo(
    () => ({
      name: t("customers.people.detail.addresses.fields.label"),
      purpose: t("customers.people.detail.addresses.fields.type"),
      companyName: t("customers.people.detail.addresses.fields.companyName", "Company name"),
      addressLine1: t("customers.people.detail.addresses.fields.line1"),
      addressLine2: t("customers.people.detail.addresses.fields.line2"),
      street: t("customers.people.detail.addresses.fields.street", "Street"),
      buildingNumber: t("customers.people.detail.addresses.fields.buildingNumber", "Building number"),
      flatNumber: t("customers.people.detail.addresses.fields.flatNumber", "Flat number"),
      city: t("customers.people.detail.addresses.fields.city"),
      region: t("customers.people.detail.addresses.fields.region"),
      postalCode: t("customers.people.detail.addresses.fields.postalCode"),
      country: t("customers.people.detail.addresses.fields.country"),
      latitude: t("customers.people.detail.addresses.fields.latitude", "Latitude"),
      longitude: t("customers.people.detail.addresses.fields.longitude", "Longitude"),
      isPrimary: t("customers.people.detail.addresses.fields.primary")
    }),
    [t]
  );
  const line1FieldLabel = React.useMemo(
    () => format === "street_first" ? fieldLabels.street : fieldLabels.addressLine1,
    [fieldLabels.addressLine1, fieldLabels.street, format]
  );
  const resetForm = React.useCallback(() => {
    setDraft(defaultDraft);
    setFieldErrors({});
    setGeneralError(null);
    setEditingId(null);
  }, []);
  React.useEffect(() => {
    let cancelled = false;
    async function loadFormat() {
      setFormatLoading(true);
      try {
        const call = await apiCall(
          "/api/customers/settings/address-format"
        );
        const payload = call.result ?? {};
        if (!call.ok) {
          if (!cancelled) {
            const message = typeof payload?.error === "string" ? payload.error : t("customers.people.detail.addresses.formatLoadError", "Failed to load address configuration");
            flash(message, "error");
          }
          return;
        }
        const valueRaw = payload?.addressFormat;
        const value = typeof valueRaw === "string" ? valueRaw : null;
        if (!cancelled && (value === "street_first" || value === "line_first")) {
          setFormat(value);
        }
      } catch (err) {
        if (!cancelled) {
          const message = err instanceof Error && err.message ? err.message : t("customers.people.detail.addresses.formatLoadError", "Failed to load address configuration");
          flash(message, "error");
        }
      } finally {
        if (!cancelled) setFormatLoading(false);
      }
    }
    loadFormat().catch(() => {
    });
    return () => {
      cancelled = true;
    };
  }, [scopeVersion, t]);
  const openCreateForm = React.useCallback(() => {
    resetForm();
    setIsFormOpen(true);
  }, [resetForm]);
  const openEditForm = React.useCallback(
    (address) => {
      setDraft({
        name: address.name ?? "",
        purpose: address.purpose ?? "",
        companyName: address.companyName ?? "",
        addressLine1: address.addressLine1,
        addressLine2: address.addressLine2 ?? "",
        buildingNumber: address.buildingNumber ?? "",
        flatNumber: address.flatNumber ?? "",
        city: address.city ?? "",
        region: address.region ?? "",
        postalCode: address.postalCode ?? "",
        country: address.country ? address.country.toUpperCase() : "",
        latitude: address.latitude != null ? String(address.latitude) : "",
        longitude: address.longitude != null ? String(address.longitude) : "",
        isPrimary: address.isPrimary ?? false
      });
      setFieldErrors({});
      setGeneralError(null);
      setEditingId(address.id);
      setIsFormOpen(true);
    },
    []
  );
  const handleCancel = React.useCallback(() => {
    setIsFormOpen(false);
    resetForm();
  }, [resetForm]);
  const handleSave = React.useCallback(async () => {
    const trimmedLine1 = draft.addressLine1.trim();
    if (!trimmedLine1.length) {
      const message = t(
        "customers.people.detail.addresses.validation.required",
        void 0,
        { field: line1FieldLabel }
      );
      setFieldErrors((prev) => ({ ...prev, addressLine1: message }));
      setGeneralError(message);
      return;
    }
    const coordinateErrors = {};
    for (const key of ["latitude", "longitude"]) {
      const result = validateCoordinateInput(key, draft[key]);
      if (result.status === "invalid") {
        coordinateErrors[key] = t(
          "customers.people.detail.addresses.validation.invalid",
          void 0,
          { field: fieldLabels[key] }
        );
      } else if (result.status === "outOfRange") {
        coordinateErrors[key] = t(
          "customers.people.detail.addresses.validation.coordinateRange",
          void 0,
          { field: fieldLabels[key], min: result.min, max: result.max }
        );
      }
    }
    if (Object.keys(coordinateErrors).length) {
      setFieldErrors((prev) => ({ ...prev, ...coordinateErrors }));
      setGeneralError(Object.values(coordinateErrors)[0] ?? null);
      return;
    }
    const payload = {
      addressLine1: trimmedLine1,
      isPrimary: draft.isPrimary
    };
    const purpose = normalizeOptional(draft.purpose);
    if (purpose !== void 0) payload.purpose = purpose;
    const name = normalizeOptional(draft.name);
    if (name !== void 0) payload.name = name;
    const companyName = normalizeOptional(draft.companyName);
    if (companyName !== void 0) payload.companyName = companyName;
    const line2 = normalizeOptional(draft.addressLine2);
    if (line2 !== void 0) payload.addressLine2 = line2;
    const buildingNumber = normalizeOptional(draft.buildingNumber);
    if (buildingNumber !== void 0) payload.buildingNumber = buildingNumber;
    const flatNumber = normalizeOptional(draft.flatNumber);
    if (flatNumber !== void 0) payload.flatNumber = flatNumber;
    const city = normalizeOptional(draft.city);
    if (city !== void 0) payload.city = city;
    const region = normalizeOptional(draft.region);
    if (region !== void 0) payload.region = region;
    const postal = normalizeOptional(draft.postalCode);
    if (postal !== void 0) payload.postalCode = postal;
    const country = normalizeOptional(draft.country);
    if (country !== void 0) payload.country = country.toUpperCase();
    const latitude = normalizeCoordinateInput(draft.latitude);
    if (latitude !== void 0) payload.latitude = latitude;
    else if (editingId) payload.latitude = null;
    const longitude = normalizeCoordinateInput(draft.longitude);
    if (longitude !== void 0) payload.longitude = longitude;
    else if (editingId) payload.longitude = null;
    setSaving(true);
    setGeneralError(null);
    setFieldErrors({});
    try {
      if (editingId && onUpdate) await onUpdate(editingId, payload);
      else await onCreate(payload);
      resetForm();
      setIsFormOpen(false);
    } catch (err) {
      const details = extractValidationDetails(err);
      if (details.length) {
        const nextErrors = {};
        for (const detail of details) {
          const path = Array.isArray(detail.path) ? detail.path : [];
          const targetKey = path.length ? serverFieldMap[String(path[0])] : void 0;
          if (!targetKey) continue;
          const message2 = resolveFieldMessage(
            detail,
            targetKey === "addressLine1" ? line1FieldLabel : fieldLabels[targetKey],
            t
          );
          if (message2) nextErrors[targetKey] = message2;
        }
        if (Object.keys(nextErrors).length) {
          setFieldErrors(nextErrors);
          setGeneralError(Object.values(nextErrors)[0] ?? null);
          setSaving(false);
          return;
        }
      }
      const message = err instanceof Error && err.message ? err.message : t("customers.people.detail.addresses.error");
      setGeneralError(message);
      flash(message, "error");
    } finally {
      setSaving(false);
    }
  }, [draft, editingId, fieldLabels, line1FieldLabel, onCreate, onUpdate, resetForm, t]);
  const handleDelete = React.useCallback(
    async (id) => {
      if (!onDelete) return;
      setDeletingId(id);
      try {
        await onDelete(id);
        if (editingId === id) {
          resetForm();
          setIsFormOpen(false);
        }
      } catch (err) {
        const message = err instanceof Error && err.message ? err.message : t("customers.people.detail.addresses.error");
        flash(message, "error");
      } finally {
        setDeletingId(null);
      }
    },
    [editingId, onDelete, resetForm, t]
  );
  const disableActions = saving || isSubmitting || deletingId !== null;
  const isEditing = editingId !== null;
  const addDisabled = disableActions || isEditing;
  const hasAddresses = addresses.length > 0;
  const emptyTitle = emptyStateTitle ?? emptyLabel;
  const emptyActionLabel = emptyStateActionLabel ?? t("customers.people.detail.addresses.add");
  React.useEffect(() => {
    if (!onAddActionChange) return;
    onAddActionChange({ openCreateForm, addDisabled });
  }, [onAddActionChange, openCreateForm, addDisabled]);
  React.useEffect(
    () => () => {
      if (onAddActionChange) onAddActionChange(null);
    },
    [onAddActionChange]
  );
  const renderFormTile = React.useCallback(
    (key) => /* @__PURE__ */ jsxs(
      "div",
      {
        className: "rounded-lg border-2 border-dashed border-muted-foreground/50 bg-muted/30 p-4 text-sm",
        onKeyDown: (event) => {
          if (!(event.metaKey || event.ctrlKey)) return;
          if (event.key !== "Enter") return;
          event.preventDefault();
          if (disableActions) return;
          void handleSave();
        },
        children: [
          /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: [
            /* @__PURE__ */ jsx("span", { children: editingId ? t("customers.people.detail.addresses.editTitle") : t("customers.people.detail.addresses.addTitle") }),
            /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: handleCancel, disabled: disableActions, children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" }) })
          ] }),
          /* @__PURE__ */ jsxs("div", { className: "mt-3 space-y-3", children: [
            formatLoading ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("customers.people.detail.addresses.formatLoading", "Loading address preferences\u2026") }) : null,
            /* @__PURE__ */ jsx(
              AddressEditor,
              {
                value: draft,
                onChange: (next) => {
                  setDraft({ ...next, latitude: next.latitude ?? "", longitude: next.longitude ?? "" });
                  if (Object.keys(fieldErrors).length) {
                    const nextErrors = { ...fieldErrors };
                    Object.keys(nextErrors).forEach((key2) => {
                      const candidate = next[key2];
                      if (candidate !== void 0 && candidate !== null && `${candidate}`.length) {
                        delete nextErrors[key2];
                      }
                    });
                    setFieldErrors(nextErrors);
                  }
                },
                format,
                t,
                disabled: disableActions,
                errors: fieldErrors,
                showFormatHint: !formatLoading,
                showCoordinateFields
              }
            ),
            generalError ? /* @__PURE__ */ jsx("p", { className: "text-xs text-status-error-text", children: generalError }) : null,
            /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap justify-end gap-2", children: [
              /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", onClick: handleCancel, disabled: disableActions, children: t("customers.people.detail.addresses.cancel") }),
              /* @__PURE__ */ jsx(Button, { type: "button", onClick: handleSave, disabled: disableActions, children: saving ? /* @__PURE__ */ jsxs(Fragment, { children: [
                /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
                editingId ? t("customers.people.detail.addresses.updating") : t("customers.people.detail.addresses.saving")
              ] }) : editingId ? t("customers.people.detail.addresses.update") : t("customers.people.detail.addresses.save") })
            ] })
          ] })
        ]
      },
      key
    ),
    [
      disableActions,
      draft,
      editingId,
      fieldErrors,
      format,
      formatLoading,
      handleCancel,
      handleSave,
      generalError,
      saving,
      showCoordinateFields,
      t
    ]
  );
  return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
    !hideAddButton && hasAddresses ? /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs(
      Button,
      {
        type: "button",
        variant: "outline",
        size: "sm",
        onClick: openCreateForm,
        disabled: addDisabled,
        children: [
          /* @__PURE__ */ jsx(Plus, { className: "mr-2 h-4 w-4" }),
          t("customers.people.detail.addresses.add")
        ]
      }
    ) }) : null,
    hasAddresses ? /* @__PURE__ */ jsxs("div", { className: gridClassName, children: [
      addresses.map((address) => {
        if (isFormOpen && editingId === address.id) {
          return renderFormTile(address.id);
        }
        const formattedJson = formatAddressJson(address, format);
        const formattedString = formatAddressString(address, format);
        return /* @__PURE__ */ jsxs(
          "div",
          {
            className: "rounded-lg border bg-background p-4 text-sm shadow-sm",
            title: formattedString,
            "data-address-json": JSON.stringify(formattedJson),
            "data-address-string": formattedString,
            children: [
              /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-2", children: [
                /* @__PURE__ */ jsxs("div", { children: [
                  /* @__PURE__ */ jsx("span", { className: "text-xs uppercase tracking-wide text-muted-foreground", children: address.name || (address.purpose ? addressTypeMap.get(address.purpose) ?? address.purpose : null) || t("customers.people.detail.address") }),
                  address.isPrimary ? /* @__PURE__ */ jsx("span", { className: "mt-1 inline-flex w-fit rounded bg-status-success-bg px-2 py-0.5 text-overline font-semibold text-status-success-text", children: t("customers.people.detail.primary") }) : null
                ] }),
                /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
                  /* @__PURE__ */ jsx(
                    Button,
                    {
                      type: "button",
                      variant: "ghost",
                      size: "icon",
                      className: "h-8 w-8",
                      onClick: () => openEditForm(address),
                      disabled: disableActions,
                      "aria-label": t("customers.people.detail.addresses.editAction"),
                      children: /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" })
                    }
                  ),
                  /* @__PURE__ */ jsx(
                    Button,
                    {
                      type: "button",
                      variant: "ghost",
                      size: "icon",
                      className: "h-8 w-8 text-destructive hover:text-destructive focus-visible:text-destructive",
                      onClick: () => handleDelete(address.id),
                      disabled: disableActions || !onDelete,
                      "aria-label": t("customers.people.detail.addresses.deleteAction"),
                      children: deletingId === address.id ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4" })
                    }
                  )
                ] })
              ] }),
              /* @__PURE__ */ jsxs("div", { className: "mt-2 space-y-1", children: [
                address.purpose ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: addressTypeMap.get(address.purpose) ?? address.purpose }) : null,
                /* @__PURE__ */ jsx(AddressView, { address, format, className: "space-y-1", lineClassName: "text-sm" })
              ] })
            ]
          },
          address.id
        );
      }),
      isFormOpen && !editingId ? renderFormTile("__new") : null
    ] }) : isFormOpen && !editingId ? /* @__PURE__ */ jsx("div", { className: gridClassName, children: renderFormTile("__new") }) : /* @__PURE__ */ jsx(
      TabEmptyState,
      {
        title: emptyTitle,
        action: {
          label: emptyActionLabel,
          onClick: openCreateForm,
          disabled: addDisabled
        }
      }
    )
  ] });
}
export {
  CustomerAddressTiles
};
//# sourceMappingURL=AddressTiles.js.map
