// --- Lista Task — versione Libro cablata all'API --------------------------
// Flusso: lista task raggruppate per progetto, timer start/stop/switch con WebSocket sync,
// subtasks inline, filtri urgency/importance/status, drag-reorder via CSS order.

const T_STATUS = {
  da_fare:    { label: 'Da fare',     cls: 'b-gray',   dot: 'var(--ink-3)' },
  in_corso:   { label: 'In corso',    cls: 'b-accent', dot: 'var(--accent)' },
  completata: { label: 'Completata', cls: 'b-green',  dot: 'var(--green)' },
  archiviata: { label: 'Archiviata', cls: 'b-gray',   dot: 'var(--ink-3)' },
};

function fmtDur(seconds) {
  if (seconds == null) return '—';
  const s = Math.max(0, Math.floor(seconds));
  const h = Math.floor(s / 3600);
  const m = Math.floor((s % 3600) / 60);
  const sec = s % 60;
  if (h > 0) return `${h}h ${String(m).padStart(2,'0')}m`;
  if (m > 0) return `${m}m ${String(sec).padStart(2,'0')}s`;
  return `${sec}s`;
}
function fmtHours(seconds) {
  if (!seconds) return '0h';
  return (seconds / 3600).toFixed(2).replace('.', ',') + 'h';
}

// --- Timer store (shared) -----------------------------------------------
window.LibroTimer = window.LibroTimer || {
  state: { isRunning: false, taskId: null, taskTitle: null, startedAt: null, elapsed: 0, isOnBreak: false, breakType: null, breakStartedAt: null, breakElapsed: 0, pausedTaskTitle: null },
  subs: new Set(),
  subscribe(fn) { this.subs.add(fn); return () => this.subs.delete(fn); },
  emit() { for (const fn of this.subs) try { fn(this.state); } catch {} },
  async refresh() {
    try {
      const r = await fetch('/api/time-entries/timer/active', { credentials: 'include' }).then(x => x.status === 200 ? x.json() : null).catch(() => null);
      const b = await fetch('/api/breaks/active', { credentials: 'include' }).then(x => x.status === 200 ? x.json() : null).catch(() => null);
      const runningOk = r && (r.started_at || r.task_id);
      this.state.isRunning = !!runningOk;
      this.state.taskId = r?.task_id || null;
      this.state.taskTitle = r?.task_title || null;
      this.state.startedAt = r?.started_at || null;
      this.state.elapsed = r?.started_at ? Math.floor((Date.now() - new Date(r.started_at).getTime()) / 1000) : 0;
      const breakOk = b && b.started_at && !b.ended_at;
      this.state.isOnBreak = !!breakOk;
      this.state.breakType = b?.type || null;
      this.state.breakStartedAt = b?.started_at || null;
      this.state.breakElapsed = b?.started_at ? Math.floor((Date.now() - new Date(b.started_at).getTime()) / 1000) : 0;
      this.emit();
    } catch {}
  },
  startTick() {
    if (this._tick) return;
    this._tick = setInterval(() => {
      if (this.state.isRunning && this.state.startedAt && !this.state.isOnBreak) {
        this.state.elapsed = Math.floor((Date.now() - new Date(this.state.startedAt).getTime()) / 1000);
        this.emit();
      }
      if (this.state.isOnBreak && this.state.breakStartedAt) {
        this.state.breakElapsed = Math.floor((Date.now() - new Date(this.state.breakStartedAt).getTime()) / 1000);
        this.emit();
      }
    }, 1000);
    this.refresh();
    this._poll = setInterval(() => this.refresh(), 15000);
  },
};
window.LibroTimer.startTick();

function useLibroTimer() {
  const [s, setS] = useState(window.LibroTimer.state);
  useEffect(() => window.LibroTimer.subscribe(setS), []);
  return s;
}

async function apiT(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) : await r.text();
  if (!r.ok) throw new Error((data && data.error) || `HTTP ${r.status}`);
  return data;
}

