// ============================================================
// TAB: Valori ematici  +  Limiti nutrizionali
// ============================================================

function BloodTab({ patient, onChange }) {
  const { BLOOD_REF, PREVIEW_KEYS, sortedEsami, formatISO } = window.NefroData;
  const esami = sortedEsami(patient);
  const [expandedId, setExpandedId] = useState(esami[0]?.id || null);
  const [editId, setEditId] = useState(null);
  const [draft, setDraft] = useState(null);
  const fileRef = useRef(null);
  const [importing, setImporting] = useState(false);

  useEffect(() => {const e = sortedEsami(patient);setExpandedId(e[0]?.id || null);setEditId(null);setDraft(null);}, [patient.id]);

  const importExcel = async (e) => {
    const file = e.target.files && e.target.files[0];
    e.target.value = "";
    if (!file) return;
    setImporting(true);
    try {
      const r = await window.NefroAPI.importEsami(patient.id, file);
      onChange(r.patient);
      alert(`Importat${r.aggiunti === 1 ? "o" : "i"} ${r.aggiunti} preliev${r.aggiunti === 1 ? "o" : "i"}.` + (
      r.saltati ? `\n${r.saltati} righe saltate (data mancante/già presente o nessun valore).` : ""));
    } catch (err) {
      alert("Import non riuscito: " + err.message);
    } finally {
      setImporting(false);
    }
  };

  const refByKey = Object.fromEntries(BLOOD_REF.map((r) => [r.key, r]));
  const blankValues = () => Object.fromEntries(BLOOD_REF.map((r) => [r.key, Math.round((r.min + r.max) / 2 * 10) / 10]));

  const startEdit = (es) => {setEditId(es.id);setDraft({ ...es.values });setExpandedId(es.id);};
  const cancel = () => {setEditId(null);setDraft(null);};
  const saveEdit = () => {
    const nuovi = patient.esami.map((e) => e.id === editId ? { ...e, values: { ...draft } } : e);
    onChange({ ...patient, esami: nuovi });
    setEditId(null);setDraft(null);
  };
  const addEsame = () => {
    const today = new Date();
    const iso = today.toISOString().slice(0, 10);
    const base = esami[0] ? { ...esami[0].values } : blankValues();
    const nuovo = { id: "e" + Date.now().toString(36), iso, data: formatISO(iso), values: base };
    onChange({ ...patient, esami: [nuovo, ...patient.esami] });
    setExpandedId(nuovo.id);setEditId(nuovo.id);setDraft({ ...base });
  };
  const deleteEsame = (id) => {
    onChange({ ...patient, esami: patient.esami.filter((e) => e.id !== id) });
    if (editId === id) cancel();
  };

  return (
    <div className="panel">
      <div className="panel-head">
        <div>
          <h3 className="panel-title">Valori ematici</h3>
          <p className="panel-sub">{esami.length > 0 ?
            <>Storico prelievi di {patient.nome} · {esami.length} esam{esami.length === 1 ? "e" : "i"} registrat{esami.length === 1 ? "o" : "i"}</> :
            <>Nessun prelievo ancora registrato per {patient.nome}.</>}</p>
        </div>
        <div className="btn-row">
          <a className="btn btn-ghost sm" href="/api/esami-template.xlsx" style={{ textDecoration: "none" }}
          title="Scarica il modello Excel: una riga per prelievo, colonne Data + valori ematici">
            <Icon name="arrowDown" size={15} /> Modello
          </a>
          <button className="btn btn-ghost" disabled={importing} onClick={() => fileRef.current && fileRef.current.click()}
          title="Carica un Excel di prelievi (formato del modello)">
            <Icon name="arrowUp" size={16} /> {importing ? "Import in corso…" : "Importa Excel"}
          </button>
          <button className="btn btn-primary" onClick={addEsame}><Icon name="plus" size={16} /> Nuovo prelievo</button>
          <input ref={fileRef} type="file" accept=".xlsx,.xls" style={{ display: "none" }} onChange={importExcel} />
        </div>
      </div>

      {esami.length === 0 ?
      <div className="empty-state">
          <div className="empty-orb"><Icon name="droplet" size={22} /></div>
          <p>Aggiungi il primo prelievo per impostare i valori ematici.</p>
          <button className="btn btn-ghost" onClick={addEsame}><Icon name="plus" size={16} /> Aggiungi prelievo</button>
        </div> :

      <div className="esami-list">
          {esami.map((es) => {
          const open = expandedId === es.id;
          const editing = editId === es.id;
          const flags = BLOOD_REF.filter((r) => bloodStatus(r, es.values[r.key]) !== "ok").length;
          return (
            <div key={es.id} className={`esame ${open ? "esame-open" : ""}`}>
                <button className="esame-row" onClick={() => setExpandedId(open ? null : es.id)}>
                  <div className="esame-date">
                    <Icon name="calendar" size={15} />
                    <span>{es.data}</span>
                  </div>
                  <div className="esame-preview">
                    {PREVIEW_KEYS.map((k) => {
                    const r = refByKey[k];const st = bloodStatus(r, es.values[k]);
                    return (
                      <span key={k} className="prev-chip">
                          <Dot status={st === "low" ? "near" : st} />
                          <i>{r.label.replace(" (BUN)", "")}</i>{es.values[k]}<u>{r.unit}</u>
                        </span>);

                  })}
                  </div>
                  <div className="esame-end">
                    {flags > 0 ?
                  <span className="esame-flag"><Icon name="alert" size={13} />{flags}</span> :
                  <span className="esame-okflag"><Icon name="check" size={13} /></span>}
                    <span className={`esame-chevron ${open ? "up" : ""}`}><Icon name="chevronDown" size={18} /></span>
                  </div>
                </button>

                {open &&
              <div className="esame-detail">
                    <div className="esame-toolbar">
                      {editing ?
                  <><span className="esame-editing"><Icon name="edit" size={13} /> Modifica in corso</span>
                            <div className="btn-row">
                              <button className="btn btn-ghost sm" onClick={cancel}>Annulla</button>
                              <button className="btn btn-primary sm" onClick={saveEdit}><Icon name="check" size={15} /> Salva prelievo</button>
                            </div></> :
                  <><span className="esame-cnt">{flags > 0 ?
                      <span className="inline-flag"><Icon name="alert" size={13} /> {flags} valori fuori range</span> :
                      <span className="inline-ok"><Icon name="check" size={13} /> tutti nei range</span>}</span>
                            <div className="btn-row">
                              <button className="btn btn-danger-ghost sm" onClick={() => deleteEsame(es.id)}><Icon name="trash" size={15} /> Elimina</button>
                              <button className="btn btn-ghost sm" onClick={() => startEdit(es)}><Icon name="edit" size={15} /> Modifica valori</button>
                            </div></>}
                    </div>
                    <div className="blood-grid">
                      {BLOOD_REF.map((ref) => {
                    const val = editing ? draft[ref.key] : es.values[ref.key];
                    const status = bloodStatus(ref, es.values[ref.key]);
                    return (
                      <div key={ref.key} className={`blood-card s-${status}`}>
                            <div className="blood-top">
                              <span className="blood-label">{ref.label}</span>
                              <Dot status={status === "low" ? "near" : status} />
                            </div>
                            {editing ?
                        <input className="blood-input" type="number" step="0.1" value={draft[ref.key]}
                        onChange={(e) => setDraft((d) => ({ ...d, [ref.key]: parseFloat(e.target.value) }))} /> :
                        <div className="blood-value">{val}<span className="blood-unit">{ref.unit}</span></div>}
                            <div className="blood-range">rif. {ref.min}–{ref.max}</div>
                          </div>);

                  })}
                    </div>
                  </div>
              }
              </div>);

        })}
        </div>
      }
    </div>);

}

