"use client";

import { useMemo, useState } from "react";
import { useLang } from "@/context/LanguageContext";
import {
  Alert,
  Button,
  Card,
  EmptyState,
  Input,
  Modal,
  PageHeader,
  PageLoader,
  Pagination,
  Select,
  StatCard,
  StatusBadge,
  usePagination,
} from "@/components/ui";
import { api, useApi } from "@/lib/client";
import { formatBDT, formatDate, formatDateTime } from "@/lib/utils";
import { INVENTORY_CATEGORIES, INVENTORY_UNITS } from "@/lib/constants";
import { REPORT_PRESETS, buildVerifyQr, mix, reportFooterHtml } from "@/lib/report-html";
import { emsConfirm } from "@/components/ConfirmDialog";
import {
  IconAlertTriangle,
  IconBox,
  IconDownload,
  IconEdit,
  IconPlus,
  IconPrinter,
  IconTrash,
  IconUpload,
  IconWallet,
} from "@/components/icons";

interface ItemRow {
  id: number;
  name: string;
  nameBn: string | null;
  category: string;
  unit: string;
  quantity: number;
  minQuantity: number;
  unitPrice: number;
  value: number;
  location: string | null;
  isActive: boolean;
  low: boolean;
}

interface MovementRow {
  id: number;
  itemName: string;
  unit: string;
  type: string;
  quantity: number;
  party: string | null;
  note: string | null;
  by: string | null;
  createdAt: string;
}

interface InventoryData {
  stats: {
    totalItems: number;
    stockValue: number;
    lowStock: number;
    movementsThisMonth: number;
  };
  items: ItemRow[];
  recentMovements: MovementRow[];
}

type Tab = "items" | "stock" | "history";

const emptyItem = {
  name: "",
  nameBn: "",
  category: "FURNITURE",
  unit: "PCS",
  quantity: "0",
  minQuantity: "0",
  unitPrice: "0",
  location: "",
};

