/* =========================================================
   ANTARES — Sensazioni, Decisioni, Da fare (db/26)
   La sensazione è un dato: si registra in dieci secondi su un preventivo,
   un progetto, una decisione o una cosa da fare, ALLA CIECA (quella
   dell'altro si vede solo dopo aver registrato la propria: lo impone il
   database), e a cose chiuse si confronta con com'è andata davvero.
   Il viola è riservato alle sensazioni: dove compare si parla di intuito.
   Conti senza interfaccia in js/sensazioni.js.
   ========================================================= */

const { useState: useS7, useMemo: useM7 } = React;
const { fmt: fmt7 } = window.AntaresData;
const Icon7 = window.AntaresScreens1.Icon;
const { Modal: Modal7, EmptyState: Empty7, progettoOptionsByYear: progOpt7 } = window.AntaresUI;
const SX = window.AntaresSensazioni;

const TIPI_OGGETTO = {
  preventivo: "Preventivo", progetto: "Progetto", decisione: "Decisione", da_fare: "Da fare",
};
const oggiIso7 = () => {
  const d = new Date();
  return d.getFullYear() + "-" + String(d.getMonth() + 1).padStart(2, "0") + "-" + String(d.getDate()).padStart(2, "0");
};
const dataIt7 = (iso) => iso ? String(iso).slice(0, 10).split("-").reverse().join("/") : "";
const giorniDa7 = (iso) => Math.round((new Date(String(iso).slice(0, 10) + "T12:00:00") - new Date(oggiIso7() + "T12:00:00")) / 86400000);

function nomeUtente7(id) {
  const u = (window.AntaresData.UTENTI || []).find(x => x.id === id);
  if (!u) return id === window.AntaresData.IO ? "Tu" : "Un utente";
  return u.nome || String(u.email || "").split("@")[0];
}
const inizialeUtente7 = (id) => (nomeUtente7(id)[0] || "?").toUpperCase();

// cosa è l'oggetto, per il diario e le liste
function descriviOggetto(tipo, id) {
  const D = window.AntaresData;
  if (tipo === "preventivo") {
    const p = Object.values(D.PREVENTIVI || {}).find(x => String(x.preventivoId) === String(id));
    return { titolo: p ? p.progetto : "Preventivo", progettoId: p ? Object.keys(D.PREVENTIVI).find(k => D.PREVENTIVI[k] === p) : null };
  }
  if (tipo === "progetto") {
    const p = (D.PROGETTI || []).find(x => x.id === id);
    return { titolo: p ? p.nome : id, progettoId: id };
  }
  if (tipo === "decisione") {
    const d = (D.DECISIONI || []).find(x => x.id === id);
    return { titolo: d ? d.titolo : "Decisione eliminata", progettoId: d && d.progetto_id };
  }
  const t = (D.DA_FARE || []).find(x => x.id === id);
  return { titolo: t ? t.titolo : "Cosa da fare eliminata", progettoId: t && t.progetto_id };
}

// margine reale (% sul ricavo) del progetto, se c'è: va con l'esito
function margineReale7(progettoId) {
  const m = (window.AntaresData.MARGINI || []).find(x => x.id === progettoId);
  return m && m.ricavi > 0 ? Math.round(m.pct * 10) / 10 : null;
}

// un oggetto è "chiuso" (e quindi da rivedere se manca l'esito) quando…
function oggettoChiuso(tipo, id) {
  const D = window.AntaresData;
  if (tipo === "decisione") { const d = (D.DECISIONI || []).find(x => x.id === id); return !!d && d.stato !== "aperta"; }
  if (tipo === "da_fare") { const t = (D.DA_FARE || []).find(x => x.id === id); return !!t && t.fatto; }
  const progettoId = descriviOggetto(tipo, id).progettoId;
  if (!progettoId) return false;
  const p = (D.PROGETTI || []).find(x => x.id === progettoId);
  if (p && /chius|conclus|complet/i.test(p.stato || "")) return true;
  return (D.CONSUNTIVI || []).some(c => c.stato === "saldato" && (c.progetti || []).some(x => x.progettoId === progettoId));
}

function Scala({ v }) {
  return (
    <span className={"sx-scala" + (v <= 2 ? " neg" : "")} title={SX.ETICHETTE[v]}>
      {[1, 2, 3, 4, 5].map(i => <i key={i} className={i <= v ? "f" : ""} />)}
    </span>
  );
}

/* ============================================================
   REGISTRA UNA SENSAZIONE (≈ 10 secondi)
   ============================================================ */