const LIMIT_DEFS = [
{ key: "proteine", label: "Proteine", unit: "g", min: 30, max: 100, step: 1, icon: "bowl", hint: "≈ 0,6–0,8 g/kg/die" },
{ key: "sodio", label: "Sodio", unit: "mg", min: 1000, max: 3000, step: 50, icon: "droplet", hint: "obiettivo < 2000 mg/die" },
{ key: "potassio", label: "Potassio", unit: "mg", min: 1500, max: 3500, step: 50, icon: "leaf", hint: "2000–3000 mg/die" },
{ key: "fosforo", label: "Fosforo", unit: "mg", min: 600, max: 1200, step: 25, icon: "flame", hint: "800–1000 mg/die" },
{ key: "calorie", label: "Energia", unit: "kcal", min: 1400, max: 2600, step: 50, icon: "flame", hint: "fabbisogno giornaliero" }];


// Parametri clinici della prescrizione mostrati nell'editor (A4).
const RX_PARAMS = [
  { key: "proteine", icon: "bowl" },
  { key: "calorie", icon: "flame" },
  { key: "sodio", icon: "droplet" },
  { key: "potassio", icon: "leaf" },
  { key: "fosforo", icon: "flame" },
  { key: "liquidi", icon: "droplet" },
  { key: "grassi_saturi", icon: "flame" },
  { key: "fosforo_inorganico", icon: "flame" },
];
const TIPO_LABEL = { max: "Tetto", min: "Minimo", range: "Intervallo", info: "Info" };
const HARD_KEYS = new Set(["sodio", "potassio", "fosforo", "liquidi"]);