export default function PortalInventoryPage() {
  const { t, locale } = useLang();
  const [tab, setTab] = useState<Tab>("items");
  const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null);

  const { data, loading, reload } = useApi<InventoryData>("/api/portal/inventory");
  const { data: movementsData, loading: movementsLoading, reload: movementsReload } = useApi<{ movements: MovementRow[] }>(
    "/api/portal/inventory/movements"
  );

  // Item form
  const [formOpen, setFormOpen] = useState(false);
  const [editing, setEditing] = useState<ItemRow | null>(null);
  const [form, setForm] = useState(emptyItem);
  const [saving, setSaving] = useState(false);
  const [search, setSearch] = useState("");

  // Stock movement form
  const [moveForm, setMoveForm] = useState({
    itemId: "",
    type: "IN",
    quantity: "1",
    party: "",
    note: "",  });
  const [moveSaving, setMoveSaving] = useState(false);

  // print report theme + optional verification QR (like the certificates /
  // exam-schedule reports)
  const [rptPrimary, setRptPrimary] = useState(REPORT_PRESETS[0].primary);
  const [rptAccent, setRptAccent] = useState(REPORT_PRESETS[0].accent);
  const [showReportQr, setShowReportQr] = useState(true);
  // verification module switch from the credential panels — when inventory
  // verification is off, no QR checkbox and no code is issued
  const notifyCfg = useApi<{ verification?: { inventory?: boolean } }>("/api/portal/settings/notify");
  const inventoryQrAllowed = notifyCfg.data?.verification?.inventory !== false;

  /** Printable inventory report — light themed with the chosen color accent,
      stats chips, full item list and the branded Increlog footer with an
      optional verification QR. */
  async function printInventoryReport() {
    const L = t.portal.inventoryPage;
    const inst = await (await fetch("/api/auth/me")).json().catch(() => null);
    const instName = inst?.user?.institution?.name ?? "IncrelogEMS";
    const instLogo: string | null = inst?.user?.institution?.logo ?? null;
    const rows = data?.items ?? [];
    const stats = data?.stats;
    const dash = "—";
    const name = (en: string, bn: string | null) => (locale === "bn" && bn ? bn : en);

    const tint = mix(rptPrimary, "#ffffff", 0.94);
    const tint2 = mix(rptPrimary, "#ffffff", 0.85);
    const soft = mix(rptPrimary, "#ffffff", 0.9);
    const ink = mix(rptPrimary, "#000000", 0.45);

    // verification QR encodes ONLY the short code (EMS-XXXX-XXXX) — readable
    // at 80x80, printed under the chip, verified by scanner or /verify search
    let qrDataUrl: string | null = null;
    let qrCodeText: string | null = null;
    if (showReportQr && inventoryQrAllowed) {
      try {
        const res = await api<{ code: string }>("/api/portal/verify-codes", {
          method: "POST",
          body: JSON.stringify({ kind: "INVENTORY", refKey: "all", label: L.printReport }),
        });
        qrCodeText = res.code;
        qrDataUrl = await buildVerifyQr(res.code, rptPrimary, rptAccent);
      } catch {
        /* report still prints without the QR */
      }
    }

    const initials = instName.split(" ").map((w: string) => w[0]).slice(0, 2).join("").toUpperCase();
    const footer = reportFooterHtml({
      primary: rptPrimary,
      accent: rptAccent,
      qrDataUrl,
      codeText: qrCodeText,
      scanLabel: t.portal.resultsPage.scanToVerify,
      poweredBy: t.landing.poweredBy,
      reportLabel: L.printReport,
    });

    const info = [
      [t.portal.inventoryPage.totalItems, String(stats?.totalItems ?? rows.length)],
      [t.portal.inventoryPage.stockValue, formatBDT(stats?.stockValue ?? 0, locale)],
      [t.portal.inventoryPage.lowStockLabel, String(stats?.lowStock ?? 0)],
      [t.portal.inventoryPage.movementsThisMonth, String(stats?.movementsThisMonth ?? 0)],
      [t.common.status, `${L.tabItems}: ${rows.filter((i) => i.isActive).length} / ${rows.length}`],
    ];

    const itemRow = (i: ItemRow, idx: number) => `
      <tr>
        <td style="text-align:center;color:#8a94a6">${idx + 1}</td>
        <td style="font-weight:700">${name(i.name, i.nameBn)}${i.isActive ? "" : ` <span style="font-size:9px;color:#98a1b3">(${t.common.inactive})</span>`}</td>
        <td>${i.category}</td>
        <td style="text-align:center">${i.quantity} ${i.unit}</td>
        <td style="text-align:center">${i.minQuantity}</td>
        <td style="text-align:right">${formatBDT(i.unitPrice, locale)}</td>
        <td style="text-align:right;font-weight:700">${formatBDT(i.value, locale)}</td>
        <td>${i.location ?? dash}</td>
        <td style="text-align:center">${i.low ? `<b style="color:#c0392b">${t.portal.inventoryPage.lowStockLabel}</b>` : `<span style="color:#1e7e34">✓</span>`}</td>
      </tr>`;

    const html = `<!DOCTYPE html>
<html lang="${locale}">
<head>
<meta charset="utf-8"/>
<title>${L.printReport} — ${instName}</title>
<style>
  * { box-sizing: border-box; }
  html, body { margin: 0; padding: 0; }
  body {
    font-family: 'Montserrat', 'Noto Sans Bengali', sans-serif;
    color: #2c323f; background: #ffffff; padding: 26px 28px;
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  @page { size: A4; margin: 10mm; }
  .hdr {
    position: relative; overflow: hidden; border-radius: 14px;
    background: linear-gradient(180deg, ${soft} 0%, #ffffff 78%);
    border: 1px solid ${tint2};
    padding: 22px 26px 20px 30px; display: flex; align-items: center; gap: 18px;
  }
  .hdr::before {
    content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 6px;
    background: linear-gradient(180deg, ${rptPrimary} 0%, ${rptAccent} 100%);
  }
  .hdr::after {
    content: ""; position: absolute; right: -52px; top: -52px; width: 190px; height: 190px;
    border-radius: 50%; background: ${rptAccent}; opacity: 0.08;
  }
  .logo {
    width: 56px; height: 56px; border-radius: 13px; background: #ffffff;
    border: 1px solid ${tint2}; box-shadow: 0 2px 8px rgba(44,50,63,0.05);
    display: flex; align-items: center; justify-content: center; overflow: hidden;
    flex: 0 0 auto; position: relative; z-index: 1;
  }
  .logo img { max-width: 100%; max-height: 100%; object-fit: contain; }
  .logo span { font-size: 18px; font-weight: 800; letter-spacing: 1px; color: ${rptPrimary}; }
  .hb { flex: 1; min-width: 0; position: relative; z-index: 1; }
  .kick { margin: 0 0 4px; font-size: 10px; font-weight: 800; letter-spacing: 2.6px;
    text-transform: uppercase; color: ${rptAccent}; }
  .hb h1 { margin: 0; font-size: 21px; font-weight: 800; color: #2c323f; }
  .exam { margin: 5px 0 0; font-size: 13px; color: ${ink}; }
  .hs { text-align: right; position: relative; z-index: 1; flex: 0 0 auto; }
  .pill { display: inline-block; background: ${tint}; color: ${ink}; border: 1px solid ${tint2};
    border-radius: 999px; padding: 4px 14px; font-size: 11px; font-weight: 700; }
  .gen { display: block; margin-top: 7px; font-size: 10px; color: #98a1b3; }
  .bar { height: 3px; border-radius: 0 0 8px 8px; margin: -1px 10px 18px 0;
    background: linear-gradient(90deg, ${rptPrimary} 0%, ${rptAccent} 60%, transparent 100%); }
  .meta { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 18px; }
  .chip { background: #ffffff; border: 1px solid ${tint2}; border-left: 3px solid ${rptAccent};
    border-radius: 9px; padding: 6px 12px 7px; min-width: 128px; }
  .chip span { display: block; font-size: 9px; font-weight: 700; letter-spacing: 1px;
    text-transform: uppercase; color: ${ink}; margin-bottom: 1px; }
  .chip b { font-size: 12px; font-weight: 700; color: #2c323f; }
  h2.sect { font-size: 12px; font-weight: 800; letter-spacing: 1.6px; text-transform: uppercase;
    color: ${ink}; margin: 0 0 8px; display: flex; align-items: center; gap: 8px; }
  h2.sect::after { content: ""; flex: 1; height: 1px; background: ${tint2}; }
  table { width: 100%; border-collapse: collapse; font-size: 11.5px; }
  th, td { border: 1px solid ${tint2}; padding: 7px 9px; }
  thead th { background: ${tint}; color: ${ink}; text-align: left; font-size: 10px;
    font-weight: 800; letter-spacing: 0.7px; text-transform: uppercase; border-bottom: 2px solid ${rptAccent}; }
  tbody tr:nth-child(even) { background: ${mix(rptPrimary, "#ffffff", 0.97)}; }
  tfoot td { background: ${soft}; font-weight: 700; }
</style>
</head>
<body>
  <div class="hdr">
    <div class="logo">${instLogo ? `<img src="${instLogo}" alt=""/>` : `<span>${initials}</span>`}</div>
    <div class="hb">
      <p class="kick">${L.printReport}</p>
      <h1>${instName}</h1>
      <p class="exam">${t.portal.inventoryPage.title}</p>
    </div>
    <div class="hs">
      <span class="pill">${new Date().toLocaleDateString(locale === "bn" ? "bn-BD" : "en-GB")}</span>
      <span class="gen">${t.portal.examsPage.generatedOn}: ${formatDate(new Date().toISOString(), locale)}</span>
    </div>
  </div>
  <div class="bar"></div>

  <div class="meta">${info.map(([k, v]) => `<div class="chip"><span>${k}</span><b>${v}</b></div>`).join("")}</div>

  <h2 class="sect">${t.portal.inventoryPage.tabItems}</h2>
  <table>
    <thead><tr>
      <th>#</th><th>${t.common.name}</th><th>${t.common.category}</th>
      <th>${t.portal.inventoryPage.onHand}</th><th>${L.minQty}</th>
      <th style="text-align:right">${t.common.unitPrice}</th>
      <th style="text-align:right">${t.common.value}</th>
      <th>${L.locationLabel}</th><th>${t.common.status}</th>
    </tr></thead>
    <tbody>${rows.map(itemRow).join("")}</tbody>
    <tfoot><tr>
      <td colspan="6" style="text-align:right">${t.portal.inventoryPage.stockValue}</td>
      <td style="text-align:right">${formatBDT(rows.reduce((sum, i) => sum + i.value, 0), locale)}</td>
      <td colspan="2" style="text-align:center">${rows.length}</td>
    </tr></tfoot>
  </table>

  ${footer}
</body>
</html>`;
    const w = window.open("", "_blank", "width=980,height=760");
    if (!w) return;
    w.document.write(html);
    w.document.close();
    w.focus();
    setTimeout(() => w.print(), 350);
  }

  const items = useMemo(() => {
    if (!data) return [];
    const q = search.trim().toLowerCase();
    if (!q) return data.items;
    return data.items.filter(
      (i) =>
        i.name.toLowerCase().includes(q) ||
        i.category.toLowerCase().includes(q) ||
        (i.location ?? "").toLowerCase().includes(q)
    );
  }, [data, search]);

  const itemsPager = usePagination(items, 10);
  const movements = movementsData?.movements ?? [];
  const movementsPager = usePagination(movements, 10);

  const activeItems = (data?.items ?? []).filter((i) => i.isActive);

  function notify(type: "success" | "error", text: string) {
    setMessage({ type, text });
    window.scrollTo({ top: 0, behavior: "smooth" });
  }

  function openCreate() {
    setEditing(null);
    setForm(emptyItem);
    setFormOpen(true);
  }

  function openEdit(i: ItemRow) {
    setEditing(i);
    setForm({
      name: i.name,
      nameBn: i.nameBn ?? "",
      category: INVENTORY_CATEGORIES.includes(i.category as never) ? i.category : "OTHER",
      unit: INVENTORY_UNITS.includes(i.unit as never) ? i.unit : "PCS",
      quantity: String(i.quantity),
      minQuantity: String(i.minQuantity),
      unitPrice: String(i.unitPrice),
      location: i.location ?? "",
    });
    setFormOpen(true);
  }

  async function saveItem() {
    setSaving(true);
    try {
      if (editing) {
        await api(`/api/portal/inventory/${editing.id}`, {
          method: "PUT",
          body: JSON.stringify({ ...form, isActive: editing.isActive }),
        });
        notify("success", t.portal.inventoryPage.itemUpdated);
      } else {
        await api("/api/portal/inventory", { method: "POST", body: JSON.stringify(form) });
        notify("success", t.portal.inventoryPage.itemCreated);
      }
      setFormOpen(false);
      reload();
      movementsReload();
    } catch {
      notify("error", t.common.tryAgain);
    } finally {
      setSaving(false);
    }
  }

  async function toggleActive(i: ItemRow) {
    try {
      await api(`/api/portal/inventory/${i.id}`, {
        method: "PUT",
        body: JSON.stringify({ isActive: !i.isActive }),
      });
      reload();
    } catch {
      notify("error", t.common.tryAgain);
    }
  }

  async function removeItem(i: ItemRow) {
    if (!(await emsConfirm({ message: t.common.confirmDelete, danger: true }))) return;
    try {
      await api(`/api/portal/inventory/${i.id}`, { method: "DELETE" });
      notify("success", t.common.deletedSuccessfully);
      reload();
    } catch (e) {
      const err = e instanceof Error ? e.message : "";
      notify("error", err === "IN_USE" ? t.portal.inventoryPage.itemInUse : t.common.tryAgain);
    }
  }

  async function recordMovement() {
    setMoveSaving(true);
    try {
      await api("/api/portal/inventory/movements", {
        method: "POST",
        body: JSON.stringify(moveForm),
      });
      setMoveForm({ ...moveForm, itemId: "", quantity: "1", party: "", note: "" });
      movementsReload();
      reload();
      notify("success", t.portal.inventoryPage.movementRecorded);
    } catch (e) {
      const err = e instanceof Error ? e.message : "";
      notify(
        "error",
        err === "INSUFFICIENT"
          ? t.portal.inventoryPage.insufficientStock
          : err === "QTY_INVALID"
            ? t.portal.inventoryPage.qtyInvalid
            : t.common.tryAgain
      );
    } finally {
      setMoveSaving(false);
    }
  }

  if (loading) return <PageLoader text={t.common.loading} />;
  const s = data?.stats;

  return (
    <div>
      <PageHeader
        title={t.portal.inventoryPage.title}
        subtitle={t.portal.inventoryPage.subtitle}
        action={
          <Button onClick={() => printInventoryReport()} disabled={!data || (data?.items ?? []).length === 0}>
            <IconPrinter className="svg-16" />
            <span className="ms-1">{t.portal.inventoryPage.printReport}</span>
          </Button>
        }
      />

      {/* print report theme — same preset/custom picker + QR toggle as the
          exam schedule report */}
      <div className="d-flex flex-wrap align-items-center gap-2 mb-4">
        <span className="ems-fs-12 f-w-700 text-muted">{t.portal.resultsPage.colorsLabel}</span>
        {REPORT_PRESETS.map((preset, i) => {
          const active = rptPrimary === preset.primary && rptAccent === preset.accent;
          return (
            <button
              key={i}
              type="button"
              className={`btn btn-sm p-0 ${active ? "" : "btn-outline-secondary"}`}
              style={{
                width: 32, height: 28, borderRadius: 8,
                background: `linear-gradient(135deg, ${preset.primary} 55%, ${preset.accent} 55%)`,
                border: active ? `2px solid ${preset.primary}` : undefined,
                boxShadow: active ? `0 0 0 3px ${preset.primary}33` : undefined,
              }}
              onClick={() => { setRptPrimary(preset.primary); setRptAccent(preset.accent); }}
              aria-label={`report-theme-${i}`}
            >
              {active && <span style={{ color: "#fff", fontSize: 12, lineHeight: 1 }}>✓</span>}
            </button>
          );
        })}
        <input
          type="color"
          className="form-control form-control-color cursor-pointer"
          style={{ width: 36, height: 28 }}
          value={rptPrimary}
          onChange={(e) => setRptPrimary(e.target.value)}
          title={t.portal.resultsPage.primaryLabel}
        />
        <input
          type="color"
          className="form-control form-control-color cursor-pointer"
          style={{ width: 36, height: 28 }}
          value={rptAccent}
          onChange={(e) => setRptAccent(e.target.value)}
          title={t.portal.resultsPage.accentLabel}
        />
        {inventoryQrAllowed && (
          <label className="form-check d-flex align-items-center gap-2 ems-fs-12 f-w-600 cursor-pointer mb-0" title={t.portal.examsPage.showQrHint}>
            <input
              className="form-check-input mt-0 cursor-pointer"
              type="checkbox"
              checked={showReportQr}
              onChange={(e) => setShowReportQr(e.target.checked)}
            />
            {t.portal.examsPage.showQr}
          </label>
        )}
      </div>

      {message && (
        <div className="mb-4">
          <Alert type={message.type} onClose={() => setMessage(null)}>{message.text}</Alert>
        </div>
      )}

      {/* Stats */}
      <div className="row g-3 mb-4">
        <div className="col-xl-3 col-sm-6">
          <StatCard label={t.portal.inventoryPage.totalItems} value={String(s?.totalItems ?? 0)} icon={<IconBox />} accent="teal" />
        </div>
        <div className="col-xl-3 col-sm-6">
          <StatCard label={t.portal.inventoryPage.stockValue} value={formatBDT(s?.stockValue ?? 0, locale)} icon={<IconWallet />} accent="blue" />
        </div>
        <div className="col-xl-3 col-sm-6">
          <StatCard label={t.portal.inventoryPage.lowStockLabel} value={String(s?.lowStock ?? 0)} icon={<IconAlertTriangle />} accent="red" />
        </div>
        <div className="col-xl-3 col-sm-6">
          <StatCard label={t.portal.inventoryPage.movementsThisMonth} value={String(s?.movementsThisMonth ?? 0)} icon={<IconDownload />} accent="orange" />
        </div>
      </div>

      {/* Tabs */}
      <ul className="nav nav-tabs mb-4" role="tablist">
        {(["items", "stock", "history"] as Tab[]).map((key) => {
          const labels: Record<Tab, string> = {
            items: t.portal.inventoryPage.tabItems,
            stock: t.portal.inventoryPage.tabStock,
            history: t.portal.inventoryPage.tabHistory,
          };
          return (
            <li className="nav-item" key={key}>
              <button
                className={`nav-link ${tab === key ? "active" : ""}`}
                onClick={() => setTab(key)}
                type="button"
              >
                {labels[key]}
              </button>
            </li>
          );
        })}
      </ul>

      {/* ---------- Items tab ---------- */}
      {tab === "items" && (
        !data || data.items.length === 0 ? (
          <div className="card">
            <EmptyState
              icon={<IconBox />}
              title={t.portal.inventoryPage.noItems}
              action={
                <Button onClick={openCreate}>
                  <IconPlus className="svg-16" />
                  <span className="ms-1">{t.portal.inventoryPage.newItem}</span>
                </Button>
              }
            />
          </div>
        ) : (
          <div className="card">
            <div className="card-header d-flex flex-wrap align-items-center justify-content-between gap-2">
              <div className="has-search" style={{ maxWidth: 320 }}>
                <span className="fa fa-search form-control-feedback" />
                <input
                  className="form-control"
                  placeholder={t.common.search}
                  value={search}
                  onChange={(e) => setSearch(e.target.value)}
                />
              </div>
              <Button onClick={openCreate}>
                <IconPlus className="svg-16" />
                <span className="ms-1">{t.portal.inventoryPage.newItem}</span>
              </Button>
            </div>
            <div className="table-responsive">
              <table className="table table-hover align-middle mb-0">
                <thead className="ems-table-head">
                  <tr>
                    <th>{t.common.name}</th>
                    <th>{t.common.category}</th>
                    <th>{t.portal.inventoryPage.onHand}</th>
                    <th>{t.common.unitPrice}</th>
                    <th>{t.common.value}</th>
                    <th>{t.common.status}</th>
                    <th className="text-end">{t.common.actions}</th>
                  </tr>
                </thead>
                <tbody>
                  {itemsPager.paged.map((i) => (
                    <tr key={i.id} className={!i.isActive ? "opacity-50" : ""}>
                      <td>
                        <p className="mb-0 f-w-700">{i.name}</p>
                        {i.location && <p className="mb-0 ems-fs-11 text-muted">{i.location}</p>}
                      </td>
                      <td>
                        <span className="ems-type-pill">
                          {t.inventoryCategories[i.category as keyof typeof t.inventoryCategories] ?? i.category}
                        </span>
                      </td>
                      <td>
                        <span className={`badge me-1 ${i.low ? "badge-danger" : "badge-primary"}`}>
                          {i.quantity} {t.inventoryUnits[i.unit as keyof typeof t.inventoryUnits] ?? i.unit}
                        </span>
                        {i.low && <span className="badge badge-danger">{t.portal.inventoryPage.lowBadge}</span>}
                        <p className="mb-0 ems-fs-11 text-muted mt-1">
                          {t.portal.inventoryPage.minQty}: {i.minQuantity}
                        </p>
                      </td>
                      <td className="ems-fs-13">{formatBDT(i.unitPrice, locale)}</td>
                      <td className="f-w-700">{formatBDT(i.value, locale)}</td>
                      <td>
                        {i.low ? (
                          <StatusBadge status="LOW" label={t.portal.inventoryPage.lowStockLabel} />
                        ) : (
                          <StatusBadge status={i.isActive ? "ACTIVE" : "INACTIVE"} label={i.isActive ? t.common.active : t.common.inactive} />
                        )}
                      </td>
                      <td className="text-end">
                        <button className="btn btn-soft-secondary btn-sm me-1" onClick={() => openEdit(i)} type="button">
                          <IconEdit className="svg-16" />
                        </button>
                        <button className="btn btn-soft-warning btn-sm me-1" onClick={() => toggleActive(i)} type="button">
                          {i.isActive ? t.portal.inventoryPage.deactivate : t.portal.inventoryPage.activate}
                        </button>
                        <button className="btn btn-soft-danger btn-sm" onClick={() => removeItem(i)} type="button">
                          <IconTrash className="svg-16" />
                        </button>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
            <Pagination {...itemsPager} onPageChange={itemsPager.setPage} onSizeChange={itemsPager.setSize} />
          </div>
        )
      )}

      {/* ---------- Stock in/out tab ---------- */}
      {tab === "stock" && (
        <div className="row">
          <div className="col-xl-6">
            <Card title={t.portal.inventoryPage.tabStock} icon={<IconDownload className="svg-18" />}>
              <Select
                label={t.common.name}
                value={moveForm.itemId}
                onChange={(e) => setMoveForm({ ...moveForm, itemId: e.target.value })}
              >
                <option value="">— {t.common.filter} —</option>
                {activeItems.map((i) => (
                  <option key={i.id} value={i.id}>
                    {i.name} ({i.quantity} {t.inventoryUnits[i.unit as keyof typeof t.inventoryUnits] ?? i.unit})
                  </option>
                ))}
              </Select>
              <div className="form-group mb-3">
                <label className="col-form-label pt-0 f-w-600">{t.common.status}</label>
                <div className="btn-group w-100" role="group">
                  <button
                    type="button"
                    className={`btn ${moveForm.type === "IN" ? "btn-success" : "btn-outline-secondary"}`}
                    onClick={() => setMoveForm({ ...moveForm, type: "IN" })}
                  >
                    <IconDownload className="svg-14" />
                    <span className="ms-1">{t.portal.inventoryPage.stockIn}</span>
                  </button>
                  <button
                    type="button"
                    className={`btn ${moveForm.type === "OUT" ? "btn-warning" : "btn-outline-secondary"}`}
                    onClick={() => setMoveForm({ ...moveForm, type: "OUT" })}
                  >
                    <IconUpload className="svg-14" />
                    <span className="ms-1">{t.portal.inventoryPage.stockOut}</span>
                  </button>
                </div>
              </div>
              <div className="row">
                <div className="col-md-6">
                  <Input
                    label={t.common.quantity}
                    type="number"
                    min="1"
                    value={moveForm.quantity}
                    onChange={(e) => setMoveForm({ ...moveForm, quantity: e.target.value })}
                  />
                </div>
                <div className="col-md-6">
                  <Input
                    label={t.portal.inventoryPage.partyLabel}
                    value={moveForm.party}
                    onChange={(e) => setMoveForm({ ...moveForm, party: e.target.value })}
                    placeholder="e.g. Science Lab / Router Store"
                  />
                </div>
              </div>
              <div className="form-group mb-3">
                <label className="col-form-label pt-0 f-w-600">{t.common.note}</label>
                <textarea
                  className="form-control"
                  rows={2}
                  value={moveForm.note}
                  onChange={(e) => setMoveForm({ ...moveForm, note: e.target.value })}
                />
              </div>
              <Button
                onClick={recordMovement}
                loading={moveSaving}
                disabled={!moveForm.itemId || Number(moveForm.quantity) < 1}
              >
                {moveForm.type === "IN" ? <IconDownload className="svg-16" /> : <IconUpload className="svg-16" />}
                <span className="ms-1">{moveForm.type === "IN" ? t.portal.inventoryPage.stockIn : t.portal.inventoryPage.stockOut}</span>
              </Button>
            </Card>
          </div>
        </div>
      )}

      {/* ---------- History tab ---------- */}
      {tab === "history" && (
        <div className="card">
          <div className="card-header">
            <h5 className="f-w-600 mb-0">{t.portal.inventoryPage.tabHistory}</h5>
          </div>
          {movementsLoading ? (
            <div className="card-body text-center py-4">
              <span className="spinner-border text-primary" role="status" />
            </div>
          ) : !movementsData || movementsData.movements.length === 0 ? (
            <EmptyState icon={<IconBox />} title={t.portal.inventoryPage.noMovements} />
          ) : (
            <>
            <div className="table-responsive">
              <table className="table table-hover align-middle mb-0">
                <thead className="ems-table-head">
                  <tr>
                    <th>{t.common.name}</th>
                    <th>{t.common.status}</th>
                    <th>{t.common.quantity}</th>
                    <th>{t.portal.inventoryPage.partyLabel}</th>
                    <th>{t.common.date}</th>
                  </tr>
                </thead>
                <tbody>
                  {movementsPager.paged.map((m) => (
                    <tr key={m.id}>
                      <td className="f-w-600">
                        {m.itemName}
                        {m.note && <p className="mb-0 ems-fs-11 text-muted">{m.note}</p>}
                      </td>
                      <td>
                        <StatusBadge status={m.type} label={t.status[m.type as keyof typeof t.status]} />
                      </td>
                      <td className="f-w-700">
                        {m.type === "IN" ? "+" : "−"}
                        {m.quantity} {t.inventoryUnits[m.unit as keyof typeof t.inventoryUnits] ?? m.unit}
                      </td>
                      <td className="ems-fs-13">{m.party ?? "—"}</td>
                      <td className="ems-fs-12">
                        {formatDateTime(m.createdAt, locale)}
                        {m.by && <p className="mb-0 ems-fs-11 text-muted">{m.by}</p>}
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
            <Pagination {...movementsPager} onPageChange={movementsPager.setPage} onSizeChange={movementsPager.setSize} />
            </>
          )}
        </div>
      )}

      {/* Item create/edit modal */}
      <Modal
        open={formOpen}
        onClose={() => setFormOpen(false)}
        title={editing ? t.portal.inventoryPage.editItem : t.portal.inventoryPage.newItem}
        wide
      >
        <div className="row">
          <div className="col-md-6">
            <Input label={t.portal.inventoryPage.itemNameLabel} value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} />
          </div>
          <div className="col-md-6">
            <Input label={t.portal.inventoryPage.itemNameBn} value={form.nameBn} onChange={(e) => setForm({ ...form, nameBn: e.target.value })} />
          </div>
          <div className="col-md-4">
            <Select label={t.common.category} value={form.category} onChange={(e) => setForm({ ...form, category: e.target.value })}>
              {INVENTORY_CATEGORIES.map((c) => (
                <option key={c} value={c}>
                  {t.inventoryCategories[c]}
                </option>
              ))}
            </Select>
          </div>
          <div className="col-md-4">
            <Select label={t.common.unit} value={form.unit} onChange={(e) => setForm({ ...form, unit: e.target.value })}>
              {INVENTORY_UNITS.map((u) => (
                <option key={u} value={u}>
                  {t.inventoryUnits[u]}
                </option>
              ))}
            </Select>
          </div>
          <div className="col-md-4">
            <Input
              label={editing ? t.common.quantity : t.portal.inventoryPage.initialQty}
              type="number"
              min="0"
              value={form.quantity}
              disabled={!!editing}
              onChange={(e) => setForm({ ...form, quantity: e.target.value })}
            />
          </div>
          <div className="col-md-4">
            <Input label={t.portal.inventoryPage.minQty} type="number" min="0" value={form.minQuantity} onChange={(e) => setForm({ ...form, minQuantity: e.target.value })} />
          </div>
          <div className="col-md-4">
            <Input label={t.common.unitPrice} type="number" min="0" value={form.unitPrice} onChange={(e) => setForm({ ...form, unitPrice: e.target.value })} />
          </div>
          <div className="col-md-4">
            <Input label={t.portal.inventoryPage.locationLabel} value={form.location} onChange={(e) => setForm({ ...form, location: e.target.value })} placeholder="e.g. Store Room" />
          </div>
        </div>
        {editing && (
          <p className="mb-3 ems-fs-12 text-muted">{t.portal.inventoryPage.tabStock} → {t.common.quantity}</p>
        )}
        <div className="d-flex justify-content-end gap-2">
          <Button variant="secondary" onClick={() => setFormOpen(false)}>
            {t.common.cancel}
          </Button>
          <Button onClick={saveItem} loading={saving} disabled={!form.name.trim()}>
            {t.common.save}
          </Button>
        </div>
      </Modal>
    </div>
  );
}
