// Workspace — Bitácora view (dailies, weeklies, retros, free notes).
// Lives next to (not inside) the Vault: Vault is reference, this is journal.
// Entries are time-series, indexed by date, with optional kind & taskIds.

const LOG_KIND_META = {
  daily:   { label: 'Daily',   icon: 'calendar-days', color: 'var(--accent)', desc: 'Lo de hoy' },
  weekly:  { label: 'Weekly',  icon: 'calendar-range', color: 'var(--code)', desc: 'Resumen de la semana' },
  retro:   { label: 'Retro',   icon: 'rotate-ccw', color: 'var(--warn)', desc: 'Qué salió bien / mal' },
  note:    { label: 'Nota',    icon: 'sticky-note', color: 'var(--text-2)', desc: 'Apunte libre' },
};
const LOG_KIND_ORDER = ['daily', 'weekly', 'retro', 'note'];

function BitacoraView() {
  const [entries, setEntries] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [filterKind, setFilterKind] = React.useState(null);
  const [showCompose, setShowCompose] = React.useState(null); // null | { kind } for new, { id, ...e } for edit
  const [openIds, setOpenIds] = React.useState(new Set());

  const refresh = React.useCallback(async () => {
    setLoading(true);
    try {
      const qs = filterKind ? `?kind=${filterKind}` : '';
      const data = await window.api('GET', `/api/log${qs}`);
      setEntries(data);
    } catch (e) { console.error(e); }
    setLoading(false);
  }, [filterKind]);

  React.useEffect(() => { refresh(); }, [refresh]);

  const toggleOpen = (id) => setOpenIds(s => {
    const n = new Set(s); n.has(id) ? n.delete(id) : n.add(id); return n;
  });

  const onDelete = async (id) => {
    if (!confirm('¿Borrar esta entrada?')) return;
    try { await window.api('DELETE', `/api/log/${id}`); await refresh(); }
    catch (e) { console.error(e); }
  };

  // Group entries by date for visual sectioning.
  const byDate = React.useMemo(() => {
    const m = new Map();
    for (const e of entries) {
      if (!m.has(e.date)) m.set(e.date, []);
      m.get(e.date).push(e);
    }
    return Array.from(m.entries()); // [[date, entries[]], …]
  }, [entries]);

  const fmtDateHeader = (iso) => {
    const d = new Date(iso + 'T00:00:00Z');
    const today = new Date(); today.setUTCHours(0,0,0,0);
    const yest = new Date(today.getTime() - 86_400_000);
    if (iso === today.toISOString().slice(0, 10)) return 'Hoy';
    if (iso === yest.toISOString().slice(0, 10)) return 'Ayer';
    return d.toLocaleDateString('es', { weekday: 'long', day: 'numeric', month: 'long' });
  };

  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      <div style={{ padding: '24px 32px 14px', flexShrink: 0 }}>
        <SectionHead level="h1" title="Bitácora"
          sub={`${entries.length} ${entries.length === 1 ? 'entrada' : 'entradas'}${filterKind ? ' · filtro: ' + LOG_KIND_META[filterKind].label.toLowerCase() : ''}`}
          right={<div style={{ display: 'flex', gap: 8 }}>
            {LOG_KIND_ORDER.map(k => (
              <Button key={k} variant={k === 'daily' ? 'primary' : 'secondary'} size="md"
                icon={LOG_KIND_META[k].icon}
                onClick={() => setShowCompose({ kind: k })}>
                {LOG_KIND_META[k].label}
              </Button>
            ))}
          </div>} />
        <div style={{ display: 'flex', gap: 6, marginTop: 14 }}>
          <button className="btn-reset" onClick={() => setFilterKind(null)}
            style={{
              padding: '5px 10px', height: 26, fontSize: 12,
              background: !filterKind ? 'var(--accent-dim)' : 'var(--bg-1)',
              border: `1px solid ${!filterKind ? 'var(--accent)' : 'var(--border)'}`,
              color: !filterKind ? 'var(--accent)' : 'var(--text-1)',
              borderRadius: 6,
            }}>Todos</button>
          {LOG_KIND_ORDER.map(k => {
            const m = LOG_KIND_META[k];
            const active = filterKind === k;
            return (
              <button key={k} className="btn-reset" onClick={() => setFilterKind(active ? null : k)}
                style={{
                  display: 'flex', alignItems: 'center', gap: 5,
                  padding: '5px 10px', height: 26, fontSize: 12,
                  background: active ? 'var(--accent-dim)' : 'var(--bg-1)',
                  border: `1px solid ${active ? 'var(--accent)' : 'var(--border)'}`,
                  color: active ? 'var(--accent)' : 'var(--text-1)',
                  borderRadius: 6,
                }}>
                <Icon name={m.icon} size={11} color={active ? 'var(--accent)' : m.color} />
                {m.label}
              </button>
            );
          })}
        </div>
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: '0 32px 60px' }}>
        {loading && <div style={{ padding: 40, textAlign: 'center', color: 'var(--text-3)', fontSize: 12.5 }}>Cargando…</div>}
        {!loading && entries.length === 0 && (
          <div style={{
            padding: '60px 24px', textAlign: 'center',
            border: '1px dashed var(--border)', borderRadius: 'var(--r-lg)',
            background: 'rgba(22,25,34,.4)',
          }}>
            <Icon name="book-open" size={28} color="var(--text-3)" />
            <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--text-1)', marginTop: 14 }}>Bitácora vacía</div>
            <div style={{ fontSize: 12.5, color: 'var(--text-2)', marginTop: 4, marginBottom: 18 }}>
              Empieza con una daily para registrar lo que hiciste hoy.
            </div>
            <Button variant="primary" icon="calendar-days" onClick={() => setShowCompose({ kind: 'daily' })}>Nueva daily</Button>
          </div>
        )}
        {byDate.map(([date, items]) => (
          <div key={date} style={{ marginBottom: 18 }}>
            <div style={{ display: 'flex', alignItems: 'baseline', gap: 12, padding: '8px 0', borderBottom: '1px solid var(--border)', marginBottom: 8, position: 'sticky', top: 0, background: 'var(--bg-0)', zIndex: 2 }}>
              <span style={{ fontSize: 14, fontWeight: 600, color: 'var(--text-0)', textTransform: 'capitalize' }}>{fmtDateHeader(date)}</span>
              <span className="mono" style={{ fontSize: 11, color: 'var(--text-3)' }}>{date}</span>
              <div style={{ flex: 1 }} />
              <span style={{ fontSize: 11.5, color: 'var(--text-3)' }}>{items.length} {items.length === 1 ? 'entrada' : 'entradas'}</span>
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {items.map(e => (
                <LogCard key={e.id} entry={e}
                  open={openIds.has(e.id)}
                  onToggle={() => toggleOpen(e.id)}
                  onEdit={() => setShowCompose({ ...e, _editing: true })}
                  onDelete={() => onDelete(e.id)} />
              ))}
            </div>
          </div>
        ))}
      </div>

      {showCompose && (
        <LogComposer
          initial={showCompose._editing ? showCompose : null}
          presetKind={!showCompose._editing ? showCompose.kind : undefined}
          onClose={() => setShowCompose(null)}
          onSaved={() => { setShowCompose(null); refresh(); }} />
      )}
    </div>
  );
}

