// BEGIN CHANGE: admin CRUD catalogo Shop Donate / Guild (+ editor bundle)
"use client";

import { FormEvent, useCallback, useEffect, useMemo, useState } from "react";
import { apiUrl } from "@/lib/api";
import { ItemIcon } from "@/components/ItemIcon";

type Slot = { itemId: number; count: number };
type BundleItem = { itemId: number; count: number };
type BundleOption = { id?: number; label: string; items: BundleItem[] };
type BundleGroup = {
  id?: number;
  label: string;
  minSelect: number;
  maxSelect: number;
  options: BundleOption[];
};
type Offer = {
  id: number;
  points: number;
  offerType: string;
  name: string;
  description: string;
  groupType: number;
  slots: Slot[];
  groups: BundleGroup[];
  // BEGIN CHANGE: optional purchase quantity
  allowQuantity?: number;
  maxQuantity?: number;
  // END CHANGE
  // BEGIN CHANGE: admin active toggle
  active?: number;
  // END CHANGE
};

type Labels = {
  shopOffersSection: string;
  shopOffersHint: string;
  shopCatalogDonate: string;
  shopCatalogGuild: string;
  shopOfferNew: string;
  shopOfferEdit: string;
  shopOfferName: string;
  shopOfferDesc: string;
  shopOfferPoints: string;
  shopOfferType: string;
  shopOfferGroup: string;
  shopOfferSlots: string;
  shopOfferSlotItem: string;
  shopOfferSlotCount: string;
  shopOfferSave: string;
  shopOfferCancel: string;
  shopOfferDelete: string;
  shopOfferConfirmDelete: string;
  // BEGIN CHANGE: optional purchase quantity
  shopOfferAllowQty: string;
  shopOfferMaxQty: string;
  shopOfferQtyHint: string;
  // END CHANGE
  // BEGIN CHANGE: admin active toggle
  shopOfferActive: string;
  shopOfferInactive: string;
  // END CHANGE
  shopBundleGroups: string;
  shopBundleGroupLabel: string;
  shopBundleMin: string;
  shopBundleMax: string;
  shopBundleAddGroup: string;
  shopBundleRemoveGroup: string;
  shopBundleOptionLabel: string;
  shopBundleAddOption: string;
  shopBundleRemoveOption: string;
  shopBundleAddItem: string;
  shopBundleRemoveItem: string;
  shopBundleHint: string;
  // BEGIN CHANGE: shop catalog manual
  shopManualTitle: string;
  shopManualSections: { title: string; items: string[] }[];
  // END CHANGE
  save: string;
  actionOk: string;
  actionFailed: string;
  delete: string;
  loading: string;
};

const EMPTY_SLOTS: Slot[] = Array.from({ length: 7 }, () => ({
  itemId: 0,
  count: 0,
}));

const OFFER_TYPES = ["item", "container", "combo", "combo2", "pacc", "bundle"] as const;

function blankBundleGroup(): BundleGroup {
  return {
    label: "Set",
    minSelect: 1,
    maxSelect: 1,
    options: [
      {
        label: "Option",
        items: [{ itemId: 0, count: 1 }],
      },
    ],
  };
}

function blankForm(): Omit<Offer, "id"> & { id: number | null } {
  return {
    id: null,
    points: 1,
    offerType: "item",
    name: "",
    description: "",
    groupType: 0,
    slots: EMPTY_SLOTS.map((s) => ({ ...s })),
    groups: [blankBundleGroup()],
    // BEGIN CHANGE: optional purchase quantity
    allowQuantity: 0,
    maxQuantity: 100,
    // END CHANGE
    // BEGIN CHANGE: admin active toggle
    active: 1,
    // END CHANGE
  };
}

