// --- Progetti — CRUD lista + form ---------------------------------------

async function apiPr(url, opts = {}) {
  const r = await fetch(url, {
    credentials: 'include',
    headers: { 'Content-Type': 'application/json', ...(opts.headers || {}) },
    ...opts,
    body: opts.body && typeof opts.body !== 'string' ? JSON.stringify(opts.body) : opts.body,
  });
  const ct = r.headers.get('content-type') || '';
  const data = ct.includes('json') ? await r.json().catch(() => null) : null;
  if (!r.ok) throw new Error((data && data.error) || `HTTP ${r.status}`);
  return data;
}

const PALETTE = ['#4f46e5', '#1f7a4d', '#b3261e', '#a4620a', '#1e5a9e', '#6366f1', '#0ea5e9', '#8b5cf6', '#ec4899', '#f59e0b', '#10b981', '#ef4444'];

function ProgettiScreen({ param, onNav }) {
  // Wrapper: mounta dettaglio o lista in base al param (no hooks qui per evitare hook-order issues)
  if (param && /^\d+$/.test(param)) {
    return <ProgettoDettaglio key={'p-' + param} id={Number(param)} onBack={() => onNav('projects')} onNav={onNav} />;
  }
  return <ProgettiList onNav={onNav} />;
}

function ProgettiList({ onNav }) {
  const [projects, setProjects] = useState([]);
  const [tasks, setTasks] = useState([]);
  const [clients, setClients] = useState([]);
  const [loading, setLoading] = useState(true);
  const [editing, setEditing] = useState(null);
  const [showForm, setShowForm] = useState(false);
  const [q, setQ] = useState('');

  const load = () => {
    setLoading(true);
    Promise.all([
      apiPr('/api/projects'),
      apiPr('/api/tasks').catch(() => []),
      window.LibroAPI.clients().catch(() => []),
    ]).then(([ps, ts, cs]) => {
      setProjects(ps || []);
      setTasks(Array.isArray(ts) ? ts : []);
      setClients(cs || []);
      setLoading(false);
    }).catch(() => setLoading(false));
  };
  useEffect(load, []);

  const clientById = useMemo(() => Object.fromEntries(clients.map((c) => [c.id, c])), [clients]);
  const tasksByProj = useMemo(() => {
    const map = {};
    for (const t of tasks) {
      if (!t.project_id) continue;
      const arr = map[t.project_id] || (map[t.project_id] = { total: 0, active: 0 });
      arr.total++;
      if (t.status !== 'completata' && t.status !== 'archiviata') arr.active++;
    }
    return map;
  }, [tasks]);

  const filtered = useMemo(() => {
    if (!q) return projects;
    const ql = q.toLowerCase();
    return projects.filter((p) => (p.name || '').toLowerCase().includes(ql) || (clientById[p.client_id]?.name || '').toLowerCase().includes(ql));
  }, [projects, q, clientById]);

  const removeProject = async (id) => {
    const p = projects.find((x) => x.id === id);
    const stats = tasksByProj[id];
    let msg = `Eliminare il progetto "${p?.name}"?`;
    if (stats?.total) msg += `\n\n${stats.total} task associate (saranno scollegate, non eliminate).`;
    if (!confirm(msg)) return;
    try { await apiPr('/api/projects/' + id, { method: 'DELETE' }); load(); }
    catch (e) { alert(e.message); }
  };

  return (
    <>
      <Topbar crumbs={['Gestionale', 'Produttività', 'Progetti']} />
      <div className="content">
        <div className="page-head">
          <div>
            <h1 className="page-title">Progetti <em>{projects.length}</em></h1>
            <div className="page-sub">Categorizza le task · tariffa oraria · cliente · budget</div>
          </div>
          <div style={{ display: 'flex', gap: 8 }}>
            <button className="btn btn-accent btn-lg" onClick={() => { setEditing(null); setShowForm(true); }}>
              <Icon name="plus" size={15} /> Nuovo progetto
            </button>
          </div>
        </div>

        <div className="filter-row">
          <div className="search-wrap">
            <Icon name="search" size={14} />
            <input className="input" placeholder="Cerca progetto o cliente…" value={q} onChange={(e) => setQ(e.target.value)} />
          </div>
        </div>

        <div className="table-wrap">
          <table className="invoices">
            <thead>
              <tr>
                <th>Progetto</th>
                <th>Cliente</th>
                <th style={{ width: 90, textAlign: 'right' }}>Tariffa</th>
                <th style={{ width: 110, textAlign: 'right' }}>Budget</th>
                <th style={{ width: 110, textAlign: 'right' }}>Task</th>
                <th style={{ width: 70 }}></th>
              </tr>
            </thead>
            <tbody>
              {loading && <tr><td colSpan={6} style={{ textAlign: 'center', padding: 40, color: 'var(--ink-3)' }}>Caricamento…</td></tr>}
              {!loading && filtered.length === 0 && (
                <tr><td colSpan={6} style={{ textAlign: 'center', padding: 40, color: 'var(--ink-3)' }}>
                  <Icon name="folder-open" size={20} style={{ margin: '0 auto 8px' }} />
                  <div>Nessun progetto</div>
                  <div style={{ marginTop: 10 }}>
                    <button className="btn btn-accent" onClick={() => { setEditing(null); setShowForm(true); }}><Icon name="plus" size={13} /> Crea il primo</button>
                  </div>
                </td></tr>
              )}
              {!loading && filtered.map((p) => {
                const c = clientById[p.client_id];
                const stats = tasksByProj[p.id] || { total: 0, active: 0 };
                return (
                  <tr key={p.id} className="row-with-top-actions" onClick={() => onNav('projects/' + p.id)} style={{ cursor: 'pointer' }}>
                    <td className="proj-name-cell">
                      <div style={{ display: 'flex', alignItems: 'center', gap: 10, fontWeight: 500 }}>
                        <span style={{ width: 14, height: 14, borderRadius: 4, background: p.color || '#6366f1', display: 'inline-block', flexShrink: 0 }} />
                        <span style={{ overflow: 'hidden', textOverflow: 'ellipsis' }}>{p.name}</span>
                      </div>
                    </td>
                    <td data-label="Cliente" className={c ? '' : 'cell-empty'}>{c ? <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}><span className="client-mark" style={{ width: 22, height: 22, fontSize: 10 }}>{c.short}</span>{c.name}</span> : <span style={{ color: 'var(--ink-3)' }}>—</span>}</td>
                    <td data-label="Tariffa" className={'amount mono ' + (p.hourly_rate ? '' : 'cell-empty')}>{p.hourly_rate ? `€${p.hourly_rate}/h` : <span style={{ color: 'var(--ink-3)' }}>—</span>}</td>
                    <td data-label="Budget" className={'amount mono ' + (p.budget_euros != null ? '' : 'cell-empty')}>{p.budget_euros != null ? `€${new Intl.NumberFormat('it-IT', { minimumFractionDigits: 0 }).format(p.budget_euros)}` : <span style={{ color: 'var(--ink-3)' }}>—</span>}</td>
                    <td data-label="Task" className="amount mono">{stats.active}<span style={{ color: 'var(--ink-3)' }}> / {stats.total}</span></td>
                    <td onClick={(e) => e.stopPropagation()}>
                      <div style={{ display: 'flex', gap: 4, justifyContent: 'flex-end' }}>
                        <button className="ia" title="Modifica" onClick={() => { setEditing(p); setShowForm(true); }}><Icon name="pencil" size={13} /></button>
                        <button className="ia" title="Elimina" onClick={() => removeProject(p.id)}><Icon name="trash-2" size={13} /></button>
                      </div>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>

      {showForm && <ProgettoForm initial={editing} clients={clients} onClose={() => setShowForm(false)} onSaved={() => { setShowForm(false); load(); }} />}
    </>
  );
}

function ProgettoForm({ initial, clients, onClose, onSaved }) {
  const [f, setF] = useState({
    name: '',
    color: PALETTE[0],
    client_id: '',
    hourly_rate: '',
    budget_euros: '',
    ...(initial || {}),
  });
  const [saving, setSaving] = useState(false);
  const [err, setErr] = useState('');
  const set = (k) => (e) => setF({ ...f, [k]: e.target.value });

  const submit = async (e) => {
    e.preventDefault();
    if (!f.name?.trim()) { setErr('Nome richiesto'); return; }
    setSaving(true); setErr('');
    try {
      const payload = {
        name: f.name.trim(),
        color: f.color || '#6366f1',
        client_id: f.client_id ? Number(f.client_id) : null,
        hourly_rate: f.hourly_rate !== '' ? Number(f.hourly_rate) : null,
        budget_euros: f.budget_euros !== '' ? Number(f.budget_euros) : null,
      };
      if (initial?.id) await apiPr('/api/projects/' + initial.id, { method: 'PATCH', body: payload });
      else await apiPr('/api/projects', { method: 'POST', body: payload });
      onSaved();
    } catch (ex) { setErr(ex.message); }
    finally { setSaving(false); }
  };

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <form className="modal" onClick={(e) => e.stopPropagation()} onSubmit={submit} style={{ width: 500 }}>
        <div className="modal-head">
          <div>
            <div style={{ fontSize: 11, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.1em' }}>{initial?.id ? 'Modifica' : 'Nuovo'} progetto</div>
            <h2 style={{ fontFamily: 'Fraunces', fontSize: 20, fontWeight: 500, margin: '4px 0 0' }}>{initial?.name || 'Progetto'}</h2>
          </div>
          <button type="button" className="btn btn-ic btn-ghost" onClick={onClose}><Icon name="x" size={14} /></button>
        </div>
        <div className="modal-body">
          {err && <div className="err" style={{ marginBottom: 12 }}><Icon name="alert-circle" size={14} /> {err}</div>}

          <div className="field"><label className="label">Nome *</label>
            <input className="input" required autoFocus value={f.name || ''} onChange={set('name')} placeholder="es. Sito web Mario Rossi" />
          </div>

          <div className="field">
            <label className="label">Colore</label>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
              {PALETTE.map((c) => (
                <button key={c} type="button" onClick={() => setF({ ...f, color: c })}
                  style={{
                    width: 30, height: 30, borderRadius: 6, background: c,
                    border: f.color === c ? '3px solid var(--ink)' : '1px solid var(--rule)',
                    cursor: 'pointer', padding: 0,
                  }} />
              ))}
            </div>
          </div>

          <div className="field"><label className="label">Cliente</label>
            <select className="input" value={f.client_id || ''} onChange={set('client_id')}>
              <option value="">— nessun cliente —</option>
              {clients.map((c) => <option key={c.id} value={c.id}>{c.name}</option>)}
            </select>
            <div className="hint">Se associ un cliente, le task del progetto si potranno aggiungere ai promemoria di quel cliente.</div>
          </div>

          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
            <div className="field"><label className="label">Tariffa oraria €/h</label>
              <input className="input mono" type="number" step="0.01" value={f.hourly_rate ?? ''} onChange={set('hourly_rate')} placeholder="50" />
              <div className="hint">Usata come default per le righe da task</div>
            </div>
            <div className="field"><label className="label">Budget €</label>
              <input className="input mono" type="number" step="0.01" value={f.budget_euros ?? ''} onChange={set('budget_euros')} placeholder="3000" />
              <div className="hint">Limite spesa progetto</div>
            </div>
          </div>
        </div>
        <div className="modal-foot">
          <button type="button" className="btn btn-ghost" onClick={onClose}>Annulla</button>
          <div style={{ flex: 1 }} />
          <button className="btn btn-accent" type="submit" disabled={saving}>{saving ? 'Salvataggio…' : (initial?.id ? 'Salva' : 'Crea progetto')}</button>
        </div>
      </form>
    </div>
  );
}

// === DETTAGLIO PROGETTO ====================================================
function ProgettoDettaglio({ id, onBack, onNav }) {
  const [project, setProject] = useState(null);
  const [client, setClient] = useState(null);
  const [tasks, setTasks] = useState([]);
  const [budget, setBudget] = useState(null);
  const [loading, setLoading] = useState(true);
  const [err, setErr] = useState('');
  const [showForm, setShowForm] = useState(false);
  const [allClients, setAllClients] = useState([]);

  const load = () => {
    setLoading(true);
    Promise.all([
      apiPr('/api/projects/' + id),
      apiPr('/api/projects/' + id + '/budget').catch(() => null),
      apiPr('/api/tasks').catch(() => []),
      window.LibroAPI.clients().catch(() => []),
    ]).then(async ([p, b, ts, cs]) => {
      setProject(p);
      setBudget(b);
      setTasks((Array.isArray(ts) ? ts : []).filter((t) => t.project_id === id));
      setAllClients(cs || []);
      if (p?.client_id) {
        try { setClient(await window.LibroAPI.client(p.client_id)); } catch {}
      }
      setLoading(false);
    }).catch((e) => { setErr(e.message); setLoading(false); });
  };
  useEffect(() => { load(); }, [id]);

  const destroy = async () => {
    const stats = tasks.length;
    let msg = `Eliminare il progetto "${project?.name}"?`;
    if (stats) msg += `\n\n${stats} task associate (saranno scollegate, non eliminate).`;
    if (!confirm(msg)) return;
    try { await apiPr('/api/projects/' + id, { method: 'DELETE' }); onBack(); }
    catch (e) { alert(e.message); }
  };

  const tasksByStatus = useMemo(() => {
    const out = { da_fare: [], in_corso: [], completata: [], archiviata: [] };
    for (const t of tasks) (out[t.status] || (out[t.status] = [])).push(t);
    return out;
  }, [tasks]);

  if (err) return <div className="content"><div className="err">{err}</div><button className="btn btn-ghost" onClick={onBack}>← Indietro</button></div>;
  if (loading || !project) return <div className="content" style={{ color: 'var(--ink-3)' }}>Caricamento…</div>;

  const total = tasks.length;
  const active = tasks.filter((t) => t.status !== 'completata' && t.status !== 'archiviata').length;
  const completed = tasksByStatus.completata?.length || 0;
  const totalSeconds = tasks.reduce((s, t) => s + (t.total_seconds || 0), 0);
  const totalHours = Math.round((totalSeconds / 3600) * 100) / 100;

  return (
    <>
      <Topbar crumbs={['Gestionale', 'Progetti', project.name]} />
      <div className="content">
        <div className="page-head">
          <div style={{ display: 'flex', alignItems: 'center', gap: 14, minWidth: 0 }}>
            <button className="btn btn-ghost btn-ic" onClick={onBack}><Icon name="arrow-left" size={14} /></button>
            <div style={{ minWidth: 0 }}>
              <h1 className="page-title" style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                <span style={{ width: 14, height: 14, borderRadius: 4, background: project.color || '#6366f1', display: 'inline-block' }} />
                {project.name}
              </h1>
              <div className="page-sub">
                {client ? (
                  <span style={{ cursor: 'pointer', color: 'var(--accent-ink)' }} onClick={() => onNav('clients/' + client.id)}>
                    <Icon name="user" size={11} /> {client.name}
                  </span>
                ) : <span>Nessun cliente associato</span>}
                {' · '}{total} task ({active} attive · {completed} completate){totalHours > 0 ? ` · ${totalHours}h tracciate` : ''}
              </div>
            </div>
          </div>
          <div style={{ display: 'flex', gap: 6 }}>
            <button className="btn btn-ghost" onClick={() => setShowForm(true)}><Icon name="pencil" size={13} /> Modifica</button>
            <button className="btn btn-ghost" onClick={destroy}><Icon name="trash-2" size={13} /> Elimina</button>
          </div>
        </div>

        <div className="kpi-strip">
          {[
            { label: 'Task attive', value: active, ic: 'list-todo', nonEuro: true },
            { label: 'Completate', value: completed, ic: 'check-circle-2', nonEuro: true },
            { label: 'Tariffa €/h', value: project.hourly_rate || 0, ic: 'banknote' },
            { label: 'Budget', value: project.budget_euros || 0, ic: 'wallet' },
          ].map((k, i) => {
            const { intp, cent } = fmtEURSplit(k.value || 0);
            return (
              <div key={i} className="kpi">
                <div className="kpi-label"><Icon name={k.ic} size={12} stroke={2} />{k.label}</div>
                <div className="kpi-value">
                  {!k.nonEuro && <span style={{ color: 'var(--ink-3)', fontSize: 18, marginRight: 2, fontWeight: 400 }}>€</span>}
                  {k.nonEuro ? k.value : <>{intp}<span className="cent">,{cent}</span></>}
                </div>
              </div>
            );
          })}
        </div>

        {budget && (budget.spent_auto > 0 || budget.spent_manual > 0 || budget.budget) && (
          <div className="card" style={{ background: '#fff', padding: 16, borderRadius: 10, border: '1px solid var(--rule)', marginBottom: 16 }}>
            <div style={{ fontSize: 11, fontWeight: 500, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--ink-3)', marginBottom: 10 }}>Budget</div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', gap: 10, fontSize: 13 }}>
              <div><div style={{ color: 'var(--ink-3)', fontSize: 11 }}>Da time entries</div><div className="mono" style={{ fontWeight: 500 }}>€ {new Intl.NumberFormat('it-IT', { minimumFractionDigits: 2 }).format(budget.spent_auto || 0)}</div></div>
              <div><div style={{ color: 'var(--ink-3)', fontSize: 11 }}>Costi manuali</div><div className="mono" style={{ fontWeight: 500 }}>€ {new Intl.NumberFormat('it-IT', { minimumFractionDigits: 2 }).format(budget.spent_manual || 0)}</div></div>
              <div><div style={{ color: 'var(--ink-3)', fontSize: 11 }}>Budget</div><div className="mono" style={{ fontWeight: 500 }}>{budget.budget != null ? `€ ${new Intl.NumberFormat('it-IT', { minimumFractionDigits: 2 }).format(budget.budget)}` : '—'}</div></div>
              <div><div style={{ color: 'var(--ink-3)', fontSize: 11 }}>Residuo</div><div className="mono" style={{ fontWeight: 500, color: budget.remaining < 0 ? 'var(--red)' : 'var(--green)' }}>{budget.remaining != null ? `€ ${new Intl.NumberFormat('it-IT', { minimumFractionDigits: 2 }).format(budget.remaining)}` : '—'}</div></div>
            </div>
          </div>
        )}

        <div className="card" style={{ background: '#fff', padding: 16, borderRadius: 10, border: '1px solid var(--rule)' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 10 }}>
            <div style={{ fontSize: 11, fontWeight: 500, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--ink-3)' }}>
              Task ({total})
            </div>
            <button className="btn btn-ghost btn-sm" onClick={() => onNav('tasks')}><Icon name="external-link" size={12} /> Vai a Lista Task</button>
          </div>
          {tasks.length === 0 ? (
            <div style={{ padding: 30, textAlign: 'center', color: 'var(--ink-3)', fontSize: 13 }}>Nessuna task associata a questo progetto</div>
          ) : (
            <table className="invoices">
              <thead>
                <tr>
                  <th>Titolo</th>
                  <th style={{ width: 120 }}>Stato</th>
                  <th style={{ width: 110 }}>Scadenza</th>
                  <th style={{ width: 90, textAlign: 'right' }}>Stima</th>
                </tr>
              </thead>
              <tbody>
                {tasks.map((t) => {
                  const statusInfo = ({ da_fare: { l: 'Da fare', cls: 'b-gray', dot: '#6b6458' }, in_corso: { l: 'In corso', cls: 'b-accent', dot: '#4f46e5' }, completata: { l: 'Completata', cls: 'b-green', dot: '#1f7a4d' }, archiviata: { l: 'Archiviata', cls: 'b-outline', dot: '#8a8174' } })[t.status] || { l: t.status, cls: 'b-gray', dot: '#6b6458' };
                  return (
                    <tr key={t.id} style={{ cursor: 'default' }}>
                      <td data-label="Titolo">
                        <div style={{ display: 'flex', alignItems: 'center', gap: 6, fontWeight: 500 }}>
                          {t.urgency === 1 && <span title="Urgente" style={{ color: 'var(--red)' }}>🔴</span>}
                          {t.importance === 1 && <span title="Importante" style={{ color: 'var(--accent)' }}>⭐</span>}
                          <span style={{ textDecoration: t.status === 'completata' ? 'line-through' : 'none', color: t.status === 'completata' ? 'var(--ink-3)' : 'var(--ink)' }}>{t.title}</span>
                        </div>
                      </td>
                      <td data-label="Stato"><span className={`badge ${statusInfo.cls}`}><span className="badge-dot" style={{ background: statusInfo.dot }} />{statusInfo.l}</span></td>
                      <td data-label="Scadenza" className={'mono ' + (t.due_date ? '' : 'cell-empty')} style={{ fontSize: 12, color: 'var(--ink-2)' }}>{t.due_date ? fmtDate(t.due_date) : '—'}</td>
                      <td data-label="Stima" className={'amount mono ' + (t.estimated_minutes ? '' : 'cell-empty')}>{t.estimated_minutes ? `${t.estimated_minutes}m` : '—'}</td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          )}
        </div>
      </div>

      {showForm && <ProgettoForm initial={project} clients={allClients} onClose={() => setShowForm(false)} onSaved={() => { setShowForm(false); load(); }} />}
    </>
  );
}

window.ProgettiScreen = ProgettiScreen;
