/* MENOUNO — Gestione Recensioni
   Fetches from FastAPI backend at /api/ */

const API = "";  // same origin

const RISULTATO_OPTIONS = [
  { value: "",          label: "— nessuno" },
  { value: "in-attesa", label: "In attesa" },
  { value: "lasciata",  label: "Recensione lasciata" },
  { value: "nessuna",   label: "Nessuna risposta" },
  { value: "rifiutata", label: "Rifiutata" },
];

// ── Status computation (mirrors backend logic) ────────────────────────────────
function computeStatus(richiesta, risultato) {
  const r   = (risultato  || "").toLowerCase();
  const req = (richiesta  || "").toLowerCase();
  if (r.includes("lasciata"))  return "lasciata";
  if (r.includes("nessuna"))   return "nessuna";
  if (r.includes("rifiutata")) return "rifiutata";
  if (req === "richiesta inviata") return "in-attesa";
  if (req.startsWith("non richiesta")) return "non-richiesta";
  return "da-inviare";
}

// ── Single table row ──────────────────────────────────────────────────────────
function ClientRow({ client: c, onPatch, onSend }) {
  return (
    <div className="v1-row">

      {/* Cliente */}
      <div className="v1-col cliente">
        <span className="v1-name-stack">
          <span className="v1-name">{fullName(c)}</span>
          <span className="v1-sub-line">{c.method === "mail" ? c.email : c.phone}</span>
        </span>
      </div>

      {/* Contatto */}
      <div className="v1-col contatto">
        <span className={"method " + c.method}>
          <span className="ic"><MethodIcon method={c.method}/></span>
          {methodLabel(c.method)}
        </span>
      </div>

      {/* Tatuatore */}
      <div className="v1-col tattoo">
        <span style={{ fontSize: 12.5, fontWeight: 500 }}>{c.artist || "—"}</span>
      </div>

      {/* Soddisfazione */}
      <div className="v1-col satis">
        <SatisfactionSelect
          value={c.satisfaction}
          onChange={v => onPatch({ satisfaction: v })}
          compact
        />
      </div>

      {/* Richiesta */}
      <div className="v1-col richiesta">
        <StatusPill status={c.status}/>
        {c.status === "non-richiesta" && c.richiesta_recensione && (
          <span className="v1-mini" title={c.richiesta_recensione}>
            {c.richiesta_recensione}
          </span>
        )}
      </div>

      {/* Modalità */}
      <div className="v1-col modalita">
        <ModalityTag value={c.modality}/>
      </div>

      {/* Risultato */}
      <div className="v1-col risultato">
        <select
          className="risultato-select"
          value={c.risultato || ""}
          onChange={e => onPatch({ risultato: e.target.value || null })}
        >
          {RISULTATO_OPTIONS.map(o => (
            <option key={o.value} value={o.value}>{o.label}</option>
          ))}
        </select>
      </div>

      {/* Stelle */}
      <div className="v1-col stelle">
        <StarInput value={c.stars} onChange={v => onPatch({ stars: v })}/>
      </div>

      {/* Foto */}
      <div className="v1-col foto">
        <PhotoTag has={c.hasPhoto}/>
      </div>

      {/* Azione */}
      <div className="v1-col azione">
        <button
          className={"v1-send " + c.method + (c.status === "lasciata" ? " soft" : "")}
          onClick={onSend}
          title={"Invia via " + methodLabel(c.method)}
        >
          <MethodIcon method={c.method} size={13}/>
          {c.status === "da-inviare" ? "Invia"
            : c.status === "in-attesa" ? "Risollecita"
            : c.status === "lasciata" ? "Contatta"
            : "Reinvia"}
        </button>
      </div>
    </div>
  );
}

