// Ravitaillement.jsx — Supply order view: per-service orders + summary

var { useState: useStatR, useEffect: useEffR } = React;

function line(qty, article, norm) { return { qty: qty, article: article, norm: norm, over: qty > norm }; }

var RAV_ORDERS = [
  { id:"o1", svc:"Urgences", lines:[ line(8,"Blouses patient",14), line(6,"Draps coton bio",12), line(5,"Protections",10), line(4,"Linges de toilette",10) ]},
  { id:"o2", svc:"Bloc opératoire", lines:[ line(12,"Champs opératoires",20), line(9,"Blouses chirurgicales",16), line(6,"Alèses",12) ]},
  { id:"o3", svc:"Gériatrie", lines:[ line(48,"Protections",18), line(22,"Alèses",14), line(10,"Draps coton bio",12) ]},
  { id:"o4", svc:"Maternité", lines:[ line(14,"Draps coton bio",16), line(10,"Taies d'oreiller",14), line(7,"Blouses patient",12) ]},
  { id:"o5", svc:"Cardiologie", lines:[ line(30,"Blouses patient",12), line(8,"Draps coton bio",12), line(5,"Taies d'oreiller",10) ]},
  { id:"o6", svc:"Pédiatrie", lines:[ line(9,"Draps coton bio",12), line(6,"Taies d'oreiller",10), line(4,"Linges de toilette",8) ]},
  { id:"o7", svc:"Oncologie", lines:[ line(11,"Blouses patient",14), line(8,"Protections",12), line(6,"Alèses",12) ]},
];

function computeOrder(o, qtyArr) {
  var lines = o.lines.map(function(l, i) {
    var qty = qtyArr ? qtyArr[i] : l.qty;
    return { qty: qty, article: l.article, norm: l.norm, over: qty > l.norm };
  });
  var total = lines.reduce(function(s, l) { return s + l.qty; }, 0);
  var over = lines.filter(function(l) { return l.over; });
  var worst = Math.max.apply(null, [0].concat(lines.map(function(l) { return l.norm ? l.qty / l.norm : 0; })));
  var flag = over.length ? (worst >= 2 ? "out" : "risk") : null;
  return { id: o.id, svc: o.svc, lines: lines, total: total, over: over, flag: flag };
}

function buildRavSummary(orders) {
  var map = {};
  orders.forEach(function(o) {
    o.lines.forEach(function(l) {
      if (!map[l.article]) map[l.article] = { article: l.article, qty: 0, over: false };
      map[l.article].qty += l.qty;
      if (l.over) map[l.article].over = true;
    });
  });
  return Object.values(map).sort(function(a, b) { return b.qty - a.qty; });
}

var FLAG_LABEL = { out: "Commande inhabituelle", risk: "À vérifier" };

// Inline SVGs to avoid lucide DOM-mutation crashes
function SvgChevR() { return React.createElement("svg", { viewBox:"0 0 24 24", width:14, height:14, fill:"none", stroke:"currentColor", strokeWidth:2, strokeLinecap:"round", strokeLinejoin:"round" }, React.createElement("polyline", { points:"9 18 15 12 9 6" })); }
function SvgPencil() { return React.createElement("svg", { viewBox:"0 0 24 24", width:12, height:12, fill:"none", stroke:"currentColor", strokeWidth:2, strokeLinecap:"round", strokeLinejoin:"round" }, React.createElement("path", { d:"M12 20h9" }), React.createElement("path", { d:"M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4Z" })); }
function SvgWarn() { return React.createElement("svg", { viewBox:"0 0 24 24", width:13, height:13, fill:"none", stroke:"currentColor", strokeWidth:2, strokeLinecap:"round", strokeLinejoin:"round" }, React.createElement("path", { d:"M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" }), React.createElement("line", { x1:12, y1:9, x2:12, y2:13 }), React.createElement("line", { x1:12, y1:17, x2:12.01, y2:17 })); }

