// ─── Activities — calls · meetings · emails · tasks ──────────

const ACT_KIND = {
  call:    { label:'Anruf',   ico:'phone' },
  meeting: { label:'Termin',  ico:'visits' },
  email:   { label:'E-Mail',  ico:'mail' },
  task:    { label:'Aufgabe', ico:'activities' }
};
const ACT_KIND_OPTS = [['call','Anruf'],['meeting','Termin'],['email','E-Mail'],['task','Aufgabe']];
const REFTYPE_OPTS = [['opportunity','Opportunity'],['account','Account'],['lead','Lead']];
const DUR_OPTS = [['15','15 Min'],['30','30 Min'],['45','45 Min'],['60','1 Std'],['90','1,5 Std'],['120','2 Std'],['240','4 Std']];
function pad2(n) { return String(n).padStart(2, '0'); }
function fmtDate(d) { return d.getFullYear() + '-' + pad2(d.getMonth() + 1) + '-' + pad2(d.getDate()); }

function refOptions(refType) {
  if (refType === 'opportunity') return CRMStore.list('opportunities').map(o => [o.id, o.name]);
  if (refType === 'account') return CRMStore.list('accounts').map(a => [a.id, a.name]);
  if (refType === 'lead') return CRMStore.list('leads').map(l => [l.id, l.company]);
  return [];
}
function refLabel(refType, refId) {
  const e = refType === 'opportunity' ? CRMStore.get('opportunities', refId)
          : refType === 'account' ? CRMStore.get('accounts', refId)
          : refType === 'lead' ? CRMStore.get('leads', refId) : null;
  if (!e) return '—';
  return e.name || e.company || refId;
}

function blankActivity() {
  const today = new Date().toISOString().slice(0, 10);
  return { kind:'call', subject:'', refType:'opportunity', refId:'', when: today + ' 09:00', dur:30, owner:'JS', done:false, note:'' };
}

function ActivityForm({ rec, onClose }) {
  const isNew = !rec.id;
  const [f, setF] = useS(Object.assign(blankActivity(), rec));
  const set = (k, v) => setF(p => ({ ...p, [k]: v }));
  const opts = refOptions(f.refType);
  const canSave = f.subject.trim() && f.refId;
  const save = () => {
    if (!canSave) return;
    if (isNew) { CRMStore.create('activities', f); toast('Aktivität angelegt'); }
    else { CRMStore.update('activities', rec.id, f); toast('Aktivität aktualisiert'); }
    onClose();
  };
  return (
    <Modal wide title={isNew ? 'Neue Aktivität' : 'Aktivität bearbeiten'} sub={isNew ? 'Anruf, Termin, E-Mail oder Aufgabe protokollieren.' : f.id} onClose={onClose}
      footer={<>
        <span className="cmodal-note">{canSave ? 'Bereit zum Speichern' : 'Betreff und Bezug sind erforderlich'}</span>
        <span className="cmodal-foot-right">
          <button className="btn ghost" onClick={onClose}>Abbrechen</button>
          <button className="btn" disabled={!canSave} onClick={save}>{isNew ? 'Anlegen' : 'Speichern'}</button>
        </span>
      </>}>
      <div className="form-grid">
        <Field label="Typ"><Select value={f.kind} onChange={v => set('kind', v)} options={ACT_KIND_OPTS} /></Field>
        <Field label="Owner"><Select value={f.owner} onChange={v => set('owner', v)} options={OWNER_OPTS} /></Field>
        <Field label="Betreff" req full><TextInput value={f.subject} onChange={v => set('subject', v)} placeholder="z. B. Discovery Call mit CTO" /></Field>
        <Field label="Bezug auf"><Select value={f.refType} onChange={v => { set('refType', v); set('refId', ''); }} options={REFTYPE_OPTS} /></Field>
        <Field label="Datensatz" req><Select value={f.refId} onChange={v => set('refId', v)} options={[['','— wählen —'], ...opts]} /></Field>
        <Field label="Datum"><input className="form-input" type="date" value={(f.when.split(' ')[0] || '')} onChange={e => set('when', e.target.value + ' ' + (f.when.split(' ')[1] || '09:00'))} /></Field>
        <Field label="Uhrzeit"><input className="form-input" type="time" value={(f.when.split(' ')[1] || '09:00')} onChange={e => set('when', (f.when.split(' ')[0] || new Date().toISOString().slice(0,10)) + ' ' + e.target.value)} /></Field>
        <Field label="Dauer"><Select value={String(f.dur || 30)} onChange={v => set('dur', Number(v))} options={DUR_OPTS} /></Field>
        <Field label="Status"><Select value={f.done ? 'done' : 'open'} onChange={v => set('done', v === 'done')} options={[['open','Offen'],['done','Erledigt']]} /></Field>
        <Field label="Notiz" full><TextArea value={f.note} onChange={v => set('note', v)} /></Field>
      </div>
    </Modal>
  );
}