function SensazioneModal({ tipo, id, versione, titolo, onClose, onSaved }) {
  const [punteggio, setPunteggio] = useS7(0);
  const [parole, setParole] = useS7([]);
  const [nota, setNota] = useS7("");
  const [prima, setPrima] = useS7(true);
  const [busy, setBusy] = useS7(false);
  const [err, setErr] = useS7("");
  const D = window.AntaresData;
  const altri = (D.UTENTI || []).filter(u => u.id !== D.IO).map(u => u.nome || u.email.split("@")[0]);

  const parola = (w) => setParole(p => p.includes(w) ? p.filter(x => x !== w) : (p.length >= 2 ? [p[1], w] : [...p, w]));

  const registra = async () => {
    if (!punteggio) { setErr("Scegli come ti senti"); return; }
    setBusy(true);
    const { error } = await window.AntaresStore.salvaSensazione({
      target_type: tipo, target_id: String(id), target_versione: versione || null,
      punteggio, parole, nota: nota.trim() || null, prima_dei_numeri: prima,
    });
    setBusy(false);
    if (error) { setErr(error.message); return; }
    await window.AntaresStore.refresh("sensazioni");
    onSaved && onSaved();
  };

  return (
    <Modal7 title="Nuova sensazione" onClose={onClose} width={520}
      footer={<button type="button" className="btn sx-btn" style={{ flex: 1, justifyContent: "center", minHeight: 44 }} onClick={registra} disabled={busy}>
        {busy ? "Registro…" : "Registra sensazione"}
      </button>}
    >
      <div className="sx-modale">
        <div>
          <div className="sx-tipo">{TIPI_OGGETTO[tipo]}{versione ? " · " + versione : ""}</div>
          <div style={{ fontWeight: 600 }}>{titolo}</div>
        </div>
        {err && <div className="login-error">{err}</div>}
        <div className="sx-domanda">Come ti senti, a pelle?</div>
        <div className="sx-facce">
          {[1, 2, 3, 4, 5].map(i => (
            <button key={i} type="button" className={punteggio === i ? "on" : ""} onClick={() => setPunteggio(i)}>
              <i><u style={{ width: 8 + i * 6, height: 8 + i * 6 }} /></i>{SX.ETICHETTE[i]}
            </button>
          ))}
        </div>
        <div>
          <div className="sx-tipo" style={{ marginBottom: 8 }}>Che parola la descrive? <span className="muted">(al massimo due)</span></div>
          <div className="sx-chips">
            {SX.PAROLE.map(w => (
              <button key={w} type="button" className={parole.includes(w) ? "on" : ""} onClick={() => parola(w)}>{w}</button>
            ))}
          </div>
        </div>
        <label className="sx-toggle">
          <span>
            <b>Prima di guardare i numeri</b>
            <small>Le sensazioni "a pelle" contano di più nelle statistiche</small>
          </span>
          <input type="checkbox" checked={prima} onChange={e => setPrima(e.target.checked)} />
        </label>
        <textarea className="textarea" rows={2} placeholder="Una frase, se vuoi" value={nota} onChange={e => setNota(e.target.value)} />
        {altri.length > 0 && (
          <div className="sx-lock"><Icon7 name="lock" size={14} />{altri.join(" e ")} {altri.length > 1 ? "vedranno" : "vedrà"} la tua solo dopo aver registrato la sua.</div>
        )}
      </div>
    </Modal7>
  );
}

/* ============================================================
   PANNELLO SENSAZIONI di un oggetto (preventivo, decisione, …)
   ============================================================ */
function PannelloSensazioni({ tipo, id, versione, titolo, compatto }) {
  const D = window.AntaresData;
  const [apri, setApri] = useS7(false);
  const [busy, setBusy] = useS7(false);
  const [, ridisegna] = useS7(0);
  if (!D.SENS_PRONTA || !id) return null;

  const righe = SX.suOggetto(D.SENSAZIONI, tipo, id);
  const tutteUltime = SX.perUtente(righe, "ultima");
  const mia = tutteUltime[D.IO];
  const chi = (D.SENS_CHI || []).filter(c => c.target_type === tipo && String(c.target_id) === String(id));
  const esito = (D.SENS_ESITI || []).find(e => e.target_type === tipo && String(e.target_id) === String(id));
  // alla cieca: il database già non manda le altrui; qui lo si ripete per sicurezza
  const visibili = !!(mia || esito);
  const ultime = visibili ? tutteUltime : (mia ? { [D.IO]: mia } : {});
  const nascosti = chi.filter(c => c.user_id !== D.IO && !ultime[c.user_id]);
  const altri = Object.values(ultime).filter(s => s.user_id !== D.IO);
  const disc = SX.discordanza(ultime);
  const progettoId = descriviOggetto(tipo, id).progettoId;

  const registraEsito = async (e) => {
    setBusy(true);
    const { error } = await window.AntaresStore.salvaEsito({
      target_type: tipo, target_id: String(id), esito: e, margine_finale: margineReale7(progettoId),
    });
    setBusy(false);
    if (error) { alert("Errore: " + error.message); return; }
    await window.AntaresStore.refresh("sensazioni");
    ridisegna(x => x + 1);
  };

  const riga = (s) => (
    <div className="sx-riga" key={s.id}>
      <div className="sx-riga-top">
        <span className="avatar-sm">{inizialeUtente7(s.user_id)}</span>
        <b>{s.user_id === D.IO ? "Tu" : nomeUtente7(s.user_id)}</b>
        <small>{dataIt7(s.created_at)}{s.prima_dei_numeri ? " · prima dei numeri" : ""}{s.target_versione ? " · " + s.target_versione : ""}</small>
      </div>
      <div className="sx-riga-top">
        <Scala v={s.punteggio} />
        <span className={"sx-etichetta" + (s.punteggio <= 2 ? " neg" : "")}>{SX.ETICHETTE[s.punteggio]}</span>
        {(s.parole || []).map(w => <span key={w} className="sx-parola">{w}</span>)}
      </div>
      {s.nota && <q className="sx-frase">{s.nota}</q>}
    </div>
  );

  return (
    <div className={"sx-card" + (compatto ? " compatto" : "")}>
      <div className="sx-head">
        <Icon7 name="spark" size={18} />
        <b>Sensazioni</b>
        {versione && <span className="sx-tipo">{versione}</span>}
        {/* a esito registrato non si aggiunge più nulla: si saprebbe già com'è andata */}
        {!esito && (
          <button type="button" className="btn sx-btn-ghost" onClick={() => setApri(true)}>
            <Icon7 name="plus" size={13} />{mia ? "Aggiorna la tua" : "Registra la tua"}
          </button>
        )}
      </div>
      <div className="sx-corpo">
        {mia ? riga(mia) : (
          <div className="sx-riga sx-vuota">Non hai ancora registrato la tua sensazione.</div>
        )}
        {altri.map(riga)}
        {nascosti.map(c => (
          <div className="sx-riga sx-vuota" key={c.user_id}>
            <Icon7 name="lock" size={14} /> {nomeUtente7(c.user_id)} ha registrato la sua il {dataIt7(c.ultima)}: registra la tua per vederla.
          </div>
        ))}
      </div>
      {disc >= 2 && (
        <div className="sx-disc">
          <Icon7 name="alert" size={16} />
          <span><b>Sensazioni distanti di {disc} punti.</b> Parlatene prima di {tipo === "decisione" ? "decidere" : "inviare o andare avanti"}.</span>
        </div>
      )}
      <div className="sx-piede">
        {esito ? (
          <>
            <span>Esito: <b>{SX.ESITI[esito.esito]}</b>{esito.margine_finale != null ? " · margine " + String(esito.margine_finale).replace(".", ",") + "%" : ""}</span>
            {mia && <button type="button" className="link-btn" disabled={busy} onClick={async () => {
              if (!confirm("Togliere l'esito? Le sensazioni torneranno alla cieca per chi non ha registrato la sua.")) return;
              await window.AntaresStore.eliminaEsito(tipo, String(id)); await window.AntaresStore.refresh("sensazioni"); ridisegna(x => x + 1);
            }}>cambia</button>}
          </>
        ) : mia ? (
          <>
            <span>{oggettoChiuso(tipo, id) ? "Com'è andata davvero?" : "Esito da registrare a fine lavoro"}</span>
            <span className="row" style={{ gap: 6 }}>
              {Object.entries(SX.ESITI).map(([k, l]) => (
                <button key={k} type="button" className="btn" style={{ minHeight: 28, padding: "3px 9px", fontSize: 12 }} disabled={busy} onClick={() => registraEsito(k)}>{l}</button>
              ))}
            </span>
          </>
        ) : <span>{chi.length ? "L'esito lo registra chi ha già dato la sua sensazione." : "Nessuna sensazione ancora."}</span>}
      </div>
      {apri && <SensazioneModal tipo={tipo} id={id} versione={versione} titolo={titolo}
        onClose={() => setApri(false)} onSaved={() => { setApri(false); ridisegna(x => x + 1); }} />}
    </div>
  );
}

