import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { api } from "../api";
import { useAuth } from "../auth";
import Icon from "../components/Icon";
import { guessGroup, suggestionToProduct } from "../offUtils";
import { buildUnitOptions, fmt, isExpired } from "../units";

const emptyLine = () => ({ quantity: "", best_before: "" });

export default function CheckIn() {
  const { isAdmin } = useAuth();
  const [barcode, setBarcode] = useState("");
  const [product, setProduct] = useState(null);
  const [suggestion, setSuggestion] = useState(null);
  // Gruppe, die diesem Code zugeordnet ist (z.B. alle Mehl-Marken in "Mehl").
  const [suggestionGroup, setSuggestionGroup] = useState({ id: "", name: "" });
  const [unknownBarcode, setUnknownBarcode] = useState(null);
  const [results, setResults] = useState([]);
  const [search, setSearch] = useState("");
  const [locations, setLocations] = useState([]);
  const [groups, setGroups] = useState([]);
  const [units, setUnits] = useState([]);

  const [unit, setUnit] = useState("");
  const [locationId, setLocationId] = useState("");
  const [lines, setLines] = useState([emptyLine()]);

  const [error, setError] = useState(null);
  const [info, setInfo] = useState(null);
  const [busy, setBusy] = useState(false);

  useEffect(() => {
    api.listLocations().then(setLocations).catch(() => {});
    api.listGroups().then(setGroups).catch(() => {});
    api.listUnits().then(setUnits).catch(() => {});
  }, []);

  function resetLookup() {
    setSuggestion(null);
    setUnknownBarcode(null);
  }

  function selectProduct(p) {
    setProduct(p);
    setResults([]);
    resetLookup();
    const opts = buildUnitOptions(p, units);
    // Gibt es ein Gebinde (Glas, Packung, …), ist das die naheliegende Eingabe.
    setUnit(p.package_size ? "package" : (p.unit_name || (opts[0] && opts[0].value) || ""));
    setLines([emptyLine()]);
    setLocationId("");
  }

  async function doLookup() {
    setError(null); setInfo(null); resetLookup();
    if (!barcode) return;
    try {
      const res = await api.lookup(barcode.trim());
      if (res.found && res.existing_product) {
        selectProduct(res.existing_product);
        setInfo(`Produkt erkannt: ${res.existing_product.name}`);
      } else if (res.found && res.suggestion) {
        setSuggestion(res.suggestion);
        setSuggestionGroup({ id: res.group_id ? String(res.group_id) : "", name: res.group_name || "" });
      } else {
        setUnknownBarcode(barcode.trim());
        setSuggestionGroup({ id: res.group_id ? String(res.group_id) : "", name: res.group_name || "" });
      }
    } catch (err) {
      setError(err.message);
    }
  }

  async function createFromSuggestion() {
    setError(null); setBusy(true);
    try {
      // Ist der Code einer Gruppe zugeordnet, hat das Vorrang vor dem Kategorie-Rateversuch.
      const groupId = suggestionGroup.id || guessGroup(groups, suggestion);
      const payload = suggestionToProduct(suggestion, groupId);
      const created = await api.createProduct(payload);
      selectProduct(created);
      setInfo(`Produkt "${created.name}" angelegt.`);
    } catch (err) {
      setError(err.message);
    } finally {
      setBusy(false);
    }
  }

  async function doSearch(e) {
    e.preventDefault();
    try {
      setResults(await api.listProducts(search));
    } catch (err) {
      setError(err.message);
    }
  }

  function setLine(i, key, value) {
    setLines((ls) => ls.map((l, idx) => (idx === i ? { ...l, [key]: value } : l)));
  }
  function addLine() {
    setLines((ls) => [...ls, emptyLine()]);
  }
  function removeLine(i) {
    setLines((ls) => (ls.length > 1 ? ls.filter((_, idx) => idx !== i) : ls));
  }

  const totalQty = lines.reduce((s, l) => s + (Number(l.quantity) || 0), 0);

  async function submit(e) {
    e.preventDefault();
    setError(null); setInfo(null);
    const payloadLines = lines
      .filter((l) => Number(l.quantity) > 0)
      .map((l) => ({
        quantity: Number(l.quantity),
        best_before: l.best_before || null,
        location_id: locationId === "" ? null : Number(locationId),
      }));
    if (payloadLines.length === 0) {
      setError("Bitte mindestens eine Menge angeben.");
      return;
    }
    setBusy(true);
    try {
      const res = await api.checkInBatch({ product_id: product.id, unit, lines: payloadLines });
      setInfo(
        `${payloadLines.length} Charge(n) eingelagert. Neuer Bestand: ` +
          `${fmt(res.product_stock / (product.unit_factor || 1))} ${product.unit_name}`
      );
      setLines([emptyLine()]);
      setProduct(await api.getProduct(product.id));
    } catch (err) {
      setError(err.message);
    } finally {
      setBusy(false);
    }
  }

  return (
    <div>
      <div className="page-head"><h1>Einlagern</h1></div>
      {error && <div className="alert error"><Icon name="alert" size={16} />{error}</div>}
      {info && <div className="alert ok"><Icon name="check" size={16} />{info}</div>}

      {!product && (
        <div className="grid-2">
          <div className="card">
            <div className="card-head"><Icon name="search" /><h2>Per Barcode</h2></div>
            <div className="field-inline">
              <label className="grow" style={{ margin: 0 }}>
                <input placeholder="Barcode eingeben oder scannen" value={barcode}
                  onChange={(e) => setBarcode(e.target.value)}
                  onKeyDown={(e) => e.key === "Enter" && doLookup()} autoFocus />
              </label>
              <button className="btn primary" onClick={doLookup}>Suchen</button>
            </div>

            {suggestion && (
              <div className="suggestion">
                {suggestion.image_url
                  ? <img className="thumb" src={suggestion.image_url} alt="" />
                  : <span className="thumb thumb-fallback"><Icon name="box" size={16} /></span>}
                <div className="info">
                  <div className="title">{suggestion.name}</div>
                  <div className="muted small">
                    {suggestion.brand ? `${suggestion.brand} · ` : ""}auf Open Food Facts gefunden
                    {suggestion.quantity_text ? ` · ${suggestion.quantity_text}` : ""}
                  </div>
                  <div className="muted small">
                    Noch nicht im Katalog.
                    {suggestionGroup.name && ` Gruppe: ${suggestionGroup.name}`}
                  </div>
                </div>
                {isAdmin ? (
                  <button className="btn primary" onClick={createFromSuggestion} disabled={busy}>
                    <Icon name="plus" size={16} />{busy ? "…" : "Anlegen & einlagern"}
                  </button>
                ) : (
                  <span className="muted small">Ein Administrator muss es anlegen.</span>
                )}
              </div>
            )}

            {unknownBarcode && (
              <div className="alert warn" style={{ marginTop: "var(--sp-3)" }}>
                <Icon name="alert" size={16} />
                <span>
                  Barcode <strong>{unknownBarcode}</strong> ist weder im Katalog noch bei
                  Open Food Facts.{" "}
                  {isAdmin
                    ? <Link to={`/products/new?barcode=${encodeURIComponent(unknownBarcode)}`}>Manuell anlegen</Link>
                    : "Bitte einen Administrator bitten, es anzulegen."}
                </span>
              </div>
            )}
          </div>

          <div className="card">
            <div className="card-head"><Icon name="package" /><h2>Aus Produktliste</h2></div>
            <form className="field-inline" onSubmit={doSearch}>
              <label className="grow" style={{ margin: 0 }}>
                <input placeholder="Name suchen…" value={search} onChange={(e) => setSearch(e.target.value)} />
              </label>
              <button className="btn">Suchen</button>
            </form>
            <ul className="picklist">
              {results.map((p) => (
                <li key={p.id}>
                  <button className="link-btn" onClick={() => selectProduct(p)}>
                    {p.name} <span className="muted">({fmt(p.stock / (p.unit_factor || 1))} {p.unit_name})</span>
                  </button>
                </li>
              ))}
            </ul>
          </div>
        </div>
      )}

      {product && (
        <form className="card form-narrow" onSubmit={submit}>
          <div className="selected-product">
            {product.image_url
              ? <img className="thumb" src={product.image_url} alt="" />
              : <span className="thumb thumb-fallback"><Icon name="box" size={16} /></span>}
            <div className="info">
              <div className="title">{product.name}</div>
              <div className="muted small">Bestand: {fmt(product.stock / (product.unit_factor || 1))} {product.unit_name}</div>
            </div>
            <button type="button" className="btn ghost" onClick={() => setProduct(null)}>Ändern</button>
          </div>

          <div className="row">
            <label className="grow">
              Einheit
              <select value={unit} onChange={(e) => setUnit(e.target.value)}>
                {buildUnitOptions(product, units).map((o) => <option key={o.value} value={o.value}>{o.label}</option>)}
              </select>
            </label>
            <label className="grow">
              Lagerort (optional)
              <select value={locationId} onChange={(e) => setLocationId(e.target.value)}>
                <option value="">– keiner –</option>
                {locations.map((l) => <option key={l.id} value={l.id}>{l.name}</option>)}
              </select>
            </label>
          </div>

          <div className="lines">
            <div className="lines-head">
              <span>Chargen</span>
              <span className="muted small">je Charge ein eigenes MHD</span>
            </div>
            {lines.map((line, i) => (
              <div className="line" key={i}>
                <label className="grow" style={{ margin: 0 }}>
                  {i === 0 && <span className="line-label">Menge</span>}
                  <input type="number" step="any" min="0" placeholder="Menge"
                    value={line.quantity} onChange={(e) => setLine(i, "quantity", e.target.value)}
                    autoFocus={i === 0} />
                </label>
                <label className="grow" style={{ margin: 0 }}>
                  {i === 0 && <span className="line-label">MHD (optional)</span>}
                  <input type="date" value={line.best_before}
                    onChange={(e) => setLine(i, "best_before", e.target.value)}
                    className={isExpired(line.best_before) ? "input-danger" : ""} />
                  {isExpired(line.best_before) && (
                    <span className="hint-danger"><Icon name="alert" size={12} />bereits abgelaufen</span>
                  )}
                </label>
                <button type="button" className="btn-icon danger" title="Charge entfernen"
                  onClick={() => removeLine(i)} disabled={lines.length === 1}>
                  <Icon name="trash" size={16} />
                </button>
              </div>
            ))}
            <button type="button" className="btn sm" onClick={addLine}>
              <Icon name="plus" size={14} />Weitere Charge (anderes MHD)
            </button>
          </div>

          <div className="field-inline" style={{ marginTop: "var(--sp-4)" }}>
            <button className="btn primary" disabled={busy}>
              <Icon name="checkin" size={16} />{busy ? "…" : "Einlagern"}
            </button>
            {totalQty > 0 && (
              <span className="muted small">Summe: {fmt(totalQty)} {
                buildUnitOptions(product, units).find((o) => o.value === unit)?.label || ""
              }</span>
            )}
          </div>
        </form>
      )}
    </div>
  );
}