// ─── Outlook-style week calendar ─────────────────────────────
const DOW_DE = ['Mo','Di','Mi','Do','Fr','Sa','So'];
const MON_DE = ['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'];
const CAL_H0 = 7, CAL_H1 = 20, CAL_HOUR_H = 46;

function startOfWeek(d) { const x = new Date(d); const off = (x.getDay() + 6) % 7; x.setDate(x.getDate() - off); x.setHours(0,0,0,0); return x; }
function parseWhen(s) { if (!s) return null; const parts = s.split(' '); const p = parts[0].split('-').map(Number); const t = (parts[1] || '09:00').split(':').map(Number); if (!p[0]) return null; return new Date(p[0], p[1]-1, p[2], t[0]||0, t[1]||0); }
function sameDay(a, b) { return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate(); }

function CalWeek({ events, week, setWeek, onEdit }) {
  const grabRef = React.useRef(0);
  const days = Array.from({ length: 7 }, (_, i) => { const d = new Date(week); d.setDate(d.getDate() + i); return d; });
  const hours = []; for (let h = CAL_H0; h <= CAL_H1; h++) hours.push(h);
  const today = new Date();
  const evDated = events.map(e => ({ e, dt: parseWhen(e.when) })).filter(x => x.dt);
  const label = days[0].getDate() + '. ' + MON_DE[days[0].getMonth()] + ' – ' + days[6].getDate() + '. ' + MON_DE[days[6].getMonth()] + ' ' + days[6].getFullYear();

  function layoutDay(d) {
    const list = evDated.filter(x => sameDay(x.dt, d)).sort((a, b) => a.dt - b.dt);
    const laneEnd = [];
    const placed = list.map(x => {
      const start = x.dt.getHours() * 60 + x.dt.getMinutes();
      const end = start + (Number(x.e.dur) || 30);
      let lane = laneEnd.findIndex(le => le <= start);
      if (lane === -1) { lane = laneEnd.length; laneEnd.push(end); } else laneEnd[lane] = end;
      return { e: x.e, start, lane };
    });
    return { placed, lanes: Math.max(1, laneEnd.length) };
  }

  const nav = (delta) => { const w = new Date(week); w.setDate(w.getDate() + delta * 7); setWeek(w); };

  // Drop an event onto a day column at the cursor's vertical position → reschedule
  const onColDrop = (day) => (ev) => {
    ev.preventDefault();
    const id = ev.dataTransfer.getData('text/plain');
    if (!id) return;
    const rect = ev.currentTarget.getBoundingClientRect();
    let mins = ((ev.clientY - rect.top - grabRef.current) / CAL_HOUR_H) * 60 + CAL_H0 * 60;
    mins = Math.round(mins / 15) * 15;                       // snap to 15 min
    mins = Math.max(CAL_H0 * 60, Math.min(mins, CAL_H1 * 60 - 15));
    const when = fmtDate(day) + ' ' + pad2(Math.floor(mins / 60)) + ':' + pad2(mins % 60);
    CRMStore.update('activities', id, { when: when });
    toast('Termin verschoben → ' + DOW_DE[(day.getDay() + 6) % 7] + ' ' + when.split(' ')[1]);
  };

  return (
    <div className="lv-card cal-card">
      <div className="cal-toolbar">
        <div className="cal-nav">
          <button onClick={() => nav(-1)} title="Vorige Woche">‹</button>
          <button className="cal-today" onClick={() => setWeek(startOfWeek(new Date()))}>Heute</button>
          <button onClick={() => nav(1)} title="Nächste Woche">›</button>
        </div>
        <div className="cal-label">{label}</div>
      </div>
      <div className="cal-head">
        <div className="cal-gutter-h"></div>
        {days.map((d, i) => (
          <div key={i} className={"cal-dayhead" + (sameDay(d, today) ? " today" : "")}>
            <span className="cdh-dow">{DOW_DE[i]}</span>
            <span className="cdh-num">{d.getDate()}</span>
          </div>
        ))}
      </div>
      <div className="cal-body">
        <div className="cal-gutter">
          {hours.map(h => <div key={h} className="cal-hour" style={{ height: CAL_HOUR_H }}><span>{String(h).padStart(2,'0')}:00</span></div>)}
        </div>
        {days.map((d, i) => {
          const { placed, lanes } = layoutDay(d);
          const isToday = sameDay(d, today);
          const nowTop = ((today.getHours() * 60 + today.getMinutes()) / 60 - CAL_H0) * CAL_HOUR_H;
          return (
            <div key={i} className="cal-col"
              onDragOver={ev => ev.preventDefault()}
              onDrop={onColDrop(d)}>
              {hours.map(h => <div key={h} className="cal-slot" style={{ height: CAL_HOUR_H }}></div>)}
              {isToday && nowTop >= 0 && nowTop <= (CAL_H1 - CAL_H0 + 1) * CAL_HOUR_H && <div className="cal-now" style={{ top: nowTop }}></div>}
              {placed.map(({ e, start, lane }) => {
                const top = Math.max((start / 60 - CAL_H0) * CAL_HOUR_H, 0);
                const h = Math.max(((Number(e.dur) || 30) / 60) * CAL_HOUR_H - 4, 20);
                const w = 100 / lanes;
                return (
                  <div key={e.id} className={"cal-ev " + e.kind + (e.done ? " done" : "")} draggable
                    style={{ top, height: h, left: 'calc(' + (lane * w) + '% + 2px)', width: 'calc(' + w + '% - 4px)' }}
                    onDragStart={ev => { ev.dataTransfer.setData('text/plain', e.id); ev.dataTransfer.effectAllowed = 'move'; grabRef.current = ev.clientY - ev.currentTarget.getBoundingClientRect().top; ev.currentTarget.classList.add('dragging'); }}
                    onDragEnd={ev => ev.currentTarget.classList.remove('dragging')}
                    onClick={() => onEdit(e)} title={e.subject + ' · ' + (e.dur || 30) + ' Min — ziehen zum Verschieben'}>
                    <span className="ce-time">{(e.when.split(' ')[1] || '')}</span>
                    <b>{e.subject}</b>
                    <span className="ce-ref">{refLabel(e.refType, e.refId)}</span>
                  </div>
                );
              })}
            </div>
          );
        })}
      </div>
    </div>
  );
}