// riassunto in una riga per le liste: scale di ciascuno, o lucchetto se alla cieca
function SensazioniInRiga({ tipo, id }) {
  const D = window.AntaresData;
  if (!D.SENS_PRONTA) return null;
  const tutte = SX.perUtente(SX.suOggetto(D.SENSAZIONI, tipo, id), "ultima");
  const chi = (D.SENS_CHI || []).filter(c => c.target_type === tipo && String(c.target_id) === String(id));
  const esito = (D.SENS_ESITI || []).some(e => e.target_type === tipo && String(e.target_id) === String(id));
  const ultime = tutte[D.IO] || esito ? tutte : {};
  const utenti = [...new Set([...Object.keys(tutte), ...chi.map(c => c.user_id)])];
  if (!utenti.length) return <span className="muted" style={{ fontSize: 12 }}>—</span>;
  return (
    <span className="sx-inriga">
      {utenti.map(u => (
        <span key={u} title={nomeUtente7(u)}>
          <span className="avatar-sm">{inizialeUtente7(u)}</span>
          {ultime[u] ? <Scala v={ultime[u].punteggio} /> : <Icon7 name="lock" size={12} />}
        </span>
      ))}
      {SX.discordanza(ultime) >= 2 && <span className="pill yellow">discordanti</span>}
    </span>
  );
}

function MigrazioneMancante7({ titolo }) {
  return (
    <div className="card">
      <Empty7 title={titolo + " non è ancora attiva"}>
        Serve la migrazione del database <code>db/26_sensazioni.sql</code> (sensazioni, decisioni e cose da fare).
      </Empty7>
    </div>
  );
}

/* ============================================================
   PAGINA SENSAZIONI (Intuito)
   ============================================================ */