// Deriva i limiti PIATTI (5 chiavi legacy) dalla prescrizione tipizzata,
// così il solver e i semafori del piano restano allineati.
function deriveLimiti(rx, patient) {
  const P = rx.parametri || {};
  const legacy = (patient && patient.limiti) || {};
  const cap = (k) => { const p = P[k]; return p ? (p.max != null ? p.max : p.min) : null; };
  const out = { ...legacy };
  ["sodio", "potassio", "fosforo"].forEach((k) => { const c = cap(k); if (c != null) out[k] = c; });
  if (P.calorie) out.calorie = P.calorie.target != null ? P.calorie.target
    : (P.calorie.min != null && P.calorie.max != null) ? Math.round((P.calorie.min + P.calorie.max) / 2)
    : (P.calorie.max != null ? P.calorie.max : P.calorie.min);
  if (P.proteine) out.proteine = P.proteine.min != null ? P.proteine.min : P.proteine.max;
  return out;
}

function activeDoctorName() {
  try {
    const id = localStorage.getItem("nefroDoctor");
    const docs = (window.NefroData && window.NefroData.DOCTORS) || [];
    const d = docs.find((x) => x.id === id) || docs[0];
    return d ? `${d.nome} ${d.cognome || ""}`.trim() : "professionista";
  } catch (e) { return "professionista"; }
}