function ActivitiesView() {
  const [q, setQ] = useS('');
  const [tab, setTab] = useS('open');
  const [mode, setMode] = useS('list');
  const [week, setWeek] = useS(startOfWeek(new Date()));
  const [edit, setEdit] = useS(null);
  const [del, setDel] = useS(null);

  const all = scopeOwner(CRMStore.list('activities'));
  const tabs = [['open','Offen',all.filter(a => !a.done).length],['done','Erledigt',all.filter(a => a.done).length],['all','Alle',all.length]];
  let rows = all;
  if (tab === 'open') rows = rows.filter(a => !a.done);
  if (tab === 'done') rows = rows.filter(a => a.done);
  if (q.trim()) { const s = q.toLowerCase(); rows = rows.filter(a => (a.subject + ' ' + refLabel(a.refType, a.refId)).toLowerCase().includes(s)); }
  // sort by when
  rows = rows.slice().sort((a, b) => (a.when < b.when ? -1 : 1));

  const toggle = (a) => { CRMStore.update('activities', a.id, { done: !a.done }); toast(a.done ? 'Als offen markiert' : 'Als erledigt markiert'); };

  return (
    <div className="page">
      <div className="page-title-row">
        <div>
          <h1 className="page-title">Activities</h1>
          <p className="page-sub">Anrufe, Termine, E-Mails und Aufgaben — verknüpft mit Opportunities, Accounts und Leads.</p>
        </div>
        <button className="btn" onClick={() => setEdit(blankActivity())}>{Icons.plus} Neue Aktivität</button>
      </div>

      <Toolbar q={q} onQ={setQ} placeholder="Aktivitäten durchsuchen …" tabs={mode === 'list' ? tabs : null} tab={tab} onTab={setTab}
        right={<div className="view-toggle">
          <button className={"vt" + (mode === 'list' ? ' active' : '')} onClick={() => setMode('list')}>Liste</button>
          <button className={"vt" + (mode === 'cal' ? ' active' : '')} onClick={() => setMode('cal')}>Kalender</button>
        </div>} />

      {mode === 'cal' ? (
        <CalWeek
          events={all.filter(a => !q.trim() || (a.subject + ' ' + refLabel(a.refType, a.refId)).toLowerCase().includes(q.toLowerCase()))}
          week={week} setWeek={setWeek} onEdit={setEdit} />
      ) : (
      <div className="lv-card">
        <div className="lv-card-hd"><h3>{tab === 'done' ? 'Erledigt' : tab === 'all' ? 'Alle Aktivitäten' : 'Offene Aktivitäten'}</h3><span className="sub">{rows.length} Einträge</span></div>
        {rows.length === 0 ? (
          <div className="empty">Keine Aktivitäten. <a onClick={() => setEdit(blankActivity())}>Erste Aktivität anlegen →</a></div>
        ) : (
        <div className="lv-scroll">
        <table className="tbl">
          <thead><tr><th></th><th>Aktivität</th><th>Bezug</th><th>Wann</th><th>Owner</th><th className="num">Aktion</th></tr></thead>
          <tbody>
            {rows.map(a => {
              const k = ACT_KIND[a.kind] || ACT_KIND.task;
              return (
                <tr key={a.id} className={a.done ? 'act-done' : ''} data-kiki-id={a.id} data-kiki-label={a.subject} data-kiki-kind="Aktivität">
                  <td style={{width:34}}>
                    <span className="act-check" onClick={() => toggle(a)} title={a.done ? 'Erledigt' : 'Offen'}>{a.done ? '✓' : ''}</span>
                  </td>
                  <td className="name"><div className="name-cell"><span className="act-ic">{Icons[k.ico]}</span><span><b>{a.subject}</b><span className="sub">{k.label}{a.note ? ' · ' + a.note : ''}</span></span></div></td>
                  <td><span className="ref-link">{refLabel(a.refType, a.refId)}</span><span className="ref-type">{a.refType === 'opportunity' ? 'Opp' : a.refType === 'account' ? 'Account' : 'Lead'}</span></td>
                  <td style={{fontFamily:'var(--font-mono)', fontSize:11.5, color:'var(--muted)', whiteSpace:'nowrap'}}>{a.when}</td>
                  <td>{a.owner}</td>
                  <td className="num">
                    <div className="row-actions">
                      <button className="ra" onClick={() => toggle(a)}>{a.done ? '↺ Offen' : '✓ Erledigt'}</button>
                      <button className="ra icon" title="Bearbeiten" onClick={() => setEdit(a)}>{Icons.edit || '✎'}</button>
                      <button className="ra icon danger" title="Löschen" onClick={() => setDel(a)}>{Icons.trash || '🗑'}</button>
                    </div>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
        </div>
        )}
      </div>
      )}

      {edit && <ActivityForm rec={edit} onClose={() => setEdit(null)} />}
      {del && <Confirm danger text={'Aktivität „' + del.subject + '" löschen?'} confirmLabel="Löschen"
        onConfirm={() => { CRMStore.remove('activities', del.id); toast('Aktivität gelöscht'); setDel(null); }}
        onCancel={() => setDel(null)} />}
    </div>
  );
}
