// ============================================================
// PIANO SETTIMANALE — calendario 7 giorni × 3 pasti
// vista griglia o lista (Tweak), barra AI "vibe", azioni rapide
// ============================================================

const PASTI = ["colazione", "pranzo", "cena"];
const PASTO_ICON = { colazione: "bowl", pranzo: "flame", cena: "leaf" };

// I limiti del paziente sono GIORNALIERI: il piano può bilanciare un pranzo
// più ricco con una cena più leggera. La quota per pasto è quindi indicativa:
// il semaforo del singolo pasto scatta con tolleranza (+30% = rosso),
// mentre il giudizio vero è sulla riga del giorno (vs limite giornaliero).
function mealStatus(ratio){
  if (ratio > 1.45) return "over";  // il pasto da solo consuma gran parte del budget del giorno
  if (ratio > 1.1) return "near";
  return "ok";
}
function dayStatus(ratio){
  if (ratio > 1.0) return "over";   // oltre il limite prescritto (invalicabile)
  if (ratio > 0.9) return "near";
  return "ok";
}
const worstOf = (a, b) => a === "over" || b === "over" ? "over" : a === "near" || b === "near" ? "near" : "ok";

function MealCard({ recipe, patient, onOpen, dense, dayState }) {
  const E = window.NefroEngine;
  const { FOOD_BY_ID } = window.NefroData;
  const t = E.totals(recipe);
  const lim = patient.limiti;
  const share = recipe.pasto === "pranzo" ? 0.4 : recipe.pasto === "cena" ? 0.38 : 0.22;
  // stato peggiore tra K, P, Na, proteine (con tolleranza sulla quota pasto)
  const keys = [["potassio", "K"], ["fosforo", "P"], ["sodio", "Na"], ["proteine", "Pr"]];
  let worst = "ok";
  keys.forEach(([k]) => {worst = worstOf(worst, mealStatus(t[k] / (lim[k] * share)));});
  // coerenza col giudizio giornaliero: se la giornata è nei limiti,
  // un pasto sbilanciato è al massimo "giallo", mai rosso
  if (dayState === "ok" && worst === "over") worst = "near";
  const ingNames = recipe.ingredienti.map((i) => FOOD_BY_ID[i.id]).filter((f) => f && f.categoria !== "Grassi").map((f) => f.nome);

  const hint = [
  recipe.fonte === "ricettario" ? "Dal ricettario" : "Inventata dal generatore",
  recipe.adattata ? "quantità adattate ai limiti del paziente" : null,
  recipe.porzione ? `porzione ${recipe.porzione}%` : null,
  recipe.motivo || null].
  filter(Boolean).join(" · ");
  return (
    <button className={`meal-card mc-${worst} ${dense ? "meal-dense" : ""}`} onClick={onOpen} title={hint}>
      <div className="meal-card-top">
        <span className="meal-tag"><Icon name={PASTO_ICON[recipe.pasto]} size={13} /> {PASTO_LABEL[recipe.pasto]}</span>
        <span className={`src-tag ${recipe.fonte === "ricettario" ? "src-rec" : "src-gen"}`}
        title={recipe.fonte === "ricettario" ? "Recuperata dal ricettario" : "Inventata dal generatore"}>
          {recipe.fonte === "ricettario" ? "Ricettario" : "Inventata"}
        </span>
        <Dot status={worst} />
      </div>
      <div className="meal-name">{recipe.nome}</div>
      {recipe.cottura && <div className="meal-cottura">{recipe.cottura}</div>}
      {!dense && <div className="meal-ings">{ingNames.slice(0, 4).join(" · ")}</div>}
      <div className="meal-micro">
        <span><i>K</i>{Math.round(t.potassio)}</span>
        <span><i>P</i>{Math.round(t.fosforo)}</span>
        <span><i>Na</i>{Math.round(t.sodio)}</span>
        <span><i>kcal</i>{Math.round(t.calorie)}</span>
      </div>
    </button>);

}