function EditableQtyR({ value, locked, onChange }) {
  var [editing, setEditing] = useStatR(false);
  var [v, setV] = useStatR(value);
  useEffR(function() { setV(value); }, [value]);
  if (locked) return <span className="qval">{value}</span>;
  function commit() { var n = Math.max(0, parseInt(v, 10) || 0); onChange(n); setEditing(false); }
  if (editing) {
    return <input className="qedit" type="number" min="0" value={v} autoFocus
      onChange={function(e) { setV(e.target.value); }}
      onBlur={commit}
      onKeyDown={function(e) { if (e.key === "Enter") commit(); if (e.key === "Escape") { setV(value); setEditing(false); } }} />;
  }
  return <button className="qbtn" onClick={function() { setEditing(true); }} title="Modifier la quantité">{value}<SvgPencil /></button>;
}

function RavOrder({ o, open, onToggle, done, onValidate, onQty }) {
  return (
    <div className={"order" + (open ? " open" : "") + (done ? " done" : "")}>
      <button className="ordtop" onClick={onToggle}>
        <span className="chev"><SvgChevR /></span>
        <span className="meta">
          <span className="nm">
            {o.svc}
            {done && <span className="donechip"><Icon name="check" size={12} />Validé</span>}
            {!done && o.flag && <span className={"flagchip " + o.flag}><Icon name="triangle-alert" size={12} />{FLAG_LABEL[o.flag]}</span>}
          </span>
        </span>
        <span className="tot"><b>{o.total}</b><span>pièces</span></span>
      </button>
      <div className="ordwrap">
        <div className="ordclip">
          <div className="orddetail">
            <div className="otable">
              <div className="oth"><div>Qte</div><div>Article</div></div>
              {o.lines.map(function(l, i) {
                return (
                  <div className={"otr" + (l.over ? " over" : "")} key={i}>
                    <div className="q">
                      <EditableQtyR value={l.qty} locked={done} onChange={function(n) { onQty(i, n); }} />
                    </div>
                    <div className="a">
                      {l.article}
                      {l.over && <span className="delta" title={"Habituel ≤ " + l.norm}><Icon name="trending-up" size={12} />+{l.qty - l.norm} de plus que d'habitude</span>}
                    </div>
                  </div>
                );
              })}
            </div>
            {o.flag && (
              <div className={"flagnote" + (o.flag === "risk" ? " risk" : "")}>
                <Icon name="triangle-alert" size={16} />
                <p>
                  {o.over.length === 1
                    ? <React.Fragment>Sur <b>{o.over[0].article}</b> : +{o.over[0].qty - o.over[0].norm} de plus que d'habitude ({o.over[0].qty} demandées contre ≤ {o.over[0].norm}).</React.Fragment>
                    : <React.Fragment>{o.over.length} articles au-dessus des bornes habituelles : {o.over.map(function(l) { return l.article + " (+" + (l.qty - l.norm) + ")"; }).join(", ")}.</React.Fragment>
                  }
                  {" "}À confirmer avant validation.
                </p>
              </div>
            )}
            <div className="ordfoot">
              {done
                ? <button className="btn btn-ghost btn-sm" onClick={onValidate}><Icon name="rotate-ccw" size={15} />Annuler</button>
                : <button className="btn btn-pri btn-sm" onClick={onValidate}><Icon name="check" size={15} />Valider la commande</button>
              }
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

function RavLeftCol({ orders, validated, onValidate, onQty }) {
  var [openId, setOpenId] = useStatR("o1");
  function handleValidate(id) {
    var becoming = !validated.has(id);
    onValidate(id);
    if (becoming) {
      var idx = orders.findIndex(function(o) { return o.id === id; });
      var nextId = null;
      for (var k = 1; k < orders.length; k++) {
        var cand = orders[(idx + k) % orders.length];
        if (cand.id !== id && !validated.has(cand.id)) { nextId = cand.id; break; }
      }
      setOpenId(nextId);
    }
  }
  return (
    <div className="col-l">
      <div className="colhead"><h2>Commandes par service</h2></div>
      <div className="ordlist">
        {orders.map(function(o) {
          return <RavOrder key={o.id} o={o} open={openId === o.id} done={validated.has(o.id)}
            onValidate={function() { handleValidate(o.id); }}
            onQty={function(idx, val) { onQty(o.id, idx, val); }}
            onToggle={function() { setOpenId(function(prev) { return prev === o.id ? null : o.id; }); }} />;
        })}
      </div>
    </div>
  );
}

function RavRightCol({ orders, validated }) {
  var sel = orders.filter(function(o) { return validated.has(o.id); });
  var summary = buildRavSummary(sel);
  var grand = summary.reduce(function(s, r) { return s + r.qty; }, 0);
  var flagged = sel.filter(function(o) { return o.flag; });
  return (
    <div className="col-r">
      <div className="colhead"><h2>Résumé commande</h2></div>
      {sel.length === 0 ? (
        <div className="sumempty">
          <Icon name="clipboard-check" size={30} />
          <p>Aucune commande validée pour l'instant.<br />Validez les commandes à gauche pour les ajouter au résumé.</p>
        </div>
      ) : (
        <React.Fragment>
          <div className="summary">
            <div className="sumtable">
              <div className="sth"><div>Qte</div><div>Article</div></div>
              {summary.map(function(r) {
                return (
                  <div key={r.article} className={"strwrap" + (r.over ? " flag" : "")}>
                    <div className="str">
                      <div className="q">{r.qty}</div>
                      <div className="a">
                        {r.article}
                        {r.over && <span className="mini-flag"><SvgWarn /></span>}
                      </div>
                    </div>
                  </div>
                );
              })}
            </div>
            <div className="sumtotal">
              <span className="l">Total</span>
              <span className="v">{grand}</span>
            </div>
          </div>
          {flagged.length > 0 && (
            <div className="sumalert">
              <Icon name="triangle-alert" size={16} />
              <p><b>{flagged.length} commande{flagged.length > 1 ? "s" : ""} hors normes</b> — {flagged.map(function(o) { return o.svc; }).join(", ")}.</p>
            </div>
          )}
        </React.Fragment>
      )}
      <div className="rfoot">
        <button className="btn btn-pri" disabled={sel.length === 0}
          onClick={function() { generateBonDeLivraison(summary, grand); }}>
          <Icon name="check" size={18} />Valider
        </button>
      </div>
    </div>
  );
}

function RavitaillementView() {
  var [validated, setValidated] = useStatR(function() { return new Set(); });
  var [qtys, setQtys] = useStatR(function() {
    var m = {};
    RAV_ORDERS.forEach(function(o) { m[o.id] = o.lines.map(function(l) { return l.qty; }); });
    return m;
  });
  function toggleValidate(id) {
    setValidated(function(prev) {
      var next = new Set(prev);
      next.has(id) ? next.delete(id) : next.add(id);
      return next;
    });
  }
  function setLineQty(oid, idx, val) {
    setQtys(function(prev) {
      var copy = {};
      Object.keys(prev).forEach(function(k) { copy[k] = prev[k].slice(); });
      copy[oid][idx] = val;
      return copy;
    });
  }
  var orders = RAV_ORDERS.map(function(o) { return computeOrder(o, qtys[o.id]); });
  return (
    <div className="panel">
      <div className="rav">
        <RavLeftCol orders={orders} validated={validated} onValidate={toggleValidate} onQty={setLineQty} />
        <div className="vsep" />
        <RavRightCol orders={orders} validated={validated} />
      </div>
    </div>
  );
}

var ARTICLE_PRICES = {
  "Blouses patient": 1.80, "Draps coton bio": 2.76, "Protections": 1.60,
  "Linges de toilette": 1.45, "Champs opératoires": 3.20, "Blouses chirurgicales": 2.90,
  "Alèses": 1.54, "Taies d'oreiller": 1.25,
};
var ARTICLE_CODES = {
  "Blouses patient": "208", "Draps coton bio": "310", "Protections": "385.1",
  "Linges de toilette": "420", "Champs opératoires": "502", "Blouses chirurgicales": "510",
  "Alèses": "340", "Taies d'oreiller": "315",
};
var TVA_RATE = 8.1;

function generateBonDeLivraison(summary, grand) {
  var jsPDF = window.jspdf.jsPDF;
  var doc = new jsPDF({ unit: "mm", format: "a4" });
  var W = 210;
  var bonNo = "20" + String(Date.now()).slice(-6) + "01";
  var now = new Date();
  var dateStr = String(now.getDate()).padStart(2, "0") + "." + String(now.getMonth() + 1).padStart(2, "0") + "." + now.getFullYear();

  // --- Header: LBG ---
  doc.setFont("helvetica", "bold");
  doc.setFontSize(10);
  doc.text("Les Blanchisseries Générales LBG SA", 20, 25);
  doc.setFont("helvetica", "normal");
  doc.setFontSize(9);
  doc.text("Rue des Petits Champs 7", 20, 30);
  doc.text("Case postale 195", 20, 34);
  doc.text("1401 Yverdon-les-Bains", 20, 38);
  doc.text("Tél : +41 24 42 42 061", 20, 43);
  doc.text("Fax : +41 24 42 42 060", 20, 47);

  // --- Bon de livraison ---
  doc.setFont("helvetica", "bold");
  doc.setFontSize(11);
  doc.text("Bon de livraison " + bonNo, 20, 58);

  // --- TVA / Date / Client ---
  doc.setFont("helvetica", "normal");
  doc.setFontSize(9);
  doc.text("N° TVA", 20, 68);
  doc.text("CHE-106.019.895 TVA", 48, 68);
  doc.text("Date", 20, 73);
  doc.text(dateStr, 48, 73);
  doc.text("N° de client", 20, 78);
  doc.text("11", 48, 78);

  // --- CHUV address ---
  doc.setFont("helvetica", "normal");
  doc.setFontSize(10);
  doc.text("CENTRE HOSPITALIER", 125, 65);
  doc.setFont("helvetica", "bold");
  doc.text("UNIVERSITAIRE VAUDOIS", 125, 70);
  doc.setFont("helvetica", "normal");
  doc.text("Vestiaire central", 125, 75);
  doc.text("1011 Lausanne", 125, 80);

  // --- Page ---
  doc.setFontSize(9);
  doc.text("Page 1", 20, 92);

  // --- Table header ---
  var y = 100;
  doc.setFont("helvetica", "bold");
  doc.setFontSize(8.5);
  var cols = [20, 42, 95, 115, 135, 152, 175, W - 20];
  doc.text("Article", cols[0], y);
  doc.text("Désignation", cols[1], y);
  doc.text("Qté", cols[2], y);
  doc.text("Qté livr.", cols[3], y);
  doc.text("Unité", cols[4], y);
  doc.text("P.U. (H.T.)", cols[5], y);
  doc.text("Montant", cols[6], y);
  doc.text("TVA", cols[7] - 2, y);

  doc.text("cmde", cols[2], y + 4);

  y += 6;
  doc.setLineWidth(0.3);
  doc.line(20, y, W - 20, y);
  y += 3;

  // --- Location header ---
  doc.setFont("helvetica", "bold");
  doc.setFontSize(8.5);
  doc.text("Location", 20, y);
  y += 5;

  // --- Table rows ---
  doc.setFont("helvetica", "normal");
  doc.setFontSize(8);
  var totalMontant = 0;

  summary.forEach(function(r) {
    var code = ARTICLE_CODES[r.article] || "000";
    var prix = ARTICLE_PRICES[r.article] || 1.50;
    var montant = Math.round(r.qty * prix * 100) / 100;
    totalMontant += montant;

    doc.text(code, cols[0], y);
    doc.text(r.article.toUpperCase(), cols[1], y);
    doc.text(String(r.qty), cols[2] + 8, y, { align: "right" });
    doc.text(String(r.qty), cols[3] + 8, y, { align: "right" });
    doc.text("PCE", cols[4], y);
    doc.text(prix.toFixed(2), cols[5] + 12, y, { align: "right" });
    doc.text(montant.toFixed(2), cols[6] + 14, y, { align: "right" });
    doc.text(String(TVA_RATE), cols[7], y);
    y += 5;

    if (y > 270) {
      doc.addPage();
      y = 25;
    }
  });

  // --- Report total ---
  y += 4;
  doc.setLineWidth(0.3);
  doc.line(20, y, W - 20, y);
  y += 6;
  doc.setFont("helvetica", "normal");
  doc.setFontSize(9);
  doc.text("Report . . . . . . . . . . .", 95, y);
  doc.setFont("helvetica", "bold");
  var totalStr = totalMontant.toLocaleString("fr-CH", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  doc.text(totalStr, cols[6] + 14, y, { align: "right" });

  doc.save("bon-de-livraison-" + bonNo + ".pdf");
}

window.RavitaillementView = RavitaillementView;
window.generateBonDeLivraison = generateBonDeLivraison;