export function AdminShopPanel({
  token,
  labels,
}: {
  token: string;
  labels: Labels;
}) {
  const [catalog, setCatalog] = useState<"donate" | "guild">("donate");
  const [offers, setOffers] = useState<Offer[]>([]);
  const [status, setStatus] = useState<"loading" | "ok" | "error">("loading");
  const [busy, setBusy] = useState(false);
  const [msg, setMsg] = useState("");
  const [err, setErr] = useState("");
  const [editing, setEditing] = useState(false);
  const [form, setForm] = useState(blankForm());
  const [query, setQuery] = useState("");
  // BEGIN CHANGE: shop catalog manual
  const [showManual, setShowManual] = useState(false);
  // END CHANGE

  const headers = useCallback(
    (json = true): HeadersInit => {
      const h: Record<string, string> = {
        Authorization: `Bearer ${token}`,
      };
      if (json) h["Content-Type"] = "application/json";
      return h;
    },
    [token]
  );

  const load = useCallback(() => {
    setStatus("loading");
    setErr("");
    fetch(apiUrl(`shop-admin.php?catalog=${catalog}`), { headers: headers(false) })
      .then((r) => {
        if (!r.ok) throw new Error("http");
        return r.json();
      })
      .then((json) => {
        const list = Array.isArray(json.offers) ? json.offers : [];
        setOffers(
          list.map((o: Offer) => ({
            ...o,
            groups: Array.isArray(o.groups) ? o.groups : [],
            slots: Array.isArray(o.slots) ? o.slots : EMPTY_SLOTS.map((s) => ({ ...s })),
          }))
        );
        setStatus("ok");
      })
      .catch(() => setStatus("error"));
  }, [catalog, headers]);

  useEffect(() => {
    load();
    setEditing(false);
    setForm(blankForm());
  }, [load]);

  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase();
    if (!q) return offers;
    return offers.filter(
      (o) =>
        o.name.toLowerCase().includes(q) ||
        o.offerType.toLowerCase().includes(q) ||
        String(o.id).includes(q)
    );
  }, [offers, query]);

  function openNew() {
    setForm(blankForm());
    setEditing(true);
    setMsg("");
    setErr("");
  }

  function openEdit(o: Offer) {
    setForm({
      id: o.id,
      points: o.points,
      offerType: o.offerType,
      name: o.name,
      description: o.description,
      groupType: o.groupType,
      slots: o.slots?.length
        ? o.slots.map((s) => ({ ...s }))
        : EMPTY_SLOTS.map((s) => ({ ...s })),
      groups:
        o.offerType !== "pacc" && o.groups.length > 0
          ? o.groups.map((g) => ({
              ...g,
              options: g.options.map((op) => ({
                ...op,
                items: op.items.map((it) => ({ ...it })),
              })),
            }))
          : o.offerType !== "pacc"
            ? [blankBundleGroup()]
            : [],
      // BEGIN CHANGE: optional purchase quantity
      allowQuantity: o.allowQuantity ? 1 : 0,
      maxQuantity: o.maxQuantity && o.maxQuantity > 0 ? o.maxQuantity : 100,
      // END CHANGE
      // BEGIN CHANGE: admin active toggle
      active: o.active === 0 ? 0 : 1,
      // END CHANGE
    });
    setEditing(true);
    setMsg("");
    setErr("");
  }

  function setOfferType(next: string) {
    setForm((cur) => ({
      ...cur,
      offerType: next,
      groups:
        next === "pacc"
          ? []
          : cur.groups.length > 0
            ? cur.groups
            : [blankBundleGroup()],
    }));
  }

  async function saveOffer(e: FormEvent) {
    e.preventDefault();
    setBusy(true);
    setErr("");
    setMsg("");
    try {
      const r = await fetch(apiUrl("shop-admin.php"), {
        method: "POST",
        headers: headers(true),
        body: JSON.stringify({
          action: form.id ? "update" : "create",
          catalog,
          id: form.id ?? undefined,
          points: form.points,
          offerType: form.offerType,
          name: form.name,
          description: form.description,
          groupType: form.groupType,
          slots: form.slots,
          groups: form.offerType !== "pacc" ? form.groups : undefined,
          paccDays:
            form.offerType === "pacc"
              ? form.slots[0]?.count || 0
              : undefined,
          // BEGIN CHANGE: optional purchase quantity
          allowQuantity: form.offerType === "pacc" ? 0 : form.allowQuantity ? 1 : 0,
          maxQuantity: form.maxQuantity || 100,
          // END CHANGE
          // BEGIN CHANGE: admin active toggle
          active: form.active === 0 ? 0 : 1,
          // END CHANGE
        }),
      });
      const json = await r.json().catch(() => ({}));
      if (!r.ok || !json.ok) {
        setErr(typeof json.error === "string" ? json.error : labels.actionFailed);
        return;
      }
      setMsg(labels.actionOk);
      setEditing(false);
      setForm(blankForm());
      load();
    } catch {
      setErr(labels.actionFailed);
    } finally {
      setBusy(false);
    }
  }

  async function deleteOffer(id: number) {
    if (!window.confirm(labels.shopOfferConfirmDelete)) return;
    setBusy(true);
    setErr("");
    setMsg("");
    try {
      const r = await fetch(apiUrl("shop-admin.php"), {
        method: "POST",
        headers: headers(true),
        body: JSON.stringify({ action: "delete", catalog, id }),
      });
      const json = await r.json().catch(() => ({}));
      if (!r.ok || !json.ok) {
        setErr(typeof json.error === "string" ? json.error : labels.actionFailed);
        return;
      }
      setMsg(labels.actionOk);
      if (form.id === id) {
        setEditing(false);
        setForm(blankForm());
      }
      load();
    } catch {
      setErr(labels.actionFailed);
    } finally {
      setBusy(false);
    }
  }

  const slotCount = form.offerType === "pacc" ? 1 : 0;

  function updateGroup(gi: number, patch: Partial<BundleGroup>) {
    const groups = form.groups.map((g, i) => (i === gi ? { ...g, ...patch } : g));
    setForm({ ...form, groups });
  }

  function updateOption(gi: number, oi: number, patch: Partial<BundleOption>) {
    const groups = form.groups.map((g, i) => {
      if (i !== gi) return g;
      return {
        ...g,
        options: g.options.map((op, j) => (j === oi ? { ...op, ...patch } : op)),
      };
    });
    setForm({ ...form, groups });
  }

  function updateItem(gi: number, oi: number, ii: number, patch: Partial<BundleItem>) {
    const groups = form.groups.map((g, i) => {
      if (i !== gi) return g;
      return {
        ...g,
        options: g.options.map((op, j) => {
          if (j !== oi) return op;
          return {
            ...op,
            items: op.items.map((it, k) => (k === ii ? { ...it, ...patch } : it)),
          };
        }),
      };
    });
    setForm({ ...form, groups });
  }

  return (
    <section className="mt-10">
      <h2 className="text-xl font-semibold tracking-tight">{labels.shopOffersSection}</h2>
      <p className="mt-1 text-sm text-muted">{labels.shopOffersHint}</p>

      {/* BEGIN CHANGE: shop catalog manual */}
      <div className="mt-4 rounded-lg border border-border bg-panel/60">
        <button
          type="button"
          onClick={() => setShowManual((v) => !v)}
          className="flex w-full items-center justify-between px-3 py-2 text-left text-sm font-medium"
        >
          <span>{labels.shopManualTitle}</span>
          <span className="text-muted">{showManual ? "-" : "+"}</span>
        </button>
        {showManual && (
          <div className="space-y-4 border-t border-border px-3 py-3 text-sm">
            {labels.shopManualSections.map((sec) => (
              <div key={sec.title}>
                <p className="mb-1 font-medium">{sec.title}</p>
                <ul className="list-disc space-y-1 pl-5 text-muted">
                  {sec.items.map((line) => (
                    <li key={line}>{line}</li>
                  ))}
                </ul>
              </div>
            ))}
          </div>
        )}
      </div>
      {/* END CHANGE */}

      <div className="mt-4 flex flex-wrap gap-2">
        <button
          type="button"
          onClick={() => setCatalog("donate")}
          className={`rounded-lg border px-3 py-1.5 text-sm ${
            catalog === "donate"
              ? "border-brand/50 bg-brand/15"
              : "border-border text-muted"
          }`}
        >
          {labels.shopCatalogDonate}
        </button>
        <button
          type="button"
          onClick={() => setCatalog("guild")}
          className={`rounded-lg border px-3 py-1.5 text-sm ${
            catalog === "guild"
              ? "border-brand/50 bg-brand/15"
              : "border-border text-muted"
          }`}
        >
          {labels.shopCatalogGuild}
        </button>
        <button
          type="button"
          onClick={openNew}
          className="rounded-lg bg-brand px-3 py-1.5 text-sm font-medium text-white"
        >
          {labels.shopOfferNew}
        </button>
      </div>

      {msg && <p className="mt-3 text-sm text-brand">{msg}</p>}
      {err && <p className="mt-3 text-sm text-red-400">{err}</p>}

      {editing && (
        <form
          onSubmit={saveOffer}
          className="mt-4 space-y-3 rounded-xl border border-border bg-panel p-4"
        >
          <h3 className="font-medium">
            {form.id ? labels.shopOfferEdit : labels.shopOfferNew}
            {form.id ? ` #${form.id}` : ""}
          </h3>
          <div className="grid gap-3 sm:grid-cols-2">
            <label className="block text-sm">
              <span className="text-muted">{labels.shopOfferName}</span>
              <input
                className="mt-1 w-full rounded border border-border bg-background px-3 py-2"
                value={form.name}
                onChange={(e) => setForm({ ...form, name: e.target.value })}
                required
              />
            </label>
            <label className="block text-sm">
              <span className="text-muted">{labels.shopOfferPoints}</span>
              <input
                type="number"
                min={1}
                className="mt-1 w-full rounded border border-border bg-background px-3 py-2"
                value={form.points}
                onChange={(e) =>
                  setForm({ ...form, points: Number(e.target.value) || 0 })
                }
                required
              />
            </label>
            <label className="block text-sm">
              <span className="text-muted">{labels.shopOfferType}</span>
              <select
                className="mt-1 w-full rounded border border-border bg-background px-3 py-2"
                value={form.offerType}
                onChange={(e) => setOfferType(e.target.value)}
              >
                {OFFER_TYPES.map((t) => (
                  <option key={t} value={t}>
                    {t}
                  </option>
                ))}
              </select>
            </label>
            <label className="block text-sm">
              <span className="text-muted">{labels.shopOfferGroup}</span>
              <input
                type="number"
                min={0}
                className="mt-1 w-full rounded border border-border bg-background px-3 py-2"
                value={form.groupType}
                onChange={(e) =>
                  setForm({ ...form, groupType: Number(e.target.value) || 0 })
                }
              />
            </label>
          </div>
          <label className="block text-sm">
            <span className="text-muted">{labels.shopOfferDesc}</span>
            <textarea
              className="mt-1 w-full rounded border border-border bg-background px-3 py-2"
              rows={3}
              value={form.description}
              onChange={(e) => setForm({ ...form, description: e.target.value })}
            />
          </label>

          {/* BEGIN CHANGE: admin active toggle */}
          <label className="flex items-start gap-2 text-sm">
            <input
              type="checkbox"
              className="mt-1"
              checked={form.active !== 0}
              onChange={(e) =>
                setForm({
                  ...form,
                  active: e.target.checked ? 1 : 0,
                })
              }
            />
            <span>
              <span className="block">{labels.shopOfferActive}</span>
              <span className="mt-0.5 block text-xs text-muted">
                {labels.shopOfferInactive}
              </span>
            </span>
          </label>
          {/* END CHANGE */}

          {/* BEGIN CHANGE: optional purchase quantity */}
          {form.offerType !== "pacc" && (
            <div className="grid gap-3 sm:grid-cols-2">
              <label className="flex items-start gap-2 text-sm">
                <input
                  type="checkbox"
                  className="mt-1"
                  checked={!!form.allowQuantity}
                  onChange={(e) =>
                    setForm({
                      ...form,
                      allowQuantity: e.target.checked ? 1 : 0,
                    })
                  }
                />
                <span>
                  <span className="block">{labels.shopOfferAllowQty}</span>
                  <span className="mt-0.5 block text-xs text-muted">
                    {labels.shopOfferQtyHint}
                  </span>
                </span>
              </label>
              <label className="block text-sm">
                <span className="text-muted">{labels.shopOfferMaxQty}</span>
                <input
                  type="number"
                  min={1}
                  max={100}
                  disabled={!form.allowQuantity}
                  className="mt-1 w-full rounded border border-border bg-background px-3 py-2 disabled:opacity-50"
                  value={form.maxQuantity || 100}
                  onChange={(e) =>
                    setForm({
                      ...form,
                      maxQuantity: Math.min(
                        100,
                        Math.max(1, Number(e.target.value) || 1)
                      ),
                    })
                  }
                />
              </label>
            </div>
          )}
          {/* END CHANGE */}

          {form.offerType !== "pacc" ? (
            <div className="space-y-4">
              <div>
                <p className="text-sm font-medium">{labels.shopBundleGroups}</p>
                <p className="mt-1 text-xs text-muted">{labels.shopBundleHint}</p>
              </div>
              {form.groups.map((g, gi) => (
                <div
                  key={gi}
                  className="space-y-3 rounded-lg border border-border bg-background p-3"
                >
                  <div className="flex flex-wrap items-end gap-2">
                    <label className="min-w-[140px] flex-1 text-xs">
                      <span className="text-muted">{labels.shopBundleGroupLabel}</span>
                      <input
                        className="mt-1 w-full rounded border border-border bg-panel px-2 py-1.5"
                        value={g.label}
                        onChange={(e) => updateGroup(gi, { label: e.target.value })}
                      />
                    </label>
                    <label className="w-20 text-xs">
                      <span className="text-muted">{labels.shopBundleMin}</span>
                      <input
                        type="number"
                        min={0}
                        max={20}
                        className="mt-1 w-full rounded border border-border bg-panel px-2 py-1.5"
                        value={g.minSelect}
                        onChange={(e) =>
                          updateGroup(gi, { minSelect: Number(e.target.value) || 0 })
                        }
                      />
                    </label>
                    <label className="w-20 text-xs">
                      <span className="text-muted">{labels.shopBundleMax}</span>
                      <input
                        type="number"
                        min={1}
                        max={20}
                        className="mt-1 w-full rounded border border-border bg-panel px-2 py-1.5"
                        value={g.maxSelect}
                        onChange={(e) =>
                          updateGroup(gi, { maxSelect: Number(e.target.value) || 1 })
                        }
                      />
                    </label>
                    <button
                      type="button"
                      className="rounded border border-border px-2 py-1.5 text-xs text-red-400"
                      onClick={() =>
                        setForm({
                          ...form,
                          groups: form.groups.filter((_, i) => i !== gi),
                        })
                      }
                    >
                      {labels.shopBundleRemoveGroup}
                    </button>
                  </div>

                  {g.options.map((op, oi) => (
                    <div
                      key={oi}
                      className="space-y-2 rounded border border-border/60 p-2"
                    >
                      <div className="flex flex-wrap items-end gap-2">
                        <label className="min-w-[140px] flex-1 text-xs">
                          <span className="text-muted">{labels.shopBundleOptionLabel}</span>
                          <input
                            className="mt-1 w-full rounded border border-border bg-panel px-2 py-1.5"
                            value={op.label}
                            onChange={(e) =>
                              updateOption(gi, oi, { label: e.target.value })
                            }
                          />
                        </label>
                        <button
                          type="button"
                          className="rounded border border-border px-2 py-1.5 text-xs text-red-400"
                          onClick={() =>
                            updateGroup(gi, {
                              options: g.options.filter((_, j) => j !== oi),
                            })
                          }
                        >
                          {labels.shopBundleRemoveOption}
                        </button>
                      </div>
                      <div className="space-y-1">
                        {op.items.map((it, ii) => (
                          <div key={ii} className="flex flex-wrap items-end gap-2">
                            <label className="w-28 text-xs">
                              <span className="text-muted">{labels.shopOfferSlotItem}</span>
                              <input
                                type="number"
                                min={0}
                                className="mt-1 w-full rounded border border-border bg-panel px-2 py-1.5"
                                value={it.itemId || ""}
                                onChange={(e) =>
                                  updateItem(gi, oi, ii, {
                                    itemId: Number(e.target.value) || 0,
                                  })
                                }
                              />
                            </label>
                            <label className="w-20 text-xs">
                              <span className="text-muted">{labels.shopOfferSlotCount}</span>
                              <input
                                type="number"
                                min={1}
                                className="mt-1 w-full rounded border border-border bg-panel px-2 py-1.5"
                                value={it.count}
                                onChange={(e) =>
                                  updateItem(gi, oi, ii, {
                                    count: Number(e.target.value) || 1,
                                  })
                                }
                              />
                            </label>
                            {it.itemId > 0 && <ItemIcon id={it.itemId} size={24} alt="" />}
                            <button
                              type="button"
                              className="text-xs text-red-400"
                              onClick={() =>
                                updateOption(gi, oi, {
                                  items: op.items.filter((_, k) => k !== ii),
                                })
                              }
                            >
                              {labels.shopBundleRemoveItem}
                            </button>
                          </div>
                        ))}
                        <button
                          type="button"
                          className="text-xs text-brand hover:underline"
                          onClick={() =>
                            updateOption(gi, oi, {
                              items: [...op.items, { itemId: 0, count: 1 }],
                            })
                          }
                        >
                          {labels.shopBundleAddItem}
                        </button>
                      </div>
                    </div>
                  ))}
                  <button
                    type="button"
                    className="text-xs text-brand hover:underline"
                    onClick={() =>
                      updateGroup(gi, {
                        options: [
                          ...g.options,
                          { label: "Option", items: [{ itemId: 0, count: 1 }] },
                        ],
                      })
                    }
                  >
                    {labels.shopBundleAddOption}
                  </button>
                </div>
              ))}
              <button
                type="button"
                className="rounded border border-border px-3 py-1.5 text-sm"
                onClick={() =>
                  setForm({
                    ...form,
                    groups: [...form.groups, blankBundleGroup()],
                  })
                }
              >
                {labels.shopBundleAddGroup}
              </button>
            </div>
          ) : (
            <div>
              <p className="text-sm text-muted">{labels.shopOfferSlots}</p>
              <div className="mt-2 grid gap-2 sm:grid-cols-2">
                {form.slots.slice(0, slotCount).map((s, idx) => (
                  <div key={idx} className="flex items-end gap-2">
                    <label className="flex-1 text-xs">
                      <span className="text-muted">
                        {form.offerType === "pacc"
                          ? labels.shopOfferSlotCount
                          : `${labels.shopOfferSlotItem} ${idx + 1}`}
                      </span>
                      {form.offerType === "pacc" ? (
                        <input
                          type="number"
                          min={1}
                          className="mt-1 w-full rounded border border-border bg-background px-2 py-1.5"
                          value={s.count}
                          onChange={(e) => {
                            const next = form.slots.map((x) => ({ ...x }));
                            next[idx] = {
                              itemId: 0,
                              count: Number(e.target.value) || 0,
                            };
                            setForm({ ...form, slots: next });
                          }}
                        />
                      ) : (
                        <input
                          type="number"
                          min={0}
                          className="mt-1 w-full rounded border border-border bg-background px-2 py-1.5"
                          value={s.itemId}
                          onChange={(e) => {
                            const next = form.slots.map((x) => ({ ...x }));
                            next[idx] = {
                              ...next[idx],
                              itemId: Number(e.target.value) || 0,
                            };
                            setForm({ ...form, slots: next });
                          }}
                        />
                      )}
                    </label>
                    {form.offerType !== "pacc" && (
                      <label className="w-24 text-xs">
                        <span className="text-muted">{labels.shopOfferSlotCount}</span>
                        <input
                          type="number"
                          min={0}
                          className="mt-1 w-full rounded border border-border bg-background px-2 py-1.5"
                          value={s.count}
                          onChange={(e) => {
                            const next = form.slots.map((x) => ({ ...x }));
                            next[idx] = {
                              ...next[idx],
                              count: Number(e.target.value) || 0,
                            };
                            setForm({ ...form, slots: next });
                          }}
                        />
                      </label>
                    )}
                    {s.itemId > 0 && form.offerType !== "pacc" && (
                      <ItemIcon id={s.itemId} size={24} alt="" />
                    )}
                  </div>
                ))}
              </div>
            </div>
          )}

          <div className="flex flex-wrap gap-2">
            <button
              type="submit"
              disabled={busy}
              className="rounded bg-brand px-4 py-2 text-sm font-medium text-white disabled:opacity-50"
            >
              {labels.shopOfferSave}
            </button>
            <button
              type="button"
              disabled={busy}
              onClick={() => {
                setEditing(false);
                setForm(blankForm());
              }}
              className="rounded border border-border px-4 py-2 text-sm"
            >
              {labels.shopOfferCancel}
            </button>
          </div>
        </form>
      )}

      <input
        value={query}
        onChange={(e) => setQuery(e.target.value)}
        placeholder="ID / name / type"
        className="mt-4 w-full max-w-sm rounded-lg border border-border bg-panel px-4 py-2 text-sm"
      />

      {status === "loading" && <p className="mt-4 text-muted">{labels.loading}</p>}
      {status === "error" && <p className="mt-4 text-muted">{labels.actionFailed}</p>}

      {status === "ok" && (
        <div className="mt-4 overflow-x-auto rounded-xl border border-border bg-panel">
          <table className="w-full min-w-[640px] text-sm">
            <thead>
              <tr className="border-b border-border text-left text-muted">
                <th className="px-3 py-2">ID</th>
                <th className="px-3 py-2">{labels.shopOfferName}</th>
                <th className="px-3 py-2">{labels.shopOfferType}</th>
                <th className="px-3 py-2">{labels.shopOfferPoints}</th>
                <th className="px-3 py-2">{labels.shopOfferAllowQty}</th>
                <th className="px-3 py-2">{labels.shopOfferActive}</th>
                <th className="px-3 py-2" />
              </tr>
            </thead>
            <tbody>
              {filtered.map((o) => {
                const previewIcons =
                  o.offerType === "pacc"
                    ? []
                    : (o.groups?.[0]?.options?.[0]?.items ?? [])
                        .filter((it) => it.itemId > 0)
                        .slice(0, 3);
                const isActive = o.active !== 0;
                return (
                  <tr
                    key={o.id}
                    className={`border-b border-border/50 last:border-0 ${
                      isActive ? "" : "opacity-60"
                    }`}
                  >
                    <td className="px-3 py-2 text-muted">{o.id}</td>
                    <td className="px-3 py-2">
                      <div className="flex items-center gap-2">
                        {o.offerType !== "pacc" &&
                          previewIcons.map((s, i) => (
                            <ItemIcon
                              key={`${o.id}-${s.itemId}-${i}`}
                              id={s.itemId}
                              size={24}
                              alt={o.name}
                            />
                          ))}
                        <span>{o.name}</span>
                        {!isActive ? (
                          <span className="rounded border border-amber-500/40 px-1.5 py-0.5 text-[10px] text-amber-300">
                            off
                          </span>
                        ) : null}
                      </div>
                    </td>
                    <td className="px-3 py-2 text-muted">{o.offerType}</td>
                    <td className="px-3 py-2 text-brand">{o.points}</td>
                    <td className="px-3 py-2 text-muted">
                      {o.allowQuantity
                        ? `1-${o.maxQuantity || 100}`
                        : "-"}
                    </td>
                    <td className="px-3 py-2 text-muted">
                      {isActive ? "on" : "off"}
                    </td>
                    <td className="px-3 py-2 text-right">
                      <button
                        type="button"
                        className="mr-2 text-brand hover:underline"
                        onClick={() => openEdit(o)}
                      >
                        {labels.shopOfferEdit}
                      </button>
                      <button
                        type="button"
                        className="text-red-400 hover:underline"
                        disabled={busy}
                        onClick={() => void deleteOffer(o.id)}
                      >
                        {labels.shopOfferDelete}
                      </button>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      )}
    </section>
  );
}
// END CHANGE
