import { useEffect, useState } from "react";
import { api } from "../api";
import { useConfirm } from "../confirm";
import { useAuth } from "../auth";
import BarcodeList from "../components/BarcodeList";
import Icon from "../components/Icon";
import DataTable from "../components/DataTable";
import LocationMinStock from "../components/LocationMinStock";
import { fmt } from "../units";

export default function Groups() {
  const confirm = useConfirm();
  const { isAdmin } = useAuth();
  const [groups, setGroups] = useState([]);
  const [units, setUnits] = useState([]);
  const [locations, setLocations] = useState([]);
  const [form, setForm] = useState({ name: "", min_stock: "", min_stock_unit_id: "" });
  const [selectedId, setSelectedId] = useState(null);
  const [error, setError] = useState(null);

  async function load() {
    try {
      const [gs, us, ls] = await Promise.all([
        api.listGroups(), api.listUnits(), api.listLocations(),
      ]);
      setGroups(gs);
      setUnits(us);
      setLocations(ls);
    } catch (err) {
      setError(err.message);
    }
  }

  useEffect(() => { load(); }, []);

  async function add(e) {
    e.preventDefault();
    setError(null);
    try {
      await api.createGroup({
        name: form.name,
        min_stock: form.min_stock === "" ? null : Number(form.min_stock),
        min_stock_unit_id: form.min_stock_unit_id === "" ? null : Number(form.min_stock_unit_id),
      });
      setForm({ name: "", min_stock: "", min_stock_unit_id: form.min_stock_unit_id });
      load();
    } catch (err) {
      setError(err.message);
    }
  }

  async function patch(group, body) {
    setError(null);
    try {
      await api.updateGroup(group.id, body);
      load();
    } catch (err) {
      setError(err.message);
    }
  }

  async function remove(group) {
    const ok = await confirm({
      title: `Gruppe „${group.name}“ löschen?`,
      message: "Die Produkte bleiben erhalten, verlieren aber ihre Zuordnung zu dieser Gruppe.",
      confirmLabel: "Löschen",
      danger: true,
    });
    if (!ok) return;
    try {
      await api.deleteGroup(group.id);
      if (selectedId === group.id) setSelectedId(null);
      load();
    } catch (err) {
      setError(err.message);
    }
  }

  const selected = groups.find((g) => g.id === selectedId) || null;

  const columns = [
    { key: "name", header: "Gruppe", grow: true, min: 160,
      filterText: (g) => g.name, sortValue: (g) => g.name,
      render: (g) => {
        const low = g.min_stock != null && g.stock < g.min_stock;
        return (
          <span className="cell-row">
            {isAdmin ? (
              <input defaultValue={g.name} style={{ marginTop: 0, minWidth: 120 }}
                onBlur={(e) => { const v = e.target.value.trim(); if (v && v !== g.name) patch(g, { name: v }); }} />
            ) : <span className="strong">{g.name}</span>}
            {low && <span className="badge warn">niedrig</span>}
          </span>
        );
      } },
    { key: "products", header: "Produkte", width: 100, align: "num",
      sortValue: (g) => g.product_count, render: (g) => <span className="muted">{g.product_count}</span> },
    { key: "stock", header: "Bestand", width: 130, align: "num",
      sortValue: (g) => g.stock, render: (g) => `${fmt(g.stock)} ${g.min_stock_unit_name || ""}` },
    { key: "min", header: "Mindestbestand", width: 150, sortValue: (g) => g.min_stock ?? -1,
      render: (g) => (isAdmin ? (
        <input type="number" step="any" defaultValue={g.min_stock ?? ""} style={{ marginTop: 0, minWidth: 90 }}
          onBlur={(e) => { const v = e.target.value; if (v !== String(g.min_stock ?? "")) patch(g, { min_stock: v === "" ? null : Number(v) }); }} />
      ) : (g.min_stock != null ? fmt(g.min_stock) : "–")) },
    { key: "unit", header: "Einheit", width: 150, filterText: (g) => g.min_stock_unit_name || "",
      render: (g) => (isAdmin ? (
        <select value={g.min_stock_unit_id ?? ""} style={{ marginTop: 0 }}
          onChange={(e) => patch(g, { min_stock_unit_id: e.target.value === "" ? null : Number(e.target.value) })}>
          <option value="">– Basiseinheit –</option>
          {units.map((u) => <option key={u.id} value={u.id}>{u.name}</option>)}
        </select>
      ) : (g.min_stock_unit_name || "–")) },
    { key: "codes", header: "EAN-Codes", width: 130, align: "num",
      render: (g) => (
        <button className="link-btn" onClick={() => setSelectedId(g.id)}>
          {(g.product_barcodes?.length || 0) + (g.barcodes?.length || 0)} verwalten
        </button>
      ) },
    { key: "actions", header: "", label: "Aktionen", fixed: true, width: 56, align: "num",
      render: (g) => isAdmin && (
        <button className="btn-icon danger" onClick={() => remove(g)} title="Löschen">
          <Icon name="trash" size={16} />
        </button>
      ) },
  ];

  return (
    <div>
      <div className="page-head">
        <div>
          <h1>Gruppen</h1>
          <div className="sub">
            Bestände mehrerer Marken zusammenzählen – z.B. Mehl von Rewe, Aldi und Migros als „5 kg Mehl“. Mit gemeinsamem Mindestbestand; die EAN-Codes der zugeordneten Artikel erscheinen automatisch hier.
          </div>
        </div>
      </div>
      {error && <div className="alert error"><Icon name="alert" size={16} />{error}</div>}

      <div className="grid-2 wide-aside">
        <div className="card">
          <DataTable id="groups" columns={columns} rows={groups}
            getRowKey={(g) => g.id} empty="Noch keine Gruppen." />
        </div>

        <div>
          {selected && (
            <section className="card">
              <div className="card-head">
                <Icon name="search" />
                <h2>EAN-Codes der Gruppe: {selected.name}</h2>
              </div>
              <BarcodeList
                barcodes={selected.barcodes || []}
                productBarcodes={selected.product_barcodes || []}
                disabled={!isAdmin}
                hint={"Codes der zugeordneten Artikel stehen automatisch hier, mit Marke und " +
                      "Artikelnamen; entfernen lassen sie sich nur, indem der Artikel die Gruppe " +
                      "wechselt. Zusätzlich sind Codes möglich, die noch zu keinem Artikel " +
                      "gehören – für die gibt es eine Notiz, weil ihnen der Artikelname fehlt. " +
                      "Wird so ein Code beim Einlagern gescannt, landet der neu angelegte Artikel " +
                      "automatisch hier."}
                onAdd={async (body) => {
                  try {
                    await api.addGroupBarcode(selected.id, body);
                    await load();
                  } catch (err) { setError(err.message); }
                }}
                onEditNote={async (code, note) => {
                  try {
                    await api.updateGroupBarcodeNote(selected.id, code, { note });
                    await load();
                  } catch (err) { setError(err.message); }
                }}
                onDelete={async (code) => {
                  try {
                    await api.deleteGroupBarcode(selected.id, code);
                    await load();
                  } catch (err) { setError(err.message); }
                }}
              />
              <button className="btn ghost" onClick={() => setSelectedId(null)}>Schließen</button>
            </section>
          )}

          {selected && isAdmin && (
            <section className="card">
              <div className="card-head">
                <Icon name="location" />
                <h2>Mindestbestand je Lagerort</h2>
              </div>
              <p className="muted small mt-0">
                Bedarf dieser Gruppe je Lagerort (z.B. Ferienhaus, Zuhause), zusätzlich zum
                Gesamt-Mindestbestand{selected.min_stock_unit_name ? ` (in ${selected.min_stock_unit_name})` : ""}.
              </p>
              <LocationMinStock
                key={selected.id}
                locations={locations}
                initial={selected.location_min_stocks || []}
                unitLabel={selected.min_stock_unit_name || ""}
                onError={setError}
                onSave={async (list) => {
                  await api.setGroupLocationMinStock(selected.id, list);
                  await load();
                }}
              />
            </section>
          )}

          {isAdmin && (
            <form className="card" onSubmit={add}>
              <div className="card-head"><Icon name="tag" /><h2>Neue Gruppe</h2></div>
              <label>
                Name
                <input placeholder="z.B. Mehl" value={form.name}
                  onChange={(e) => setForm({ ...form, name: e.target.value })} required />
              </label>
              <div className="row">
                <label className="grow">
                  Mindestbestand (optional)
                  <input type="number" step="any" value={form.min_stock}
                    onChange={(e) => setForm({ ...form, min_stock: e.target.value })} placeholder="z.B. 2" />
                </label>
                <label className="grow">
                  Einheit
                  <select value={form.min_stock_unit_id}
                    onChange={(e) => setForm({ ...form, min_stock_unit_id: e.target.value })}>
                    <option value="">– Basiseinheit –</option>
                    {units.map((u) => <option key={u.id} value={u.id}>{u.name}</option>)}
                  </select>
                </label>
              </div>
              <button className="btn primary"><Icon name="plus" size={16} />Anlegen</button>
              <p className="muted small">
                Der Bestand der Gruppe summiert nur Produkte, die zur gewählten Einheit passen.
                Namen lassen sich in der Tabelle direkt ändern.
              </p>
            </form>
          )}
        </div>
      </div>
    </div>
  );
}