// ── Main App ──────────────────────────────────────────────────────────────────
function App() {
  const [clients,     setClients]     = React.useState([]);
  const [messages,    setMessages]    = React.useState([]);
  const [loading,     setLoading]     = React.useState(true);
  const [error,       setError]       = React.useState(null);
  const [selectedMsg, setSelectedMsg] = React.useState(null);
  const [filter,      setFilter]      = React.useState("tutti");
  const [query,       setQuery]       = React.useState("");
  const [sideOpen,    setSideOpen]    = React.useState(true);
  const [editing,     setEditing]     = React.useState(null);
  const [refreshing,  setRefreshing]  = React.useState(false);
  const [toast, showToast] = useToast();

  // ── Fetch ─────────────────────────────────────────────────────────────────

  // Messages: local JSON, fast — runs independently, never blocks the table skeleton
  const fetchMessages = React.useCallback(async () => {
    try {
      const msgs = await fetch(API + "/api/messages").then(r => r.json());
      setMessages(msgs);
      setSelectedMsg(sel => {
        const ids = msgs.map(m => m.id);
        return ids.includes(sel) ? sel : (msgs[0]?.id || null);
      });
    } catch {}
  }, []);

  // Clients: Google Sheets — controls table loading/error state
  const fetchClients = React.useCallback(async (showSpinner = true) => {
    if (showSpinner) setRefreshing(true);
    try {
      const cls = await fetch(API + "/api/clients").then(r => {
        if (!r.ok) throw new Error("Errore caricamento clienti");
        return r.json();
      });
      setClients(cls);
      setError(null);
    } catch (e) {
      setError(e.message);
    } finally {
      setLoading(false);
      setRefreshing(false);
    }
  }, []);

  React.useEffect(() => {
    fetchMessages();   // fast, non-blocking
    fetchClients(false); // controls table skeleton
  }, []);

  // ── Client mutations ───────────────────────────────────────────────────────

  const patchClient = React.useCallback(async (id, updates) => {
    // Optimistic UI update
    setClients(cs => cs.map(c => {
      if (c.id !== id) return c;
      const next = { ...c, ...updates };
      next.status = computeStatus(
        updates.richiesta_recensione ?? c.richiesta_recensione,
        updates.risultato             ?? c.risultato
      );
      return next;
    }));
    try {
      const res = await fetch(API + "/api/clients/" + id, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(updates),
      });
      if (!res.ok) throw new Error(await res.text());
    } catch (e) {
      showToast("⚠️ Errore salvataggio: " + e.message);
      fetchClients(false);  // roll back optimistic update
    }
  }, [fetchClients, showToast]);

  const handleSend = React.useCallback((client) => {
    const msg = messages.find(m => m.id === selectedMsg);
    const url = buildContactURL(client, msg);
    try {
      if (client.method === "call") { window.location.href = url; }
      else { window.open(url, "_blank", "noopener"); }
    } catch {}
    showToast("Aperto contatto con " + client.first + " via " + methodLabel(client.method));
  }, [messages, selectedMsg, showToast]);

  // ── Counts & filter ────────────────────────────────────────────────────────

  const counts = React.useMemo(() => {
    const c = { tutti: clients.length, "da-inviare": 0, "in-attesa": 0, "lasciata": 0, "altro": 0, "non-richiesta": 0 };
    clients.forEach(cl => {
      if (cl.status === "da-inviare")    c["da-inviare"]++;
      else if (cl.status === "in-attesa") c["in-attesa"]++;
      else if (cl.status === "lasciata")  c["lasciata"]++;
      else if (cl.status === "non-richiesta") c["non-richiesta"]++;
      else c["altro"]++;
    });
    return c;
  }, [clients]);

  const filtered = React.useMemo(() => {
    return clients.filter(c => {
      if (filter === "da-inviare"   && c.status !== "da-inviare")   return false;
      if (filter === "in-attesa"    && c.status !== "in-attesa")    return false;
      if (filter === "lasciata"     && c.status !== "lasciata")     return false;
      if (filter === "non-richiesta"&& c.status !== "non-richiesta")return false;
      if (filter === "altro" && !["nessuna","rifiutata"].includes(c.status)) return false;
      if (query) {
        const q = query.toLowerCase();
        return (
          (c.first + " " + c.last).toLowerCase().includes(q) ||
          c.email.toLowerCase().includes(q) ||
          c.phone.includes(q)
        );
      }
      return true;
    });
  }, [clients, filter, query]);

  const message = messages.find(m => m.id === selectedMsg);

  // ── Message CRUD ───────────────────────────────────────────────────────────

  const saveMessage = async m => {
    try {
      if (m.id) {
        const res = await fetch(API + "/api/messages/" + m.id, {
          method: "PUT",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ title: m.title, body: m.body }),
        });
        const updated = await res.json();
        setMessages(ms => ms.map(x => x.id === m.id ? updated : x));
      } else {
        const res = await fetch(API + "/api/messages", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ title: m.title, body: m.body }),
        });
        const created = await res.json();
        setMessages(ms => [...ms, created]);
        setSelectedMsg(created.id);
      }
      setEditing(null);
      showToast("Messaggio salvato");
    } catch (e) {
      showToast("⚠️ Errore: " + e.message);
    }
  };

  const deleteMessage = async id => {
    await fetch(API + "/api/messages/" + id, { method: "DELETE" });
    setMessages(ms => ms.filter(x => x.id !== id));
    if (selectedMsg === id) {
      const rem = messages.filter(x => x.id !== id);
      setSelectedMsg(rem[0]?.id || null);
    }
    showToast("Messaggio eliminato");
  };

  // ── Render ─────────────────────────────────────────────────────────────────

  return (
    <div className={"v1-root " + (sideOpen ? "" : "side-collapsed")}>

      {/* ── Top bar ──────────────────────────────────────────────────────── */}
      <header className="v1-top">
        <div className="v1-brand">
          <span className="v1-dot"></span>
          <span className="brand-wordmark">MENOUNO</span>
          <span className="v1-sub">/ FRONT OFFICE — RECENSIONI</span>
        </div>
        <div className="v1-search">
          <Icon name="search" size={14}/>
          <input
            className="v1-search-input"
            placeholder="Cerca per nome, email o telefono…"
            value={query}
            onChange={e => setQuery(e.target.value)}
          />
          {query && (
            <button className="v1-clear" onClick={() => setQuery("")} aria-label="Pulisci">
              <Icon name="close" size={12}/>
            </button>
          )}
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <button
            className={"btn icon ghost" + (refreshing ? " disabled" : "")}
            onClick={() => fetchClients()}
            title="Aggiorna dati"
            disabled={refreshing}
            style={{ opacity: refreshing ? 0.5 : 1 }}
          >
            <Icon name="refresh" size={15}/>
          </button>
        </div>
      </header>

      {/* ── Chips ────────────────────────────────────────────────────────── */}
      <nav className="v1-chips">
        {[
          ["tutti",         "Tutti",                 counts.tutti],
          ["da-inviare",    "Da inviare",             counts["da-inviare"]],
          ["in-attesa",     "In attesa",              counts["in-attesa"]],
          ["lasciata",      "Lasciata",               counts["lasciata"]],
          ["altro",         "Nessuna risp./Rifiutate",counts["altro"]],
          ["non-richiesta", "Non richiesta",          counts["non-richiesta"]],
        ].map(([k, label, count]) => (
          <button key={k} className={"chip " + (filter === k ? "active" : "")} onClick={() => setFilter(k)}>
            {label} <span className="count">{count}</span>
          </button>
        ))}

        <span className="v1-using">
          <span className="eyebrow">Messaggio attivo</span>
          <span className="v1-using-name">{message ? message.title : "—"}</span>
        </span>

        {!sideOpen && (
          <button className="v1-side-reopen" onClick={() => setSideOpen(true)}>
            <Icon name="edit" size={13}/>
            <span>Messaggi</span>
            <span className="v1-side-reopen-n">{messages.length}</span>
          </button>
        )}
      </nav>

      {/* ── Body ─────────────────────────────────────────────────────────── */}
      <div className="v1-body">

        {/* TABLE */}
        <main className="v1-table-pane">
          <div className="v1-thead">
            <div className="v1-col cliente">Cliente</div>
            <div className="v1-col contatto">Contatto pref.</div>
            <div className="v1-col tattoo">Tatuatore</div>
            <div className="v1-col satis">Soddisfaz.</div>
            <div className="v1-col richiesta">Richiesta</div>
            <div className="v1-col modalita">Modalità</div>
            <div className="v1-col risultato">Risultato</div>
            <div className="v1-col stelle">Stelle</div>
            <div className="v1-col foto">Foto</div>
            <div className="v1-col azione">Azione</div>
          </div>
          <div className="v1-tbody scroll">
            {loading ? (
              Array.from({ length: 6 }).map((_, i) => (
                <div key={i} className="v1-row skeleton-row">
                  <div className="v1-col cliente"><div className="sk-stack"><div className="sk sk-name"/><div className="sk sk-sub"/></div></div>
                  <div className="v1-col contatto"><div className="sk sk-med"/></div>
                  <div className="v1-col tattoo"><div className="sk sk-sm"/></div>
                  <div className="v1-col satis"><div className="sk sk-med"/></div>
                  <div className="v1-col richiesta"><div className="sk sk-med"/></div>
                  <div className="v1-col modalita"><div className="sk sk-sm"/></div>
                  <div className="v1-col risultato"><div className="sk sk-lg"/></div>
                  <div className="v1-col stelle"><div className="sk sk-sm"/></div>
                  <div className="v1-col foto"><div className="sk sk-xs"/></div>
                  <div className="v1-col azione"><div className="sk sk-btn"/></div>
                </div>
              ))
            ) : error ? (
              <div className="v1-empty" style={{ color: "var(--bad)" }}>
                ⚠️ {error}
                <br/>
                <button className="btn sm ghost" style={{ marginTop: 12 }}
                  onClick={() => { setLoading(true); fetchClients(false); }}>
                  Riprova
                </button>
              </div>
            ) : (
              <>
                {filtered.map(c => (
                  <ClientRow
                    key={c.id}
                    client={c}
                    onPatch={updates => patchClient(c.id, updates)}
                    onSend={() => handleSend(c)}
                  />
                ))}
                {filtered.length === 0 && (
                  <div className="v1-empty">Nessun cliente trovato.</div>
                )}
              </>
            )}
          </div>
          <footer className="v1-footer">
            <span>{filtered.length} di {clients.length} clienti</span>
            <span className="v1-tip">
              Seleziona un messaggio → clicca Invia → si apre WhatsApp/Email/Telefono già compilato
            </span>
          </footer>
        </main>

        {/* SIDEBAR */}
        {sideOpen && (
          <aside className="v1-side">
            <div className="v1-side-head">
              <div>
                <div className="eyebrow">Libreria</div>
                <div className="v1-side-title">Messaggi prefatti</div>
              </div>
              <div style={{ display: "flex", gap: 6, alignItems: "center" }}>
                <button className="btn sm primary" onClick={() => setEditing({ title: "", body: "" })}>
                  <Icon name="plus" size={13}/> Nuovo
                </button>
                <button className="btn icon ghost" onClick={() => setSideOpen(false)} title="Chiudi" aria-label="Chiudi">
                  <Icon name="close" size={14}/>
                </button>
              </div>
            </div>

            <div className="v1-msglist scroll">
              {messages.map(m => {
                const active = m.id === selectedMsg;
                return (
                  <div key={m.id} className={"v1-msg " + (active ? "active" : "")} onClick={() => setSelectedMsg(m.id)}>
                    <div className="v1-msg-head">
                      <div className="v1-msg-title">{m.title}</div>
                      <div className="v1-msg-actions">
                        <button className="btn xs ghost"
                          onClick={e => {
                            e.stopPropagation();
                            copyToClipboard(applyVars(m.body, null));
                            showToast("Testo copiato negli appunti");
                          }}
                          title="Copia testo">
                          <Icon name="copy" size={12}/>
                        </button>
                        <button className="btn xs ghost"
                          onClick={e => { e.stopPropagation(); setEditing({ ...m }); }}
                          title="Modifica">
                          <Icon name="edit" size={12}/>
                        </button>
                        <button className="btn xs danger"
                          onClick={e => { e.stopPropagation(); deleteMessage(m.id); }}
                          title="Elimina">
                          <Icon name="trash" size={12}/>
                        </button>
                      </div>
                    </div>
                    <div className="v1-msg-preview">{applyVars(m.body, null)}</div>
                    {active && <span className="v1-msg-active-mark">In uso</span>}
                  </div>
                );
              })}
            </div>

            {editing && (
              <div className="v1-editor">
                <div className="v1-editor-head">
                  <span>{editing.id ? "Modifica messaggio" : "Nuovo messaggio"}</span>
                  <button className="btn xs ghost" onClick={() => setEditing(null)}>
                    <Icon name="close" size={12}/>
                  </button>
                </div>
                <input
                  className="input"
                  placeholder="Titolo (es. Sollecito gentile)"
                  value={editing.title}
                  onChange={e => setEditing({ ...editing, title: e.target.value })}
                />
                <textarea
                  className="textarea"
                  placeholder="Usa {{nome}}, {{tatuatore}}, {{stile}} per personalizzare…"
                  value={editing.body}
                  onChange={e => setEditing({ ...editing, body: e.target.value })}
                  rows={14}
                />
                <div className="v1-editor-foot">
                  <button className="btn sm ghost" onClick={() => setEditing(null)}>Annulla</button>
                  <button
                    className="btn sm primary"
                    onClick={() => saveMessage(editing)}
                    disabled={!editing.title.trim() || !editing.body.trim()}
                  >
                    Salva
                  </button>
                </div>
              </div>
            )}
          </aside>
        )}
      </div>

      {toast}
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App/>);