// --- Task list screen ----------------------------------------------------
function TasksScreen() {
  const [tasks, setTasks] = useState([]);
  const [projects, setProjects] = useState([]);
  const [filter, setFilter] = useState('all'); // all | today | urgent | overdue | completed
  const [projectFilter, setProjectFilter] = useState('all');
  const [q, setQ] = useState('');
  const [loading, setLoading] = useState(true);
  const [showForm, setShowForm] = useState(false);
  const [editing, setEditing] = useState(null);
  const timer = useLibroTimer();

  const load = () => {
    setLoading(true);
    Promise.all([
      apiT('/api/tasks').catch(() => []),
      apiT('/api/projects').catch(() => []),
    ]).then(([tks, prs]) => {
      setTasks(Array.isArray(tks) ? tks : []);
      setProjects(Array.isArray(prs) ? prs : []);
      setLoading(false);
    });
  };
  useEffect(load, []);

  const projById = useMemo(() => Object.fromEntries(projects.map((p) => [p.id, p])), [projects]);

  const today = new Date().toISOString().slice(0, 10);
  const rows = useMemo(() => tasks.filter((t) => {
    if (filter === 'today'    && (t.status === 'completata' || (t.due_date || '').slice(0, 10) !== today)) return false;
    if (filter === 'urgent'   && !t.urgency) return false;
    if (filter === 'overdue'  && (!t.due_date || t.due_date >= today || t.status === 'completata')) return false;
    if (filter === 'completed' && t.status !== 'completata') return false;
    if (filter === 'active'   && (t.status === 'completata' || t.status === 'archiviata')) return false;
    if (projectFilter !== 'all' && String(t.project_id || '') !== String(projectFilter)) return false;
    if (q && !(t.title || '').toLowerCase().includes(q.toLowerCase())) return false;
    return true;
  }), [tasks, filter, projectFilter, q, today]);

  const counts = {
    all: tasks.length,
    active: tasks.filter((t) => t.status !== 'completata' && t.status !== 'archiviata').length,
    today: tasks.filter((t) => t.status !== 'completata' && (t.due_date || '').slice(0, 10) === today).length,
    urgent: tasks.filter((t) => t.urgency && t.status !== 'completata').length,
    overdue: tasks.filter((t) => t.due_date && t.due_date < today && t.status !== 'completata').length,
    completed: tasks.filter((t) => t.status === 'completata').length,
  };

  const startTimer = async (id) => {
    try {
      if (timer.isRunning) await apiT('/api/time-entries/timer/switch', { method: 'POST', body: { task_id: id } });
      else await apiT('/api/time-entries/timer/start', { method: 'POST', body: { task_id: id } });
      window.LibroTimer.refresh();
      load();
    } catch (e) { alert(e.message); }
  };
  const stopTimer = async () => {
    try { await apiT('/api/time-entries/timer/stop', { method: 'POST' }); window.LibroTimer.refresh(); load(); }
    catch (e) { alert(e.message); }
  };
  const complete = async (id) => {
    try { await apiT('/api/tasks/' + id, { method: 'PATCH', body: { status: 'completata' } }); load(); window.LibroTimer.refresh(); }
    catch (e) { alert(e.message); }
  };
  const archive = async (id) => {
    if (!confirm('Archiviare?')) return;
    try { await apiT('/api/tasks/' + id, { method: 'PATCH', body: { status: 'archiviata' } }); load(); }
    catch (e) { alert(e.message); }
  };
  const destroy = async (id) => {
    if (!confirm('Eliminare questa task?')) return;
    try { await apiT('/api/tasks/' + id, { method: 'DELETE' }); load(); }
    catch (e) { alert(e.message); }
  };
  const toggleFlag = async (task, key) => {
    try { await apiT('/api/tasks/' + task.id, { method: 'PATCH', body: { [key]: task[key] ? 0 : 1 } }); load(); }
    catch (e) { alert(e.message); }
  };

  return (
    <>
      <Topbar crumbs={['Gestionale', 'Produttività', 'Lista Task']} />
      <div className="content">
        <div className="page-head">
          <div>
            <h1 className="page-title">Task <em>{counts.active}</em></h1>
            <div className="page-sub">Timer + progetti · urgency/importance · subtasks</div>
          </div>
          <div style={{ display: 'flex', gap: 8 }}>
            {timer.isRunning && <button className="btn btn-ghost" onClick={stopTimer}><Icon name="square" size={14} /> Stop timer</button>}
            <button className="btn btn-accent btn-lg" onClick={() => { setEditing(null); setShowForm(true); }}>
              <Icon name="plus" size={15} /> Nuova task
            </button>
          </div>
        </div>

        <div className="kpi-strip">
          {[
            { label: 'Attive', value: counts.active, ic: 'list-todo' },
            { label: 'Urgenti', value: counts.urgent, ic: 'alert-triangle', kind: counts.urgent > 0 ? 'danger' : '' },
            { label: 'Scadute', value: counts.overdue, ic: 'clock', kind: counts.overdue > 0 ? 'danger' : '' },
            { label: 'Completate', value: counts.completed, ic: 'check-circle-2', kind: 'success' },
          ].map((k, i) => (
            <div key={i} className={`kpi ${k.kind === 'danger' ? 'kpi-danger' : ''}`}>
              <div className="kpi-label"><Icon name={k.ic} size={12} stroke={2} />{k.label}</div>
              <div className="kpi-value" style={{ fontSize: 36 }}>{k.value}</div>
            </div>
          ))}
        </div>

        <div className="tabs">
          {[
            { id: 'all', l: 'Tutte', c: counts.all },
            { id: 'active', l: 'Attive', c: counts.active },
            { id: 'today', l: 'Oggi', c: counts.today },
            { id: 'urgent', l: 'Urgenti', c: counts.urgent },
            { id: 'overdue', l: 'Scadute', c: counts.overdue },
            { id: 'completed', l: 'Fatte', c: counts.completed },
          ].map((t) => (
            <div key={t.id} className={`tab ${filter === t.id ? 'active' : ''}`} onClick={() => setFilter(t.id)}>
              {t.l}<span className="c">{t.c}</span>
            </div>
          ))}
        </div>

        <div className="filter-row">
          <select className="select-sm" value={projectFilter} onChange={(e) => setProjectFilter(e.target.value)}>
            <option value="all">Tutti i progetti</option>
            {projects.map((p) => <option key={p.id} value={p.id}>{p.name}</option>)}
          </select>
          <div className="search-wrap">
            <Icon name="search" size={14} />
            <input className="input" placeholder="Cerca task…" value={q} onChange={(e) => setQ(e.target.value)} />
          </div>
        </div>

        {loading ? (
          <div style={{ padding: 40, textAlign: 'center', color: 'var(--ink-3)' }}>Caricamento…</div>
        ) : rows.length === 0 ? (
          <div style={{ padding: 40, textAlign: 'center', color: 'var(--ink-3)' }}>
            <Icon name="inbox" size={24} style={{ margin: '0 auto 10px' }} />
            <div>Nessuna task con questi filtri</div>
            <div style={{ marginTop: 10 }}>
              <button className="btn btn-accent" onClick={() => { setEditing(null); setShowForm(true); }}>
                <Icon name="plus" size={13} /> Crea la prima
              </button>
            </div>
          </div>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            {rows.map((t) => {
              const p = projById[t.project_id];
              const isActive = timer.isRunning && timer.taskId === t.id;
              return (
                <div key={t.id}
                  className="card task-row"
                  style={{
                    display: 'grid',
                    gridTemplateColumns: 'auto 1fr auto auto',
                    alignItems: 'center',
                    gap: 14,
                    padding: '14px 16px',
                    background: isActive ? 'var(--accent-wash)' : '#fff',
                    borderLeft: `3px solid ${isActive ? 'var(--accent)' : (p?.color || 'transparent')}`,
                    border: isActive ? '1px solid var(--accent)' : '1px solid var(--rule)',
                    borderRadius: 10,
                    cursor: 'pointer',
                    transition: 'border-color 0.15s',
                  }}
                  onClick={(e) => { if (e.target.closest('button')) return; setEditing(t); setShowForm(true); }}
                >
                  <button
                    className="task-check"
                    onClick={(e) => { e.stopPropagation(); t.status === 'completata' ? apiT('/api/tasks/' + t.id, { method: 'PATCH', body: { status: 'da_fare' } }).then(load) : complete(t.id); }}
                    style={{
                      width: 26, height: 26, borderRadius: 6,
                      border: `1.5px solid ${t.status === 'completata' ? 'var(--green)' : 'var(--rule)'}`,
                      background: t.status === 'completata' ? 'var(--green)' : '#fff',
                      color: '#fff', cursor: 'pointer',
                      display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
                    }}
                    title={t.status === 'completata' ? 'Rimetti da fare' : 'Completa'}
                  >
                    {t.status === 'completata' && <Icon name="check" size={14} stroke={3} />}
                  </button>

                  <div style={{ minWidth: 0 }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 14, fontWeight: 500, color: t.status === 'completata' ? 'var(--ink-3)' : 'var(--ink)', textDecoration: t.status === 'completata' ? 'line-through' : 'none' }}>
                      {isActive && <span className="task-pulse" style={{ width: 8, height: 8, borderRadius: '50%', background: 'var(--green)', display: 'inline-block' }} />}
                      {t.urgency === 1 && <span title="Urgente" style={{ color: 'var(--red)' }}>🔴</span>}
                      {t.importance === 1 && <span title="Importante" style={{ color: 'var(--accent)' }}>⭐</span>}
                      <span style={{ overflow: 'hidden', textOverflow: 'ellipsis' }}>{t.title}</span>
                    </div>
                    <div style={{ display: 'flex', gap: 10, marginTop: 4, fontSize: 11.5, color: 'var(--ink-3)', alignItems: 'center' }}>
                      {p && <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}><span style={{ width: 8, height: 8, borderRadius: '50%', background: p.color }} />{p.name}</span>}
                      {t.due_date && <span style={{ color: t.due_date < today && t.status !== 'completata' ? 'var(--red)' : 'var(--ink-3)' }}><Icon name="calendar" size={11} /> {fmtDate(t.due_date)}</span>}
                      {t.estimated_minutes && <span><Icon name="clock" size={11} /> {t.estimated_minutes}m stimati</span>}
                      {t.subtasks_total > 0 && <span>☑ {t.subtasks_done}/{t.subtasks_total}</span>}
                    </div>
                  </div>

                  <div style={{ display: 'flex', gap: 4 }} onClick={(e) => e.stopPropagation()}>
                    <button className="ia" onClick={() => toggleFlag(t, 'urgency')} title="Urgenza">
                      <Icon name="alert-triangle" size={13} style={{ color: t.urgency ? 'var(--red)' : 'var(--ink-3)' }} />
                    </button>
                    <button className="ia" onClick={() => toggleFlag(t, 'importance')} title="Importanza">
                      <Icon name="star" size={13} style={{ color: t.importance ? 'var(--accent)' : 'var(--ink-3)' }} />
                    </button>
                  </div>

                  <div style={{ display: 'flex', gap: 4 }} onClick={(e) => e.stopPropagation()}>
                    {t.status !== 'completata' && (
                      isActive
                        ? <button className="btn btn-accent btn-sm" onClick={stopTimer}><Icon name="square" size={12} /> Stop</button>
                        : <button className="btn btn-ghost btn-sm" onClick={() => startTimer(t.id)} title={timer.isRunning ? 'Switch timer' : 'Avvia timer'}>
                            <Icon name={timer.isRunning ? 'shuffle' : 'play'} size={12} /> {timer.isRunning ? 'Switch' : 'Start'}
                          </button>
                    )}
                    <button className="ia" onClick={() => archive(t.id)} title="Archivia"><Icon name="archive" size={13} /></button>
                    <button className="ia" onClick={() => destroy(t.id)} title="Elimina"><Icon name="trash-2" size={13} /></button>
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>

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

// --- Task form (new/edit) -----------------------------------------------
function TaskForm({ initial, projects, onClose, onSaved }) {
  const [f, setF] = useState({
    title: '', description: '', project_id: '',
    urgency: 0, importance: 0,
    due_date: '', estimated_minutes: '',
    status: 'da_fare',
    ...(initial || {}),
  });
  const [saving, setSaving] = useState(false);
  const [err, setErr] = useState('');
  const [subtasks, setSubtasks] = useState([]);
  const [newSub, setNewSub] = useState('');

  useEffect(() => {
    if (initial?.id) {
      apiT('/api/tasks/' + initial.id).then((t) => setSubtasks(t.subtasks || [])).catch(() => {});
    }
  }, [initial?.id]);

  const set = (k) => (e) => {
    let v = e.target.type === 'number' ? (e.target.value === '' ? '' : parseFloat(e.target.value)) : e.target.value;
    if (e.target.type === 'checkbox') v = e.target.checked ? 1 : 0;
    setF({ ...f, [k]: v });
  };

  const submit = async (e) => {
    e.preventDefault();
    setSaving(true); setErr('');
    try {
      const payload = {
        title: f.title, description: f.description || null,
        project_id: f.project_id || null,
        urgency: f.urgency ? 1 : 0, importance: f.importance ? 1 : 0,
        due_date: f.due_date || null,
        estimated_minutes: f.estimated_minutes || null,
        status: f.status,
      };
      if (initial?.id) await apiT('/api/tasks/' + initial.id, { method: 'PATCH', body: payload });
      else await apiT('/api/tasks', { method: 'POST', body: payload });
      onSaved();
    } catch (e) { setErr(e.message); }
    finally { setSaving(false); }
  };

  const addSub = async () => {
    if (!newSub.trim() || !initial?.id) return;
    try {
      const s = await apiT(`/api/tasks/${initial.id}/subtasks`, { method: 'POST', body: { title: newSub.trim() } });
      setSubtasks([...subtasks, s]);
      setNewSub('');
    } catch (e) { alert(e.message); }
  };
  const toggleSub = async (s) => {
    try {
      await apiT(`/api/tasks/${initial.id}/subtasks/${s.id}`, { method: 'PATCH', body: { completed: !s.completed } });
      setSubtasks(subtasks.map((x) => x.id === s.id ? { ...x, completed: !x.completed } : x));
    } catch (e) { alert(e.message); }
  };
  const delSub = async (s) => {
    try {
      await apiT(`/api/tasks/${initial.id}/subtasks/${s.id}`, { method: 'DELETE' });
      setSubtasks(subtasks.filter((x) => x.id !== s.id));
    } catch (e) { alert(e.message); }
  };

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

          <div className="field"><label className="label">Titolo *</label>
            <input className="input" required autoFocus value={f.title} onChange={set('title')} />
          </div>
          <div className="field"><label className="label">Descrizione</label>
            <textarea className="textarea" rows={3} value={f.description || ''} onChange={set('description')} />
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: '2fr 1fr', gap: 10 }}>
            <div className="field"><label className="label">Progetto</label>
              <select className="input" value={f.project_id || ''} onChange={set('project_id')}>
                <option value="">— nessuno —</option>
                {projects.map((p) => <option key={p.id} value={p.id}>{p.name}</option>)}
              </select>
            </div>
            <div className="field"><label className="label">Stato</label>
              <select className="input" value={f.status} onChange={set('status')}>
                <option value="da_fare">Da fare</option>
                <option value="in_corso">In corso</option>
                <option value="completata">Completata</option>
                <option value="archiviata">Archiviata</option>
              </select>
            </div>
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
            <div className="field"><label className="label">Scadenza</label>
              <input className="input" type="date" value={f.due_date || ''} onChange={set('due_date')} />
            </div>
            <div className="field"><label className="label">Minuti stimati</label>
              <input className="input mono" type="number" value={f.estimated_minutes || ''} onChange={set('estimated_minutes')} />
            </div>
          </div>
          <div style={{ display: 'flex', gap: 16, marginTop: 4 }}>
            <label style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 13, cursor: 'pointer' }}>
              <input type="checkbox" checked={!!f.urgency} onChange={set('urgency')} /> 🔴 Urgente
            </label>
            <label style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 13, cursor: 'pointer' }}>
              <input type="checkbox" checked={!!f.importance} onChange={set('importance')} /> ⭐ Importante
            </label>
          </div>

          {initial?.id && (
            <div style={{ marginTop: 20, paddingTop: 16, borderTop: '1px solid var(--rule)' }}>
              <div className="label" style={{ marginBottom: 8 }}>Subtasks ({subtasks.filter((s) => s.completed).length}/{subtasks.length})</div>
              {subtasks.map((s) => (
                <div key={s.id} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '6px 0', borderBottom: '1px solid var(--rule-2)' }}>
                  <input type="checkbox" checked={!!s.completed} onChange={() => toggleSub(s)} />
                  <span style={{ flex: 1, fontSize: 13, textDecoration: s.completed ? 'line-through' : 'none', color: s.completed ? 'var(--ink-3)' : 'var(--ink)' }}>{s.title}</span>
                  <button type="button" className="ia" onClick={() => delSub(s)}><Icon name="trash-2" size={12} /></button>
                </div>
              ))}
              <div style={{ display: 'flex', gap: 6, marginTop: 8 }}>
                <input className="input" style={{ flex: 1 }} placeholder="Nuova subtask…" value={newSub} onChange={(e) => setNewSub(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); addSub(); } }} />
                <button type="button" className="btn btn-ghost" onClick={addSub}><Icon name="plus" size={13} /></button>
              </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 ? 'Salvo…' : (initial?.id ? 'Salva' : 'Crea task')}</button>
        </div>
      </form>
    </div>
  );
}

window.TasksScreen = TasksScreen;