function WeekTab({ patient, week, setWeek, calStyle, dirty, saving, onSave, onDownload, onRegenerate, regenerating, active, hasB, onSwitch, onGenerate2 }) {
  const E = window.NefroEngine;
  const [open, setOpen] = useState(null); // {giorno, pasto}
  const [chat, setChat] = useState([]);
  const [input, setInput] = useState("");
  const [busy, setBusy] = useState(false);
  const [chatOpen, setChatOpen] = useState(false);
  const [lastLog, setLastLog] = useState([]);     // A7: log dell'ultimo comando
  const [showLog, setShowLog] = useState(false);
  const chatRef = useRef(null);
  const Rx = window.NefroRx;

  // A5/A6: validazione clinica dell'intera settimana contro la prescrizione.
  const validation = React.useMemo(() => E.validateWeek(week, patient), [week, patient]);
  const overDays = validation.filter((d) => d.worst === "over");
  const underDays = validation.filter((d) => d.worst === "under");
  const patientAlerts = Rx ? Rx.evaluatePatient(patient) : [];
  const rxV = patient.prescrizione;

  useEffect(() => {setChat([]);setChatOpen(false);setLastLog([]);setShowLog(false);}, [patient.id]);
  useEffect(() => {if (chatRef.current) chatRef.current.scrollTop = chatRef.current.scrollHeight;}, [chat]);

  const dayTotals = (g) => {
    const tot = { potassio: 0, fosforo: 0, sodio: 0, proteine: 0, calorie: 0 };
    PASTI.forEach((p) => {const t = E.totals(g[p]);for (const k in tot) tot[k] += t[k];});
    return tot;
  };

  // stato della giornata: i totali contro i limiti GIORNALIERI del paziente
  const lim = patient.limiti;
  const dayWorst = (dt) => ["potassio", "fosforo", "sodio"].
  reduce((w, k) => worstOf(w, dayStatus(dt[k] / lim[k])), "ok");
  const dayHint = (dt) =>
  `Totali giornata vs limiti — K ${Math.round(dt.potassio)}/${lim.potassio} · P ${Math.round(dt.fosforo)}/${lim.fosforo} · Na ${Math.round(dt.sodio)}/${lim.sodio} · prot ${Math.round(dt.proteine)}/${lim.proteine} g · ${Math.round(dt.calorie)}/${lim.calorie} kcal`;

  const openRecipe = (giornoId, pasto) => setOpen({ giornoId, pasto });
  const current = open ? week.find((g) => g.id === open.giornoId)?.[open.pasto] : null;

  // totali degli ALTRI pasti del giorno aperto: il modale mostra la giornata
  // intera (altri pasti + quello in modifica) contro i limiti giornalieri
  const altriPasti = (() => {
    if (!open) return null;
    const g = week.find((x) => x.id === open.giornoId);
    if (!g) return null;
    const tot = { proteine: 0, sodio: 0, potassio: 0, fosforo: 0, calorie: 0 };
    PASTI.filter((p) => p !== open.pasto).forEach((p) => {
      const t = E.totals(g[p]);
      for (const k in tot) tot[k] += t[k];
    });
    return tot;
  })();

  const saveRecipe = (r) => {
    setWeek(week.map((g) => g.id === open.giornoId ? { ...g, [open.pasto]: r } : g));
    setOpen(null);
  };
  const deleteRecipe = (r) => {
    // sostituisce con una nuova ricetta generata (non lascia il pasto vuoto)
    const nw = E.generateWeek(patient, Date.now() % 9999);
    const fresh = nw[0][open.pasto];
    setWeek(week.map((g) => g.id === open.giornoId ? { ...g, [open.pasto]: { ...fresh } } : g));
    setOpen(null);
  };

  const send = (text) => {
    const msg = text.trim();if (!msg) return;
    setChat((c) => [...c, { role: "user", text: msg }]);
    setInput("");setBusy(true);setChatOpen(true);
    setTimeout(() => {
      const res = E.applyCommand(msg, week, patient);
      if (res.ok) setWeek(res.week);
      if (res.log && res.log.length) { setLastLog(res.log); setShowLog(true); }
      setChat((c) => [...c, { role: "ai", text: res.message }]);
      setBusy(false);
    }, 750);
  };

  const quick = ["Sostituisci il pesce a cena", "Più verdure a pranzo", "Cambia la frutta a colazione", "Rigenera la settimana"];

  return (
    <div className="week-wrap">
      <div className="week-main">
        <div className="week-head">
          <div>
            <h3 className="panel-title" style={{ fontFamily: "\"Open Sans\"", fontSize: "19px" }}>Piano settimanale</h3>
            <p className="panel-sub">
              {hasB ? "Due settimane che si alternano · " : ""}7 giorni · colazione, pranzo e cena · nei limiti di {patient.nome}
            </p>
          </div>
          <div className="btn-row">
            {hasB &&
              <div className="seg" style={{ marginRight: 4 }} title="Due settimane che si alternano per dare varietà al paziente">
                {["A", "B"].map((w) => <button key={w} className={`seg-btn ${active === w ? "on" : ""}`} onClick={() => onSwitch(w)}>Sett. {w}</button>)}
              </div>}
            <button className="btn btn-ghost" onClick={onDownload} title="Scarica il piano in Excel (salva prima le modifiche)">
              <Icon name="arrowDown" size={16} /> Scarica Excel
            </button>
            <button className="btn btn-ghost" disabled={regenerating} onClick={onRegenerate}
            title="Rigenera solo la settimana visualizzata (OR-Tools)">
              <Icon name="refresh" size={16} /> {regenerating ? "…" : "Rigenera"}
            </button>
            <button className="btn btn-ghost" disabled={regenerating} onClick={onGenerate2}
            title="Genera due settimane diverse (A e B) che si alterneranno, per dare varietà al paziente">
              <Icon name="calendar" size={16} /> {regenerating ? "…" : "Genera 2 settimane"}
            </button>
            <button className={`btn ${dirty ? "btn-primary" : "btn-ghost"}`} disabled={!dirty || saving} onClick={onSave}
            title={dirty ? "Salva la pianificazione su database" : "Il piano è già salvato"}>
              <Icon name="check" size={16} /> {saving ? "Salvataggio…" : dirty ? "Salva piano" : "Piano salvato"}
            </button>
          </div>
        </div>

        {/* —— Pannello clinico: validazione prescrizione + alert (A4/A5/A6) —— */}
        <div className="clin-panel" style={{ margin: "0 0 14px", border: "1px solid var(--line,#e5e7eb)", borderRadius: 12, overflow: "hidden" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 8, padding: "8px 12px", fontSize: 13,
            background: rxV?.validata ? "color-mix(in oklab, var(--ok,#16a34a) 10%, transparent)" : "color-mix(in oklab, var(--warn,#d97706) 12%, transparent)" }}>
            <Icon name={rxV?.validata ? "check" : "droplet"} size={15} />
            {rxV?.validata
              ? <span>Prescrizione <b>validata</b> da {rxV.validataDa} il {rxV.validataIl}.</span>
              : <span><b>Prescrizione non validata</b> — le proposte sotto sono suggerimenti del motore, da validare dal professionista (scheda «Limiti nutrizionali»).</span>}
          </div>
          <div style={{ padding: "10px 12px", display: "grid", gap: 6, fontSize: 13 }}>
            {overDays.length === 0 && underDays.length === 0 && patientAlerts.length === 0 &&
              <div style={{ color: "var(--ok,#16a34a)", display: "flex", gap: 6, alignItems: "center" }}><Icon name="check" size={14} /> Tutti i 7 giorni rientrano nella prescrizione (nessun tetto superato, nessun minimo sotto soglia).</div>}
            {overDays.map((d) => (
              <div key={"o" + d.id} style={{ color: "var(--over,#dc2626)" }}>
                <b>⚠ {d.nome}:</b> {d.alerts.filter((a) => a.livello === "over").map((a) => a.msg).join(" · ")}
              </div>))}
            {underDays.map((d) => (
              <div key={"u" + d.id} style={{ color: "var(--warn,#d97706)" }}>
                <b>▽ {d.nome} (apporto insufficiente):</b> {d.alerts.filter((a) => a.livello === "under").map((a) => a.msg).join(" · ")}
              </div>))}
            {patientAlerts.map((a, i) => (
              <div key={"p" + i} style={{ color: "var(--warn,#d97706)", display: "flex", gap: 6, alignItems: "center" }}><Icon name="droplet" size={14} /> {a.msg}</div>))}
            {lastLog.length > 0 &&
              <div style={{ marginTop: 4, borderTop: "1px dashed var(--line,#e5e7eb)", paddingTop: 6 }}>
                <button className="btn btn-ghost" style={{ padding: "2px 8px", fontSize: 12 }} onClick={() => setShowLog((s) => !s)}>
                  <Icon name={showLog ? "chevronDown" : "arrowUp"} size={13} /> Tracciabilità ultime modifiche ({lastLog.length})
                </button>
                {showLog &&
                  <ul style={{ margin: "6px 0 0", paddingLeft: 18, color: "var(--muted,#667)" }}>
                    {lastLog.map((l, i) => <li key={i}>{l.giorno ? `${l.giorno} · ${l.pasto} — ` : ""}{l.motivo}</li>)}
                  </ul>}
              </div>}
          </div>
        </div>

        {calStyle === "grid" ?
        <div className="cal-grid">
            <div className="cal-corner"></div>
            {PASTI.map((p) => <div key={p} className="cal-col-head"><Icon name={PASTO_ICON[p]} size={14} /> {PASTO_LABEL[p]}</div>)}
            {week.map((g) => {
            const dt = dayTotals(g);
            return (
          <React.Fragment key={g.id}>
                <div className="cal-day-head" title={dayHint(dt)}>
                  <span className="cal-day-name" style={{ fontFamily: "\"Open Sans\"", fontSize: "15px" }}>{g.nome}</span>
                  <span className="cal-day-kcal"><Dot status={dayWorst(dt)} /> {Math.round(dt.calorie)} kcal</span>
                </div>
                {PASTI.map((p) =>
            <div key={p} className="cal-cell">
                    <MealCard recipe={g[p]} patient={patient} dense dayState={dayWorst(dt)} onOpen={() => openRecipe(g.id, p)} />
                  </div>
            )}
              </React.Fragment>);
          })}
          </div> :

        <div className="cal-list">
            {week.map((g) => {
            const dt = dayTotals(g);
            return (
              <div key={g.id} className="cal-day-row">
                  <div className="cal-day-side" title={dayHint(dt)}>
                    <span className="cal-day-name">{g.nome}</span>
                    <div className="cal-day-mini">
                      <span className={`dv-${dayStatus(dt.potassio / lim.potassio)}`}><i>K</i>{Math.round(dt.potassio)}</span>
                      <span className={`dv-${dayStatus(dt.fosforo / lim.fosforo)}`}><i>P</i>{Math.round(dt.fosforo)}</span>
                      <span className={`dv-${dayStatus(dt.sodio / lim.sodio)}`}><i>Na</i>{Math.round(dt.sodio)}</span>
                    </div>
                  </div>
                  <div className="cal-day-meals">
                    {PASTI.map((p) => <MealCard key={p} recipe={g[p]} patient={patient} dayState={dayWorst(dt)} onOpen={() => openRecipe(g.id, p)} />)}
                  </div>
                </div>);

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

      {/* —— Modale editor ricetta —— */}
      {current &&
      <RecipeModal recipe={current} patient={patient} altriPasti={altriPasti}
      onSave={saveRecipe} onDelete={deleteRecipe} onClose={() => setOpen(null)} />
      }

      {/* —— Dock assistente AI (fisso in basso) —— */}
      <div className={`ai-dock ${chatOpen && chat.length > 0 ? "open" : ""}`}>
        {chatOpen && chat.length > 0 &&
        <div className="ai-dock-chat" ref={chatRef}>
            {chat.map((m, i) =>
          <div key={i} className={`bubble ${m.role}`}>{m.text}</div>
          )}
            {busy && <div className="bubble ai"><span className="typing"><i></i><i></i><i></i></span></div>}
          </div>
        }
        <div className="ai-dock-bar">
          <div className="ai-orb dock-orb"><Icon name="wand" size={17} /></div>
          <div className="ai-dock-center">
            <div className="ai-dock-quick">
              {quick.map((q) => <button key={q} className="quick-chip" onClick={() => send(q)}>{q}</button>)}
            </div>
            <form className="ai-dock-input" onSubmit={(e) => {e.preventDefault();send(input);}}>
              <input placeholder={`Modifica il piano di ${patient.nome} a parole — es. «questa settimana niente zucchine»`}
              value={input} onChange={(e) => setInput(e.target.value)} />
              <button type="submit" className="ai-send" disabled={!input.trim()}><Icon name="send" size={17} /></button>
            </form>
          </div>
          {chat.length > 0 &&
          <button className="ai-dock-toggle" onClick={() => setChatOpen((o) => !o)} title={chatOpen ? "Comprimi" : "Mostra conversazione"}>
              <Icon name={chatOpen ? "chevronDown" : "arrowUp"} size={18} />
            </button>
          }
        </div>
      </div>
    </div>);

}

window.WeekTab = WeekTab;