function LimitsTab({ patient, onChange }) {
  const { FOODS, FOOD_BY_ID } = window.NefroData;
  const Rx = window.NefroRx;
  const clone = (o) => JSON.parse(JSON.stringify(o));
  const [rx, setRx] = useState(() => clone(Rx.effectivePrescription(patient)));
  const [prefs, setPrefs] = useState(() => ({
    esclusi: [...(patient.preferenze?.esclusi || [])],
    note: patient.preferenze?.note || "",
    diet: patient.diet || "",
  }));
  const [tpl, setTpl] = useState(() => Rx.templateKeyFor(patient));
  const [dirty, setDirty] = useState(false);
  const [adding, setAdding] = useState(false);
  const [q, setQ] = useState("");

  useEffect(() => {
    setRx(clone(Rx.effectivePrescription(patient)));
    setPrefs({ esclusi: [...(patient.preferenze?.esclusi || [])], note: patient.preferenze?.note || "", diet: patient.diet || "" });
    setTpl(Rx.templateKeyFor(patient));
    setDirty(false);setAdding(false);setQ("");
  }, [patient.id]);

  // Modifica di un parametro: invalida sempre la validazione (va rifirmata).
  const touchRx = (mut) => setRx((r) => { const n = clone(r); mut(n); n.validata = false; n.validataDa = null; n.validataIl = null; return n; });
  const setParam = (key, patch) => { touchRx((n) => { n.parametri[key] = { ...(n.parametri[key] || {}), ...patch }; }); setDirty(true); };
  const setTipo = (key, tipo) => { touchRx((n) => { n.parametri[key] = { ...(n.parametri[key] || {}), tipo }; }); setDirty(true); };
  const setMargine = (key, pct) => { touchRx((n) => { n.margini = { ...(n.margini || {}) }; n.margini[key] = (parseFloat(pct) || 0) / 100; }); setDirty(true); };
  const setPref = (k, v) => {setPrefs((p) => ({ ...p, [k]: v }));setDirty(true);};
  const addEscluso = (id) => {setPrefs((p) => ({ ...p, esclusi: [...p.esclusi, id] }));setDirty(true);setAdding(false);setQ("");};
  const removeEscluso = (id) => {setPrefs((p) => ({ ...p, esclusi: p.esclusi.filter((x) => x !== id) }));setDirty(true);};

  const applyTemplate = () => {
    const t = Rx.prescriptionFromTemplate(tpl, patient);
    if (t) { setRx(clone(t)); setDirty(true); }
  };

  const persist = (rxToSave) => {
    onChange({
      ...patient,
      prescrizione: rxToSave,
      limiti: deriveLimiti(rxToSave, patient),
      diet: prefs.diet.trim() ? prefs.diet.trim() : undefined,
      preferenze: { ...(patient.preferenze || {}), esclusi: prefs.esclusi, note: prefs.note.trim() },
    });
    setDirty(false);
  };
  const save = () => persist(rx);
  const validate = () => {
    const v = clone(rx);
    v.validata = true; v.validataDa = activeDoctorName();
    v.validataIl = new Date().toISOString().slice(0, 10); v.daValidare = false;
    setRx(v); persist(v);
  };

  const resetPatientPw = async () => {
    const pw = prompt(`Nuova password di accesso per ${patient.nome} ${patient.cognome}:`);
    if (!pw) return;
    try { await window.NefroAPI.setPatientCredentials(patient.id, { password: pw }); alert("Password del paziente aggiornata."); }
    catch (e) { alert("Non riuscito: " + e.message); }
  };
  const changePatientUser = async () => {
    const u = prompt("Nuovo username del paziente:", patient.username || "");
    if (!u) return;
    try { await window.NefroAPI.setPatientCredentials(patient.id, { username: u }); alert(`Username aggiornato in «${u.trim().toLowerCase()}». Ricarica la pagina per vederlo.`); }
    catch (e) { alert("Non riuscito: " + e.message); }
  };

  const matches = FOODS.filter((f) => {
    if (prefs.esclusi.includes(f.id)) return false;
    if (!q) return true;
    return f.nome.toLowerCase().includes(q.toLowerCase()) || f.categoria.toLowerCase().includes(q.toLowerCase());
  }).slice(0, 30);

  const validata = rx.validata;
  const daValidare = rx.daValidare;

  return (
    <div className="panel">
      <div className="panel-head">
        <div>
          <h3 className="panel-title" style={{ fontSize: "20px", fontFamily: "\"Open Sans\"" }}>Prescrizione nutrizionale</h3>
          <p className="panel-sub">Vincoli clinici che il motore rispetta senza superarli. Ogni parametro può essere un tetto invalicabile, un minimo, un intervallo-obiettivo o solo informativo.</p>
        </div>
        <div className="btn-row">
          <button className={`btn btn-ghost ${dirty ? "" : "btn-disabled"}`} disabled={!dirty} onClick={save}>Salva bozza</button>
          <button className="btn btn-primary" onClick={validate}><Icon name="check" size={16} /> Valida prescrizione</button>
        </div>
      </div>

      {/* Stato validazione (A4) */}
      <div className={`rx-status ${validata ? "rx-ok" : "rx-draft"}`} style={{ display: "flex", alignItems: "center", gap: 8, padding: "8px 12px", borderRadius: 10, margin: "0 0 12px", fontSize: 13,
        background: validata ? "color-mix(in oklab, var(--ok, #16a34a) 12%, transparent)" : "color-mix(in oklab, var(--warn, #d97706) 14%, transparent)" }}>
        <Icon name={validata ? "check" : "droplet"} size={15} />
        {validata
          ? <span>Prescrizione <b>validata</b> da {rx.validataDa} il {rx.validataIl}. Il motore opera solo entro questi vincoli.</span>
          : <span><b>Bozza non validata</b>{daValidare ? " — valori indicativi da template, da rivedere e validare dal nefrologo." : " — modifiche non ancora firmate dal professionista."}</span>}
      </div>

      {/* A8 — template per stadio/trattamento */}
      <div className="rx-template" style={{ display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap", margin: "0 0 14px", fontSize: 13, color: "var(--muted, #667)" }}>
        <Icon name="sliders" size={15} />
        <span>Template stadio/trattamento:</span>
        <select className="field-input" style={{ width: "auto", minWidth: 220 }} value={tpl} onChange={(e) => setTpl(e.target.value)}>
          {Object.keys(Rx.TEMPLATES).map((k) => <option key={k} value={k}>{Rx.TEMPLATES[k].label}</option>)}
        </select>
        <button className="btn btn-ghost" onClick={applyTemplate}>Applica</button>
        <span style={{ fontStyle: "italic" }}>valori indicativi (KDOQI) — da validare</span>
      </div>

      <div className="limits-list" style={{ display: "grid", gap: 8 }}>
        {RX_PARAMS.map((d) => {
          const meta = Rx.NUTRIENT_META[d.key] || { label: d.key, unit: "" };
          const p = rx.parametri[d.key] || { tipo: meta.verso === "min" ? "min" : meta.verso === "target" ? "range" : meta.verso === "info" ? "info" : "max" };
          const showMax = p.tipo === "max" || p.tipo === "range";
          const showMin = p.tipo === "min" || p.tipo === "range";
          const showMargin = p.tipo === "max" && HARD_KEYS.has(d.key);
          return (
            <div key={d.key} className="limit-row" style={{ alignItems: "center" }}>
              <div className="limit-ico"><Icon name={d.icon} size={18} /></div>
              <div className="limit-main">
                <div className="limit-top">
                  <span className="limit-label">{meta.label}{meta.a3 && <span className="field-opt" title="Parametro A3: dati stimati, da validare"> · A3</span>}</span>
                  <span className="limit-hint">{meta.unit}</span>
                </div>
                <div className="seg" style={{ marginTop: 6 }}>
                  {["max", "min", "range", "info"].map((tp) => (
                    <button key={tp} className={`seg-btn ${p.tipo === tp ? "on" : ""}`} onClick={() => setTipo(d.key, tp)}>{TIPO_LABEL[tp]}</button>
                  ))}
                </div>
              </div>
              <div className="limit-val" style={{ display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap", justifyContent: "flex-end" }}>
                {showMin && <label style={{ display: "flex", flexDirection: "column", fontSize: 11, color: "var(--muted,#667)" }}>min
                  <input className="limit-num" type="number" value={p.min ?? ""} onChange={(e) => setParam(d.key, { min: parseFloat(e.target.value) })} /></label>}
                {showMax && <label style={{ display: "flex", flexDirection: "column", fontSize: 11, color: "var(--muted,#667)" }}>{p.tipo === "range" ? "max" : "tetto"}
                  <input className="limit-num" type="number" value={p.max ?? ""} onChange={(e) => setParam(d.key, { max: parseFloat(e.target.value) })} /></label>}
                {showMargin && <label style={{ display: "flex", flexDirection: "column", fontSize: 11, color: "var(--muted,#667)" }} title="Tolleranza clinica: 0 = tetto invalicabile">margine %
                  <input className="limit-num" type="number" min="0" max="20" value={Math.round((rx.margini?.[d.key] || 0) * 100)} onChange={(e) => setMargine(d.key, e.target.value)} /></label>}
                {p.tipo === "info" && <span className="limit-unit" style={{ fontStyle: "italic" }}>solo informativo</span>}
              </div>
            </div>);
        })}
      </div>

      <div className="prefs-box" style={{ marginTop: 18 }}>
        <div className="prefs-head" style={{ display: "flex", alignItems: "center", gap: 6 }}><Icon name="leaf" size={16} /> Preferenze e abitudini del paziente <span className="field-opt">(livello separato dai vincoli clinici)</span></div>
        <div className="prefs-edit">
          <label className="field">
            <span className="field-label">Regime alimentare <span className="field-opt">(facoltativo)</span></span>
            <input className="field-input" value={prefs.diet} onChange={(e) => setPref("diet", e.target.value)}
            placeholder="es. vegetariana, iposodica…" />
          </label>

          <div className="field">
            <span className="field-label">Alimenti esclusi <span className="field-opt">(mai proposti nei piani)</span></span>
            <div className="excl-chips">
              {prefs.esclusi.map((id) => {
                const f = FOOD_BY_ID[id];
                return (
                  <span key={id} className="tag tag-over excl-chip">
                    no {f ? f.nome.toLowerCase() : id}
                    <button onClick={() => removeEscluso(id)} title="Rimuovi esclusione"><Icon name="x" size={12} /></button>
                  </span>);
              })}
              <button className="side-new" style={{ marginTop: 0 }} onClick={() => setAdding((a) => !a)}>
                <Icon name="plus" size={14} /> Escludi alimento
              </button>
            </div>
            {adding &&
            <div className="add-pop">
                <div className="add-search">
                  <Icon name="search" size={16} />
                  <input autoFocus placeholder="Cerca l'alimento da escludere…" value={q} onChange={(e) => setQ(e.target.value)} />
                  <button className="icon-btn sm" onClick={() => {setAdding(false);setQ("");}}><Icon name="x" size={16} /></button>
                </div>
                <div className="add-results">
                  {matches.map((f) =>
                  <button key={f.id} className="add-item" onClick={() => addEscluso(f.id)}>
                      <span className="ing-cat-dot" style={{ background: `oklch(0.62 0.13 ${catHue(f.categoria)})` }}></span>
                      <span className="add-item-name">{f.nome}</span>
                      <span className="add-item-cat">{f.categoria}</span>
                    </button>
                  )}
                  {!matches.length && <div className="add-empty">Nessun alimento trovato.</div>}
                </div>
              </div>
            }
          </div>

          <label className="field">
            <span className="field-label">Note e restrizioni</span>
            <textarea className="field-input field-textarea" value={prefs.note}
            onChange={(e) => setPref("note", e.target.value)}
            placeholder="Allergie, alimenti non graditi, indicazioni cliniche…" />
          </label>
        </div>
      </div>

      {/* Accesso del paziente (login riservato) */}
      <div className="prefs-box" style={{ marginTop: 14 }}>
        <div className="prefs-head" style={{ display: "flex", alignItems: "center", gap: 6 }}><Icon name="users" size={16} /> Accesso del paziente <span className="field-opt">(il paziente vede solo il proprio piano)</span></div>
        <div style={{ display: "flex", alignItems: "center", gap: 14, flexWrap: "wrap", padding: "6px 2px 0" }}>
          <div><div className="field-label">Username</div><code style={{ fontSize: 14, color: "var(--brand,#2f5233)" }}>{patient.username || "—"}</code></div>
          <button className="btn btn-ghost" onClick={resetPatientPw}>Reimposta password</button>
          <button className="btn btn-ghost" onClick={changePatientUser}>Cambia username</button>
        </div>
        <p className="form-hint" style={{ marginTop: 8 }}><Icon name="alert" size={13} /> Password iniziale di default: «paziente». Comunicala al paziente e invitalo a cambiarla al primo accesso.</p>
      </div>
    </div>);

}

Object.assign(window, { BloodTab, LimitsTab });