function Sensazioni() {
  const D = window.AntaresData;
  const [filtro, setFiltro] = useS7("tutte");
  const [dettaglio, setDettaglio] = useS7(null); // {tipo,id}
  const [nuova, setNuova] = useS7(false);

  const testata = (
    <div className="page-head">
      <div className="page-title-block">
        <span className="eyebrow">Quello che sentiamo prima dei numeri, e se avevamo ragione</span>
        <h1 className="h1">Sensazioni</h1>
      </div>
      {D.SENS_PRONTA && (
        <div className="page-actions">
          <button className="btn sx-btn" onClick={() => setNuova(true)}><Icon7 name="plus" size={14} />Nuova sensazione</button>
        </div>
      )}
    </div>
  );
  if (!D.SENS_PRONTA) return <div className="stack">{testata}<MigrazioneMancante7 titolo="La pagina Sensazioni" /></div>;

  const anno = new Date().getFullYear();
  const st = SX.statistiche(D.SENSAZIONI, D.SENS_ESITI, anno);
  // gli oggetti "visti" da me: quelli con sensazioni leggibili + quelli dove solo l'altro ha registrato
  const ogg = SX.oggetti(D.SENSAZIONI, D.SENS_ESITI);
  const visti = new Set(ogg.map(o => o.tipo + ":" + o.id));
  (D.SENS_CHI || []).forEach(c => {
    const k = c.target_type + ":" + c.target_id;
    if (!visti.has(k)) { visti.add(k); ogg.push({ tipo: c.target_type, id: c.target_id, ultime: {}, prime: {}, righe: [], esito: null, discordanza: 0, ultima: String(c.ultima) }); }
  });
  ogg.sort((a, b) => b.ultima.localeCompare(a.ultima));
  const filtrati = ogg.filter(o => filtro === "tutte" || o.tipo === filtro);
  const daRivedere = ogg.filter(o => !o.esito && oggettoChiuso(o.tipo, o.id));
  const pct = (n, d) => (d ? Math.round((n / d) * 100) : 0);
  const fmtPctX = (v) => v == null ? "—" : String(Math.round(v * 10) / 10).replace(".", ",") + "%";

  const statoOggetto = (o) => {
    if (o.esito) {
      const a = Object.values(o.prime).map(s => SX.azzeccata(s.punteggio, o.esito.esito)).filter(x => x !== null);
      return <span className="sx-pill">{SX.ESITI[o.esito.esito]}{a.length ? " · azzeccata " + a.filter(Boolean).length + "/" + a.length : ""}</span>;
    }
    if (o.discordanza >= 2 && o.ultime[D.IO]) return <span className="pill yellow">Discordanti</span>;
    const chi = new Set((D.SENS_CHI || []).filter(c => c.target_type === o.tipo && String(c.target_id) === String(o.id)).map(c => c.user_id));
    const manca = (D.UTENTI || []).filter(u => !chi.has(u.id));
    if (manca.length && manca.length < (D.UTENTI || []).length) return <span className="pill">Manca {manca.map(u => u.nome || u.email.split("@")[0]).join(", ")}</span>;
    if (Object.keys(o.ultime).length >= 2) return <span className="pill teal">Concordi</span>;
    return <span className="pill">In attesa</span>;
  };

  return (
    <div className="stack">
      {testata}
      <div className="kpi-grid">
        <div className="kpi">
          <div className="kpi-label">Registrate nel {anno}</div>
          <div className="kpi-value">{st.registrate}</div>
          <div className="kpi-sub">su {ogg.length} tra preventivi, progetti, decisioni e cose da fare</div>
        </div>
        <div className="kpi">
          <div className="kpi-label">In attesa di esito</div>
          <div className="kpi-value">{st.inAttesa}</div>
          <div className="kpi-sub">{daRivedere.length ? daRivedere.length + " da rivedere ora" : "nessuna da rivedere"}</div>
        </div>
        <div className="kpi sx-kpi">
          <div className="kpi-label">L'intuito ci azzecca</div>
          <div className="kpi-value">{st.azzeccate.pct == null ? "—" : st.azzeccate.pct + "%"}</div>
          <div className="kpi-sub">{st.azzeccate.prove ? st.azzeccate.centri + " esiti su " + st.azzeccate.prove : "servono esiti registrati"}</div>
        </div>
        <div className="kpi">
          <div className="kpi-label">Sensazioni discordanti</div>
          <div className="kpi-value">{st.discordanti.n}</div>
          <div className="kpi-sub">{st.discordanti.finitePeggio} finite peggio del previsto</div>
        </div>
      </div>

      <div className="sx-due">
        <div className="card">
          <div className="card-head">
            <h3 className="h3">Diario <span className="muted" style={{ fontFamily: "var(--sans)", fontSize: 12 }}>tutto ciò che ha una sensazione</span></h3>
            <div className="segmented compact">
              {[["tutte", "Tutte"], ["preventivo", "Preventivi"], ["progetto", "Progetti"], ["decisione", "Decisioni"], ["da_fare", "Da fare"]].map(([k, l]) => (
                <button key={k} type="button" className={filtro === k ? "active" : ""} onClick={() => setFiltro(k)}>{l}</button>
              ))}
            </div>
          </div>
          <div className="table-wrap">
            <table className="table">
              <thead><tr><th>Su cosa</th><th>Sensazioni</th><th>Parole</th><th>Stato</th></tr></thead>
              <tbody>
                {filtrati.length === 0 && (
                  <tr><td colSpan={4} className="empty">Ancora nessuna sensazione. Registrane una con "Nuova sensazione", o dal pannello viola nei preventivi e nelle decisioni.</td></tr>
                )}
                {filtrati.map(o => (
                  <tr key={o.tipo + o.id} className="pn-riga" onClick={() => setDettaglio({ tipo: o.tipo, id: o.id })}>
                    <td><div className="sx-tipo">{TIPI_OGGETTO[o.tipo]}</div>{descriviOggetto(o.tipo, o.id).titolo}</td>
                    <td><SensazioniInRiga tipo={o.tipo} id={o.id} /></td>
                    <td className="muted">{[...new Set(Object.values(o.ultime).filter(s => o.esito || o.ultime[D.IO] || s.user_id === D.IO).flatMap(s => s.parole || []))].join(" / ") || "—"}</td>
                    <td>{statoOggetto(o)}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>

        <div className="stack">
          <div className="card">
            <div className="card-head"><h3 className="h3">Cosa dice il passato</h3></div>
            <div className="card-body">
              <div className="sx-confronto">
                <div><small>Partiti con sensazione buona</small><b className="pos">{fmtPctX(st.margineBuona.media)}</b><small>margine medio · {st.margineBuona.n} esiti</small></div>
                <div><small>Partiti con sensazione pesante</small><b className="neg">{fmtPctX(st.marginePesante.media)}</b><small>margine medio · {st.marginePesante.n} esiti</small></div>
              </div>
              <div className="sx-barre">
                {(D.UTENTI || []).map(u => {
                  const p = st.perPersona[u.id];
                  const v = p ? pct(p.centri, p.prove) : null;
                  return (
                    <div className="sx-barra" key={u.id}>
                      <span>{u.nome || u.email.split("@")[0]}</span>
                      <div className="bar"><i style={{ width: (v || 0) + "%" }} /></div>
                      <b>{v == null ? "—" : v + "%"}</b>
                    </div>
                  );
                })}
              </div>
              <p className="help" style={{ marginTop: 10 }}>
                Conta la prima sensazione di ciascuno: azzeccata se era pesante ed è finita peggio, o era buona ed è finita come sentivo o meglio. Le neutre non contano.
              </p>
            </div>
          </div>

          <div className="sx-card">
            <div className="sx-head"><Icon7 name="spark" size={18} /><b>Da rivedere</b><span className="sx-tipo">{daRivedere.length}</span></div>
            {daRivedere.length === 0 && <div className="sx-riga sx-vuota">Nulla da rivedere: quando un progetto si chiude, una decisione è presa o una cosa è fatta, compare qui.</div>}
            {daRivedere.slice(0, 6).map(o => (
              <div className="sx-riga" key={o.tipo + o.id}>
                <div className="sx-tipo">{TIPI_OGGETTO[o.tipo]}</div>
                <b>{descriviOggetto(o.tipo, o.id).titolo}</b>
                <div className="row" style={{ gap: 8, fontSize: 12.5 }}><SensazioniInRiga tipo={o.tipo} id={o.id} /></div>
                <button type="button" className="link-btn" style={{ alignSelf: "flex-start" }} onClick={() => setDettaglio({ tipo: o.tipo, id: o.id })}>Registra com'è andata</button>
              </div>
            ))}
          </div>
        </div>
      </div>

      {dettaglio && (
        <Modal7 title={descriviOggetto(dettaglio.tipo, dettaglio.id).titolo} subtitle={TIPI_OGGETTO[dettaglio.tipo]} onClose={() => setDettaglio(null)} width={560}>
          <PannelloSensazioni tipo={dettaglio.tipo} id={dettaglio.id} titolo={descriviOggetto(dettaglio.tipo, dettaglio.id).titolo} />
        </Modal7>
      )}
      {nuova && <ScegliOggettoModal onClose={() => setNuova(false)} />}
    </div>
  );
}

// "Nuova sensazione" dalla pagina: prima si sceglie su cosa
function ScegliOggettoModal({ onClose }) {
  const D = window.AntaresData;
  const [tipo, setTipo] = useS7("progetto");
  const [id, setId] = useS7("");
  const [pronto, setPronto] = useS7(false);
  const preventivi = Object.entries(D.PREVENTIVI || {}).map(([pid, p]) => ({ id: p.preventivoId, nome: p.progetto, versione: p.versioneAttiva }));
  const opzioni = tipo === "preventivo" ? preventivi.map(p => ({ id: p.id, nome: p.nome + " · " + p.versione }))
    : tipo === "decisione" ? (D.DECISIONI || []).filter(d => d.stato === "aperta").map(d => ({ id: d.id, nome: d.titolo }))
    : tipo === "da_fare" ? (D.DA_FARE || []).filter(t => !t.fatto).map(t => ({ id: t.id, nome: t.titolo }))
    : null;
  if (pronto && id) {
    const prev = preventivi.find(p => p.id === id);
    return <SensazioneModal tipo={tipo} id={id} versione={tipo === "preventivo" && prev ? prev.versione : null}
      titolo={descriviOggetto(tipo, id).titolo} onClose={onClose} onSaved={onClose} />;
  }
  return (
    <Modal7 title="Nuova sensazione" subtitle="Su cosa?" onClose={onClose} width={520}
      footer={<>
        <button type="button" className="btn" onClick={onClose}>Annulla</button>
        <button type="button" className="btn sx-btn" disabled={!id} onClick={() => setPronto(true)}>Avanti</button>
      </>}
    >
      <div className="segmented" style={{ display: "flex", marginBottom: 12 }}>
        {Object.entries(TIPI_OGGETTO).map(([k, l]) => (
          <button key={k} type="button" style={{ flex: 1 }} className={tipo === k ? "active" : ""} onClick={() => { setTipo(k); setId(""); }}>{l}</button>
        ))}
      </div>
      <select className="select" value={id} onChange={e => setId(e.target.value)}>
        <option value="">Scegli…</option>
        {opzioni ? opzioni.map(o => <option key={o.id} value={o.id}>{o.nome}</option>) : progOpt7(D.PROGETTI || [])}
      </select>
      {opzioni && opzioni.length === 0 && <p className="help">Nessun elemento aperto di questo tipo.</p>}
    </Modal7>
  );
}

/* ============================================================
   DECISIONI
   ============================================================ */
function Decisioni() {
  const D = window.AntaresData;
  const [stato, setStato] = useS7("aperta");
  const [aperta, setAperta] = useS7(null); // null | "nuova" | decisione

  const testata = (
    <div className="page-head">
      <div className="page-title-block">
        <span className="eyebrow">Le scelte da fare, con le sensazioni di entrambi</span>
        <h1 className="h1">Decisioni</h1>
      </div>
      {D.SENS_PRONTA && <div className="page-actions"><button className="btn primary" onClick={() => setAperta("nuova")}><Icon7 name="plus" size={14} />Nuova decisione</button></div>}
    </div>
  );
  if (!D.SENS_PRONTA) return <div className="stack">{testata}<MigrazioneMancante7 titolo="La pagina Decisioni" /></div>;

  const tutte = D.DECISIONI || [];
  const lista = tutte.filter(d => d.stato === stato)
    .sort((a, b) => stato === "aperta"
      ? String(a.scadenza || "9999").localeCompare(String(b.scadenza || "9999"))
      : String(b.decisa_il || b.created_at).localeCompare(String(a.decisa_il || a.created_at)));
  const conta = (s) => tutte.filter(d => d.stato === s).length;

  return (
    <div className="stack">
      {testata}
      <div className="segmented" style={{ alignSelf: "flex-start" }}>
        {[["aperta", "Da decidere"], ["presa", "Prese"], ["scartata", "Scartate"]].map(([k, l]) => (
          <button key={k} type="button" className={stato === k ? "active" : ""} onClick={() => setStato(k)}>{l} · {conta(k)}</button>
        ))}
      </div>
      <div className="card">
        <div className="table-wrap">
          <table className="table">
            <thead><tr><th>Decisione</th><th>{stato === "aperta" ? "Entro" : "Decisa il"}</th><th>Progetto</th><th>Sensazioni</th><th>Cose da fare</th></tr></thead>
            <tbody>
              {lista.length === 0 && <tr><td colSpan={5} className="empty">{stato === "aperta" ? "Nessuna decisione in sospeso." : "Niente qui."}</td></tr>}
              {lista.map(d => {
                const todo = (D.DA_FARE || []).filter(t => t.decisione_id === d.id);
                const g = d.scadenza ? giorniDa7(d.scadenza) : null;
                return (
                  <tr key={d.id} className="pn-riga" onClick={() => setAperta(d)}>
                    <td>
                      <div className="pn-desc">{d.titolo}</div>
                      {(d.esito || d.descrizione) && <div className="pn-nota">{d.esito || d.descrizione}</div>}
                    </td>
                    <td style={{ whiteSpace: "nowrap" }}>
                      {stato === "aperta"
                        ? (d.scadenza ? <span className={g < 0 ? "neg" : g <= 7 ? "warn" : ""}>{dataIt7(d.scadenza)}</span> : <span className="muted">—</span>)
                        : dataIt7(d.decisa_il)}
                    </td>
                    <td className="muted">{d.progetto_id ? descriviOggetto("progetto", d.progetto_id).titolo : "—"}</td>
                    <td><SensazioniInRiga tipo="decisione" id={d.id} /></td>
                    <td className="muted">{todo.length ? todo.filter(t => t.fatto).length + "/" + todo.length + " fatte" : "—"}</td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>
      {aperta && <DecisioneModal decisione={aperta === "nuova" ? null : aperta} onClose={() => setAperta(null)} />}
    </div>
  );
}

function DecisioneModal({ decisione, onClose }) {
  const D = window.AntaresData;
  const [dec, setDec] = useS7(decisione);
  const [titolo, setTitolo] = useS7(decisione ? decisione.titolo : "");
  const [descrizione, setDescrizione] = useS7(decisione ? decisione.descrizione || "" : "");
  const [scadenza, setScadenza] = useS7(decisione ? decisione.scadenza || "" : "");
  const [progetto, setProgetto] = useS7(decisione ? decisione.progetto_id || "" : "");
  const [esito, setEsito] = useS7(decisione ? decisione.esito || "" : "");
  const [nuovoTodo, setNuovoTodo] = useS7("");
  const [busy, setBusy] = useS7(false);
  const [err, setErr] = useS7("");

  const salva = async (patch) => {
    setErr("");
    if (!titolo.trim()) { setErr("Scrivi la decisione da prendere"); return null; }
    setBusy(true);
    const { data, error } = await window.AntaresStore.salvaDecisione({
      id: dec && dec.id, titolo: titolo.trim(), descrizione: descrizione.trim() || null,
      scadenza: scadenza || null, progetto_id: progetto || null, esito: esito.trim() || null, ...(patch || {}),
    });
    setBusy(false);
    if (error) { setErr(error.message); return null; }
    await window.AntaresStore.refresh("sensazioni");
    setDec(data);
    return data;
  };

  const ultime = dec ? SX.perUtente(SX.suOggetto(D.SENSAZIONI, "decisione", dec.id), "ultima") : {};
  const disc = SX.discordanza(ultime);
  const decidi = async (stato) => {
    if (stato === "presa" && disc >= 2 && !confirm(`Le vostre sensazioni sono distanti di ${disc} punti. Ne avete parlato? Confermi la decisione?`)) return;
    if (stato === "presa" && !esito.trim() && !confirm("Non hai scritto cosa avete deciso. Confermi comunque?")) return;
    const d = await salva({ stato, decisa_il: oggiIso7() });
    if (d) onClose();
  };
  const riapri = async () => { const d = await salva({ stato: "aperta", decisa_il: null }); if (d) setDec(d); };
  const elimina = async () => {
    if (!confirm("Eliminare questa decisione? Le cose da fare collegate restano.")) return;
    const { error } = await window.AntaresStore.eliminaDecisione(dec.id);
    if (error) { setErr(error.message); return; }
    await window.AntaresStore.refresh("sensazioni");
    onClose();
  };
  const aggiungiTodo = async () => {
    if (!nuovoTodo.trim()) return;
    const d = dec || await salva();
    if (!d) return;
    const { error } = await window.AntaresStore.salvaDaFare({ titolo: nuovoTodo.trim(), decisione_id: d.id, progetto_id: d.progetto_id || null });
    if (error) { setErr(error.message); return; }
    setNuovoTodo("");
    await window.AntaresStore.refresh("sensazioni");
    setDec({ ...d });
  };
  const todo = dec ? (D.DA_FARE || []).filter(t => t.decisione_id === dec.id) : [];

  return (
    <Modal7 title={dec ? "Decisione" : "Nuova decisione"} onClose={onClose} width={760}
      subtitle={dec && dec.stato !== "aperta" ? (dec.stato === "presa" ? "Presa il " : "Scartata il ") + dataIt7(dec.decisa_il) : null}
      footer={<>
        {dec && <button type="button" className="btn danger modal-foot-left" onClick={elimina} disabled={busy}>Elimina</button>}
        {dec && dec.stato !== "aperta" && <button type="button" className="btn" onClick={riapri} disabled={busy}>Riapri</button>}
        {(!dec || dec.stato === "aperta") && <>
          <button type="button" className="btn" onClick={async () => { if (await salva()) onClose(); }} disabled={busy}>Salva</button>
          {dec && <button type="button" className="btn" onClick={() => decidi("scartata")} disabled={busy}>Scarta</button>}
          {dec && <button type="button" className="btn primary" onClick={() => decidi("presa")} disabled={busy}>Decisa</button>}
        </>}
        {dec && dec.stato !== "aperta" && <button type="button" className="btn primary" onClick={async () => { if (await salva()) onClose(); }} disabled={busy}>Salva</button>}
      </>}
    >
      {err && <div className="login-error" style={{ marginBottom: 10 }}>{err}</div>}
      <div className="sx-dec">
        <div className="form-grid" style={{ alignContent: "start" }}>
          <div className="field span-2">
            <label className="label">Cosa decidere</label>
            <input className="input" value={titolo} onChange={e => setTitolo(e.target.value)} placeholder="es. Comprare una seconda regia mobile" />
          </div>
          <div className="field span-2">
            <label className="label">Il contesto</label>
            <textarea className="textarea" rows={3} value={descrizione} onChange={e => setDescrizione(e.target.value)} placeholder="Pro, contro, numeri, chi è coinvolto…" />
          </div>
          <div className="field">
            <label className="label">Entro il</label>
            <input className="input" type="date" value={scadenza} onChange={e => setScadenza(e.target.value)} />
          </div>
          <div className="field">
            <label className="label">Progetto</label>
            <select className="select" value={progetto} onChange={e => setProgetto(e.target.value)}>
              <option value="">— nessuno —</option>
              {progOpt7(D.PROGETTI || [])}
            </select>
          </div>
          <div className="field span-2">
            <label className="label">Cosa si è deciso</label>
            <textarea className="textarea" rows={2} value={esito} onChange={e => setEsito(e.target.value)} placeholder="Si scrive quando si decide" />
          </div>
          <div className="field span-2">
            <label className="label">Cose da fare che ne seguono</label>
            {todo.map(t => (
              <label key={t.id} className="pn-check" style={{ marginTop: 2 }}>
                <input type="checkbox" checked={t.fatto} onChange={async e => {
                  await window.AntaresStore.salvaDaFare({ id: t.id, fatto: e.target.checked });
                  await window.AntaresStore.refresh("sensazioni"); setDec({ ...dec });
                }} />
                <span style={{ textDecoration: t.fatto ? "line-through" : "none" }}>{t.titolo}</span>
              </label>
            ))}
            <div className="row" style={{ gap: 6, flexWrap: "nowrap", marginTop: 4 }}>
              <input className="input" value={nuovoTodo} onChange={e => setNuovoTodo(e.target.value)} placeholder="Aggiungi una cosa da fare"
                onKeyDown={e => { if (e.key === "Enter") { e.preventDefault(); aggiungiTodo(); } }} />
              <button type="button" className="btn" onClick={aggiungiTodo}><Icon7 name="plus" size={13} /></button>
            </div>
          </div>
        </div>
        <div>
          {dec ? <PannelloSensazioni tipo="decisione" id={dec.id} titolo={titolo} />
            : <div className="sx-card"><div className="sx-riga sx-vuota">Salva la decisione per registrare le sensazioni.</div></div>}
        </div>
      </div>
    </Modal7>
  );
}

/* ============================================================
   DA FARE
   ============================================================ */
function DaFare() {
  const D = window.AntaresData;
  const [chi, setChi] = useS7("tutti");
  const [mostraFatte, setMostraFatte] = useS7(false);
  const [aperta, setAperta] = useS7(null);
  const [qa, setQa] = useS7({ titolo: "", scadenza: "", assegnato_a: "", progetto_id: "" });
  const [busy, setBusy] = useS7(false);

  const testata = (
    <div className="page-head">
      <div className="page-title-block">
        <span className="eyebrow">Le cose da fare, di tutti e due</span>
        <h1 className="h1">Da fare</h1>
      </div>
    </div>
  );
  if (!D.SENS_PRONTA) return <div className="stack">{testata}<MigrazioneMancante7 titolo="La pagina Da fare" /></div>;

  const tutte = (D.DA_FARE || []).filter(t => chi === "tutti" || (chi === "io" ? t.assegnato_a === D.IO : !t.assegnato_a));
  const aperte = tutte.filter(t => !t.fatto);
  const gruppi = [
    { nome: "In ritardo", lista: aperte.filter(t => t.scadenza && giorniDa7(t.scadenza) < 0), classe: "neg" },
    { nome: "Oggi e questa settimana", lista: aperte.filter(t => t.scadenza && giorniDa7(t.scadenza) >= 0 && giorniDa7(t.scadenza) <= 7) },
    { nome: "Più avanti", lista: aperte.filter(t => t.scadenza && giorniDa7(t.scadenza) > 7) },
    { nome: "Senza data", lista: aperte.filter(t => !t.scadenza) },
  ];
  const fatte = tutte.filter(t => t.fatto).sort((a, b) => String(b.fatto_il).localeCompare(String(a.fatto_il)));

  const aggiungi = async (e) => {
    e.preventDefault();
    if (!qa.titolo.trim()) return;
    setBusy(true);
    const { error } = await window.AntaresStore.salvaDaFare({ ...qa, titolo: qa.titolo.trim() });
    setBusy(false);
    if (error) { alert("Errore: " + error.message); return; }
    setQa({ ...qa, titolo: "" });
    await window.AntaresStore.refresh("sensazioni");
  };
  const spunta = async (t, v) => {
    await window.AntaresStore.salvaDaFare({ id: t.id, fatto: v });
    await window.AntaresStore.refresh("sensazioni");
  };

  const riga = (t) => {
    const g = t.scadenza ? giorniDa7(t.scadenza) : null;
    return (
      <tr key={t.id} className="pn-riga">
        <td style={{ width: 36 }} onClick={e => e.stopPropagation()}>
          <input type="checkbox" checked={t.fatto} onChange={e => spunta(t, e.target.checked)} aria-label="Fatto" />
        </td>
        <td onClick={() => setAperta(t)}>
          <div className="pn-desc" style={{ textDecoration: t.fatto ? "line-through" : "none" }}>{t.titolo}</div>
          {t.nota && <div className="pn-nota">{t.nota}</div>}
          {t.decisione_id && <div className="pn-nota">dalla decisione: {descriviOggetto("decisione", t.decisione_id).titolo}</div>}
        </td>
        <td onClick={() => setAperta(t)} style={{ whiteSpace: "nowrap" }} className={g != null && g < 0 && !t.fatto ? "neg" : ""}>
          {t.fatto ? "fatta il " + dataIt7(t.fatto_il) : (t.scadenza ? (g === 0 ? "oggi" : g === 1 ? "domani" : dataIt7(t.scadenza)) : "—")}
        </td>
        <td onClick={() => setAperta(t)} className="muted">{t.assegnato_a ? nomeUtente7(t.assegnato_a) : "Chiunque"}</td>
        <td onClick={() => setAperta(t)} className="muted">{t.progetto_id ? descriviOggetto("progetto", t.progetto_id).titolo : "—"}</td>
        <td onClick={() => setAperta(t)}><SensazioniInRiga tipo="da_fare" id={t.id} /></td>
      </tr>
    );
  };

  return (
    <div className="stack">
      {testata}
      <div className="row" style={{ justifyContent: "space-between" }}>
        <div className="segmented">
          {[["tutti", "Tutte"], ["io", "Le mie"], ["nessuno", "Di chiunque"]].map(([k, l]) => (
            <button key={k} type="button" className={chi === k ? "active" : ""} onClick={() => setChi(k)}>{l}</button>
          ))}
        </div>
        <label className="pn-check" style={{ marginTop: 0 }}>
          <input type="checkbox" checked={mostraFatte} onChange={e => setMostraFatte(e.target.checked)} /> Mostra le fatte ({fatte.length})
        </label>
      </div>
      <div className="card">
        <form className="pn-rapido df-rapido" onSubmit={aggiungi} style={{ borderTop: 0 }}>
          <input className="input" placeholder="Cosa c'è da fare…" value={qa.titolo} onChange={e => setQa({ ...qa, titolo: e.target.value })} />
          <input className="input" type="date" value={qa.scadenza} onChange={e => setQa({ ...qa, scadenza: e.target.value })} aria-label="Entro il" />
          <select className="select" value={qa.assegnato_a} onChange={e => setQa({ ...qa, assegnato_a: e.target.value })} aria-label="Chi">
            <option value="">Chiunque</option>
            {(D.UTENTI || []).map(u => <option key={u.id} value={u.id}>{u.nome || u.email.split("@")[0]}</option>)}
          </select>
          <select className="select" value={qa.progetto_id} onChange={e => setQa({ ...qa, progetto_id: e.target.value })} aria-label="Progetto">
            <option value="">Nessun progetto</option>
            {progOpt7(D.PROGETTI || [])}
          </select>
          <button type="submit" className="btn primary" disabled={busy}><Icon7 name="plus" size={14} />Aggiungi</button>
        </form>
        <div className="table-wrap">
          <table className="table pn-tabella">
            <thead><tr><th></th><th>Cosa</th><th>Entro</th><th>Chi</th><th>Progetto</th><th>Sensazioni</th></tr></thead>
            <tbody>
              {aperte.length === 0 && !mostraFatte && <tr><td colSpan={6} className="empty">Niente da fare. Aggiungi una cosa qui sopra.</td></tr>}
              {gruppi.filter(g => g.lista.length).map(g => (
                <React.Fragment key={g.nome}>
                  <tr className="pn-giorno"><td colSpan={6} className={g.classe || ""}>{g.nome} · {g.lista.length}</td></tr>
                  {g.lista.sort((a, b) => String(a.scadenza || "").localeCompare(String(b.scadenza || ""))).map(riga)}
                </React.Fragment>
              ))}
              {mostraFatte && fatte.length > 0 && (
                <>
                  <tr className="pn-giorno"><td colSpan={6}>Fatte · {fatte.length}</td></tr>
                  {fatte.map(riga)}
                </>
              )}
            </tbody>
          </table>
        </div>
      </div>
      {aperta && <DaFareModal cosa={aperta} onClose={() => setAperta(null)} />}
    </div>
  );
}

function DaFareModal({ cosa, onClose }) {
  const D = window.AntaresData;
  const [f, setF] = useS7({ ...cosa, nota: cosa.nota || "", scadenza: cosa.scadenza || "", assegnato_a: cosa.assegnato_a || "", progetto_id: cosa.progetto_id || "" });
  const [err, setErr] = useS7("");
  const salva = async () => {
    if (!f.titolo.trim()) { setErr("Scrivi cosa c'è da fare"); return; }
    const { error } = await window.AntaresStore.salvaDaFare({ ...f, titolo: f.titolo.trim(), nota: f.nota.trim() || null });
    if (error) { setErr(error.message); return; }
    await window.AntaresStore.refresh("sensazioni");
    onClose();
  };
  const elimina = async () => {
    if (!confirm("Eliminare questa cosa da fare?")) return;
    const { error } = await window.AntaresStore.eliminaDaFare(cosa.id);
    if (error) { setErr(error.message); return; }
    await window.AntaresStore.refresh("sensazioni");
    onClose();
  };
  return (
    <Modal7 title="Cosa da fare" onClose={onClose} width={720}
      footer={<>
        <button type="button" className="btn danger modal-foot-left" onClick={elimina}>Elimina</button>
        <button type="button" className="btn" onClick={onClose}>Annulla</button>
        <button type="button" className="btn primary" onClick={salva}>Salva</button>
      </>}
    >
      {err && <div className="login-error" style={{ marginBottom: 10 }}>{err}</div>}
      <div className="sx-dec">
        <div className="form-grid" style={{ alignContent: "start" }}>
          <div className="field span-2"><label className="label">Cosa</label>
            <input className="input" value={f.titolo} onChange={e => setF({ ...f, titolo: e.target.value })} /></div>
          <div className="field span-2"><label className="label">Nota</label>
            <textarea className="textarea" rows={2} value={f.nota} onChange={e => setF({ ...f, nota: e.target.value })} /></div>
          <div className="field"><label className="label">Entro il</label>
            <input className="input" type="date" value={f.scadenza} onChange={e => setF({ ...f, scadenza: e.target.value })} /></div>
          <div className="field"><label className="label">Chi</label>
            <select className="select" value={f.assegnato_a} onChange={e => setF({ ...f, assegnato_a: e.target.value })}>
              <option value="">Chiunque</option>
              {(D.UTENTI || []).map(u => <option key={u.id} value={u.id}>{u.nome || u.email.split("@")[0]}</option>)}
            </select></div>
          <div className="field span-2"><label className="label">Progetto</label>
            <select className="select" value={f.progetto_id} onChange={e => setF({ ...f, progetto_id: e.target.value })}>
              <option value="">— nessuno —</option>
              {progOpt7(D.PROGETTI || [])}
            </select></div>
          <label className="pn-check span-2" style={{ gridColumn: "1 / -1" }}>
            <input type="checkbox" checked={f.fatto} onChange={e => setF({ ...f, fatto: e.target.checked })} /> Fatto
          </label>
        </div>
        <PannelloSensazioni tipo="da_fare" id={cosa.id} titolo={cosa.titolo} />
      </div>
    </Modal7>
  );
}

// numeri per i pallini del menu
function contaDaFareUrgenti() {
  return (window.AntaresData.DA_FARE || []).filter(t => !t.fatto && t.scadenza && giorniDa7(t.scadenza) <= 0).length;
}
function contaSensazioniDaRivedere() {
  const D = window.AntaresData;
  if (!D.SENS_PRONTA) return 0;
  return SX.oggetti(D.SENSAZIONI, D.SENS_ESITI).filter(o => !o.esito && oggettoChiuso(o.tipo, o.id)).length;
}

window.AntaresScreens7 = { Sensazioni, Decisioni, DaFare, PannelloSensazioni, contaDaFareUrgenti, contaSensazioniDaRivedere };