function LogCard({ entry, open, onToggle, onEdit, onDelete }) {
  const m = LOG_KIND_META[entry.kind] || LOG_KIND_META.note;
  const a = ACTORS[entry.actorId] || { name: entry.actorId, color: 'var(--text-2)' };
  const firstLine = (entry.title || (entry.bodyMd.split('\n').find(l => l.trim()) || '').replace(/^#+\s*/, '')).slice(0, 120);
  return (
    <div style={{
      background: 'var(--bg-1)', border: '1px solid var(--border)', borderRadius: 'var(--r-md)',
      borderLeft: `3px solid ${m.color}`,
    }}>
      <button className="btn-reset" onClick={onToggle}
        style={{
          display: 'flex', alignItems: 'center', gap: 12, width: '100%',
          padding: '10px 14px', textAlign: 'left',
        }}>
        <Icon name={open ? 'chevron-down' : 'chevron-right'} size={12} color="var(--text-3)" />
        <div style={{ width: 24, height: 24, borderRadius: 5, display: 'flex', alignItems: 'center', justifyContent: 'center', background: `color-mix(in srgb, ${m.color} 12%, transparent)`, color: m.color }}>
          <Icon name={m.icon} size={12} />
        </div>
        <span style={{ fontSize: 11, fontWeight: 600, color: m.color, textTransform: 'uppercase', letterSpacing: 0.5, minWidth: 50 }}>{m.label}</span>
        <span style={{ flex: 1, fontSize: 13, color: 'var(--text-0)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{firstLine || <span style={{ color: 'var(--text-3)', fontStyle: 'italic' }}>sin título</span>}</span>
        <Avatar actor={entry.actorId} size={18} />
        {entry.taskIds.length > 0 && (
          <span style={{ fontSize: 11, color: 'var(--text-3)', display: 'inline-flex', alignItems: 'center', gap: 3 }}>
            <Icon name="link-2" size={11} /> {entry.taskIds.length}
          </span>
        )}
      </button>
      {open && (
        <div style={{ padding: '0 14px 12px 50px', borderTop: '1px solid var(--border)' }}>
          <div style={{ padding: '12px 0', fontSize: 13, color: 'var(--text-1)', lineHeight: 1.6 }}>
            <RenderedMd md={entry.bodyMd} />
          </div>
          {entry.taskIds.length > 0 && (
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap', marginTop: 6 }}>
              <span style={{ fontSize: 11, color: 'var(--text-3)', textTransform: 'uppercase', letterSpacing: 0.5 }}>Tareas:</span>
              {entry.taskIds.map(tid => <Tag key={tid} mono>{tid}</Tag>)}
            </div>
          )}
          {entry.tags.length > 0 && (
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap', marginTop: 6 }}>
              <span style={{ fontSize: 11, color: 'var(--text-3)', textTransform: 'uppercase', letterSpacing: 0.5 }}>Tags:</span>
              {entry.tags.map(t => <Tag key={t}>{t}</Tag>)}
            </div>
          )}
          <div style={{ display: 'flex', gap: 6, marginTop: 12, paddingTop: 10, borderTop: '1px solid var(--border)' }}>
            <Button variant="ghost" size="sm" icon="pencil" onClick={onEdit}>Editar</Button>
            <Button variant="ghost" size="sm" icon="trash-2" onClick={onDelete}>Borrar</Button>
            <div style={{ flex: 1 }} />
            <span style={{ fontSize: 11, color: 'var(--text-3)', alignSelf: 'center' }}>
              {ACTORS[entry.actorId]?.name || entry.actorId} · {new Date(entry.updatedAt).toLocaleString('es', { hour: '2-digit', minute: '2-digit' })}
            </span>
          </div>
        </div>
      )}
    </div>
  );
}

function LogComposer({ initial, presetKind, onClose, onSaved }) {
  const isEdit = !!initial;
  const [kind, setKind] = React.useState(initial?.kind || presetKind || 'note');
  const [date, setDate] = React.useState(initial?.date || new Date().toISOString().slice(0, 10));
  const [title, setTitle] = React.useState(initial?.title || '');
  const [bodyMd, setBodyMd] = React.useState(initial?.bodyMd || '');
  const [taskIdsRaw, setTaskIdsRaw] = React.useState((initial?.taskIds || []).join(', '));
  const [tagsRaw, setTagsRaw] = React.useState((initial?.tags || []).join(', '));
  const [submitting, setSubmitting] = React.useState(false);
  const [error, setError] = React.useState(null);
  const [templateLoaded, setTemplateLoaded] = React.useState(isEdit);

  // Auto-load a template when opening a new entry of a non-note kind.
  React.useEffect(() => {
    if (templateLoaded || isEdit || bodyMd) return;
    if (kind === 'note') { setTemplateLoaded(true); return; }
    window.api('GET', `/api/log/template?kind=${kind}&date=${date}`)
      .then(t => { setBodyMd(t.body); setTemplateLoaded(true); })
      .catch(() => setTemplateLoaded(true));
  }, [kind, date, templateLoaded, isEdit, bodyMd]);

  const submit = async () => {
    if (!bodyMd.trim()) { setError('El cuerpo no puede estar vacío.'); return; }
    setSubmitting(true);
    setError(null);
    const body = {
      date, kind, title: title.trim() || undefined, bodyMd,
      taskIds: taskIdsRaw.split(/[,\s]+/).filter(Boolean),
      tags: tagsRaw.split(/[,\s]+/).filter(Boolean),
    };
    try {
      if (isEdit) await window.api('PATCH', `/api/log/${initial.id}`, body);
      else await window.api('POST', '/api/log', body);
      onSaved();
    } catch (e) { setError(e.message || 'Error guardando.'); setSubmitting(false); }
  };

  return (
    <Modal title={isEdit ? 'Editar entrada' : `Nueva entrada · ${LOG_KIND_META[kind].label}`} onClose={onClose} width={680}
      footer={<>
        <Button variant="ghost" onClick={onClose}>Cancelar</Button>
        <Button variant="primary" onClick={submit} disabled={submitting || !bodyMd.trim()}>
          {submitting ? 'Guardando…' : isEdit ? 'Guardar cambios' : 'Crear entrada'}
        </Button>
      </>}>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12 }}>
        <FormRow label="Tipo">
          <select value={kind} onChange={(e) => { setKind(e.target.value); setTemplateLoaded(false); }}
            style={{ width: '100%', height: 32, padding: '0 8px', background: 'var(--bg-0)', border: '1px solid var(--border)', borderRadius: 6, color: 'var(--text-0)', fontSize: 12.5, outline: 'none' }}>
            {LOG_KIND_ORDER.map(k => <option key={k} value={k}>{LOG_KIND_META[k].label}</option>)}
          </select>
        </FormRow>
        <FormRow label="Fecha">
          <input type="date" value={date} onChange={(e) => setDate(e.target.value)}
            style={{ width: '100%', height: 32, padding: '0 10px', background: 'var(--bg-0)', border: '1px solid var(--border)', borderRadius: 6, color: 'var(--text-0)', fontSize: 12.5, outline: 'none' }} />
        </FormRow>
        <FormRow label="Título (opcional)">
          <input value={title} onChange={(e) => setTitle(e.target.value)} placeholder="Auto del primer encabezado"
            style={{ width: '100%', height: 32, padding: '0 10px', background: 'var(--bg-0)', border: '1px solid var(--border)', borderRadius: 6, color: 'var(--text-0)', fontSize: 12.5, outline: 'none' }} />
        </FormRow>
      </div>
      <FormRow label="Contenido (Markdown)">
        <textarea value={bodyMd} onChange={(e) => setBodyMd(e.target.value)} rows={14}
          autoFocus
          style={{ width: '100%', padding: '10px 12px', resize: 'vertical', background: 'var(--bg-0)', border: '1px solid var(--border)', borderRadius: 6, color: 'var(--text-0)', fontSize: 13, fontFamily: 'var(--font-mono)', outline: 'none' }} />
      </FormRow>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
        <FormRow label="Tareas relacionadas" hint="Ids T-NNN separados por coma o espacio">
          <input value={taskIdsRaw} onChange={(e) => setTaskIdsRaw(e.target.value)} placeholder="T-001, T-005"
            style={{ width: '100%', height: 32, padding: '0 10px', background: 'var(--bg-0)', border: '1px solid var(--border)', borderRadius: 6, color: 'var(--text-0)', fontSize: 12.5, fontFamily: 'var(--font-mono)', outline: 'none' }} />
        </FormRow>
        <FormRow label="Tags" hint="Etiquetas libres separadas por coma">
          <input value={tagsRaw} onChange={(e) => setTagsRaw(e.target.value)} placeholder="planning, blockers"
            style={{ width: '100%', height: 32, padding: '0 10px', background: 'var(--bg-0)', border: '1px solid var(--border)', borderRadius: 6, color: 'var(--text-0)', fontSize: 12.5, outline: 'none' }} />
        </FormRow>
      </div>
      {error && <div style={{ color: 'var(--danger)', fontSize: 12.5, marginTop: 6 }}>{error}</div>}
    </Modal>
  );
}

Object.assign(window, { BitacoraView, LOG_KIND_META, LOG_KIND_ORDER });
