// Calendar — month grid with events. Click a day to add; click an event to view/delete.

const KINDS = [
  { value: 'exam',       label: 'Exam',       color: 'var(--coral)' },
  { value: 'assignment', label: 'Assignment', color: 'var(--blue)' },
  { value: 'study',      label: 'Study',      color: 'var(--mint)' },
  { value: 'other',      label: 'Other',      color: 'var(--ink-mute)' },
];
const KIND_COLOR = Object.fromEntries(KINDS.map((k) => [k.value, k.color]));

function CalendarScreen() {
  const events = useEvents();
  const subjects = useSubjects();
  const [cursor, setCursor] = React.useState(() => {
    const d = new Date();
    return { y: d.getFullYear(), m: d.getMonth() };
  });
  const [editing, setEditing] = React.useState(null); // { mode: 'create'|'view', date, event }

  const monthName = new Date(cursor.y, cursor.m, 1).toLocaleString(undefined, { month: 'long', year: 'numeric' });
  const cells = monthCells(cursor.y, cursor.m);
  const eventsByDate = groupBy(events, (e) => e.date);
  const today = todayISO();

  return (
    <Page>
      <PageHeader
        breadcrumb={['Calendar']}
        sub={`${events.length} event${events.length === 1 ? '' : 's'} total`}
        actions={
          <>
            <button className="btn ghost small" onClick={() => setCursor(monthOffset(cursor, -1))}>←</button>
            <button className="btn ghost small" onClick={() => {
              const d = new Date();
              setCursor({ y: d.getFullYear(), m: d.getMonth() });
            }}>Today</button>
            <button className="btn ghost small" onClick={() => setCursor(monthOffset(cursor, 1))}>→</button>
            <button className="btn blue small" onClick={() => setEditing({ mode: 'create', date: today })}>{Icon.plus} New event</button>
          </>
        }
      />

      <div style={{ flex: 1, display: 'grid', gridTemplateColumns: '1fr 280px', overflow: 'hidden' }}>
        <div style={{ padding: '16px 22px', overflowY: 'auto' }}>
          <h2 className="display" style={{ margin: '0 0 12px', fontSize: 22, letterSpacing: '-0.02em' }}>{monthName}</h2>

          {/* Day-of-week header */}
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 4, marginBottom: 4 }}>
            {['Sun','Mon','Tue','Wed','Thu','Fri','Sat'].map((d) => (
              <div key={d} style={{ fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.06em', color: 'var(--ink-mute)', padding: '4px 6px' }}>{d}</div>
            ))}
          </div>

          {/* Grid */}
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 4 }}>
            {cells.map((cell) => {
              const dayEvents = eventsByDate[cell.date] || [];
              const isToday = cell.date === today;
              const inMonth = cell.month === cursor.m;
              return (
                <div
                  key={cell.date}
                  onClick={() => setEditing({ mode: 'create', date: cell.date })}
                  style={{
                    minHeight: 90,
                    background: 'white',
                    border: `1px solid ${isToday ? 'var(--blue)' : 'var(--line)'}`,
                    borderRadius: 6,
                    padding: 6,
                    opacity: inMonth ? 1 : 0.45,
                    cursor: 'pointer',
                    display: 'flex', flexDirection: 'column', gap: 3,
                    overflow: 'hidden',
                  }}
                >
                  <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
                    <span className="mono" style={{ fontSize: 11, fontWeight: isToday ? 700 : 500, color: isToday ? 'var(--blue-deep)' : 'var(--ink-soft)' }}>
                      {cell.day}
                    </span>
                    {dayEvents.length > 2 && (
                      <span className="mono" style={{ fontSize: 9, color: 'var(--ink-mute)' }}>+{dayEvents.length - 2}</span>
                    )}
                  </div>
                  {dayEvents.slice(0, 3).map((e) => (
                    <div
                      key={e.id}
                      onClick={(ev) => { ev.stopPropagation(); setEditing({ mode: 'view', event: e }); }}
                      style={{
                        background: KIND_COLOR[e.kind] || 'var(--ink-mute)',
                        color: 'white',
                        fontSize: 10,
                        padding: '2px 6px',
                        borderRadius: 3,
                        overflow: 'hidden',
                        textOverflow: 'ellipsis',
                        whiteSpace: 'nowrap',
                        cursor: 'pointer',
                      }}
                      title={`${e.title} · ${e.kind}`}
                    >
                      {e.title}
                    </div>
                  ))}
                </div>
              );
            })}
          </div>
        </div>

        {/* Right rail: upcoming list */}
        <aside style={{ borderLeft: '1px solid var(--line)', overflowY: 'auto', padding: '16px 16px', background: 'var(--bg)' }}>
          <div style={{ fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--ink-mute)', marginBottom: 8 }}>Upcoming · 30 days</div>
          {upcomingEvents(events, 30).length === 0 ? (
            <div style={{ fontSize: 11.5, color: 'var(--ink-mute)' }}>No upcoming events. Click any day to add one.</div>
          ) : upcomingEvents(events, 30).slice(0, 12).map((e) => (
            <UpcomingItem key={e.id} ev={e} subjects={subjects} onClick={() => setEditing({ mode: 'view', event: e })} />
          ))}

          <div style={{ fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--ink-mute)', marginTop: 16, marginBottom: 6 }}>Legend</div>
          <div style={{ background: 'white', border: '1px solid var(--line)', borderRadius: 6, padding: 10 }}>
            {KINDS.map((k) => (
              <div key={k.value} style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '3px 0', fontSize: 11.5, color: 'var(--ink-soft)' }}>
                <span style={{ width: 10, height: 10, borderRadius: 3, background: k.color }} />
                <span>{k.label}</span>
              </div>
            ))}
          </div>
        </aside>
      </div>

      {editing && <EventDialog
        editing={editing}
        subjects={subjects}
        onClose={() => setEditing(null)}
      />}
    </Page>
  );
}

function UpcomingItem({ ev, subjects, onClick }) {
  const subject = subjects.find((s) => s.id === ev.subject_id);
  const today = todayISO();
  const days = daysBetween(today, ev.date);
  const dayLabel = days === 0 ? 'Today' : days === 1 ? 'Tomorrow' : `in ${days}d`;
  return (
    <div onClick={onClick} style={{ display: 'flex', alignItems: 'flex-start', gap: 8, padding: '6px 0', cursor: 'pointer', borderBottom: '1px solid var(--line-soft)' }}>
      <span style={{ width: 6, height: 6, marginTop: 6, borderRadius: 3, background: KIND_COLOR[ev.kind] || 'var(--ink-mute)', flexShrink: 0 }} />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 11.5, fontWeight: 500, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{ev.title}</div>
        <div style={{ fontSize: 10, color: 'var(--ink-mute)', display: 'flex', gap: 6 }}>
          <span>{ev.date}</span>
          {subject && <span>· {subject.emoji} {subject.name}</span>}
        </div>
      </div>
      <span className="mono" style={{ fontSize: 10, color: 'var(--ink-mute)', flexShrink: 0 }}>{dayLabel}</span>
    </div>
  );
}

function EventDialog({ editing, subjects, onClose }) {
  const initialEvent = editing.mode === 'view' ? editing.event : null;
  const [title, setTitle] = React.useState(initialEvent?.title || '');
  const [kind, setKind] = React.useState(initialEvent?.kind || 'study');
  const [date, setDate] = React.useState(initialEvent?.date || editing.date);
  const [subjectId, setSubjectId] = React.useState(initialEvent?.subject_id || '');
  const [notes, setNotes] = React.useState(initialEvent?.notes || '');
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState(null);

  const isView = editing.mode === 'view';

  const submit = async (e) => {
    e.preventDefault();
    setBusy(true); setErr(null);
    try {
      await addEvent({ title, kind, date, subjectId: subjectId || null, notes });
      onClose();
    } catch (e2) {
      setErr(e2.message);
    } finally {
      setBusy(false);
    }
  };

  const remove = async () => {
    if (!confirm(`Delete "${initialEvent.title}"?`)) return;
    setBusy(true);
    try { await deleteEvent(initialEvent.id); onClose(); }
    catch (e) { setErr(e.message); setBusy(false); }
  };

  return (
    <div onClick={onClose} style={{
      position: 'fixed', inset: 0, background: 'rgba(20,22,43,0.4)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      zIndex: 200, padding: 20, backdropFilter: 'blur(4px)',
    }}>
      <form
        onClick={(e) => e.stopPropagation()}
        onSubmit={isView ? (e) => e.preventDefault() : submit}
        style={{
          width: 380, background: 'white', borderRadius: 12,
          boxShadow: 'var(--shadow-l)', padding: 20,
          display: 'flex', flexDirection: 'column', gap: 12,
        }}
      >
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <h2 style={{ margin: 0, fontSize: 15, fontWeight: 600 }}>{isView ? 'Event' : 'New event'}</h2>
          <button type="button" onClick={onClose} style={{ border: 'none', background: 'transparent', fontSize: 18, cursor: 'pointer', color: 'var(--ink-mute)', padding: 0, lineHeight: 1 }}>×</button>
        </div>

        <Field label="Title">
          <input type="text" value={title} onChange={(e) => setTitle(e.target.value)} disabled={isView} required style={fieldInputStyle} />
        </Field>
        <Field label="Date">
          <input type="date" value={date} onChange={(e) => setDate(e.target.value)} disabled={isView} required style={fieldInputStyle} />
        </Field>
        <Field label="Kind">
          <div style={{ display: 'flex', gap: 4 }}>
            {KINDS.map((k) => (
              <button key={k.value} type="button" disabled={isView} onClick={() => setKind(k.value)}
                style={{
                  flex: 1, padding: '6px 8px', border: `1.5px solid ${kind === k.value ? k.color : 'var(--line)'}`,
                  background: kind === k.value ? k.color : 'white', color: kind === k.value ? 'white' : 'var(--ink-soft)',
                  borderRadius: 6, fontSize: 11, fontWeight: 500, cursor: isView ? 'default' : 'pointer',
                }}>{k.label}</button>
            ))}
          </div>
        </Field>
        <Field label="Subject (optional)">
          <select value={subjectId} onChange={(e) => setSubjectId(e.target.value)} disabled={isView} style={fieldInputStyle}>
            <option value="">— none —</option>
            {subjects.map((s) => <option key={s.id} value={s.id}>{s.emoji} {s.name}</option>)}
          </select>
        </Field>
        <Field label="Notes (optional)">
          <textarea value={notes || ''} onChange={(e) => setNotes(e.target.value)} disabled={isView} rows={3}
            style={{ ...fieldInputStyle, height: 'auto', padding: 8, resize: 'vertical' }} />
        </Field>

        {err && (
          <div style={{ padding: '8px 10px', background: 'var(--coral-soft)', border: '1px solid var(--coral)', borderRadius: 6, fontSize: 11.5, color: '#8a3a20' }}>
            {err}
          </div>
        )}

        <div style={{ display: 'flex', gap: 8, marginTop: 4 }}>
          {isView ? (
            <>
              <button type="button" className="btn ghost small" onClick={remove} disabled={busy} style={{ color: 'var(--coral)', borderColor: 'var(--coral)' }}>Delete</button>
              <div style={{ flex: 1 }} />
              <button type="button" className="btn small" onClick={onClose}>Close</button>
            </>
          ) : (
            <>
              <button type="button" className="btn ghost small" onClick={onClose}>Cancel</button>
              <div style={{ flex: 1 }} />
              <button type="submit" className="btn blue small" disabled={busy}>{busy ? 'Saving…' : 'Save event'}</button>
            </>
          )}
        </div>
      </form>
    </div>
  );
}

function Field({ label, children }) {
  return (
    <label style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
      <span style={{ fontSize: 11, fontWeight: 600, color: 'var(--ink-soft)' }}>{label}</span>
      {children}
    </label>
  );
}

const fieldInputStyle = {
  height: 32, padding: '0 10px',
  border: '1px solid var(--line)', borderRadius: 6,
  fontSize: 12.5, fontFamily: 'inherit', color: 'var(--ink)',
  outline: 'none', background: 'white',
};

// — utilities —
function monthCells(y, m) {
  const first = new Date(y, m, 1);
  const startDay = first.getDay(); // 0=Sun
  const out = [];
  // Leading days from previous month
  for (let i = startDay - 1; i >= 0; i--) {
    const d = new Date(y, m, -i);
    out.push({ day: d.getDate(), month: d.getMonth(), date: dateISO(d) });
  }
  // This month
  const last = new Date(y, m + 1, 0).getDate();
  for (let d = 1; d <= last; d++) {
    const dt = new Date(y, m, d);
    out.push({ day: d, month: m, date: dateISO(dt) });
  }
  // Trailing to fill last week
  while (out.length % 7 !== 0) {
    const last = out[out.length - 1];
    const dt = new Date(last.date + 'T00:00:00');
    dt.setDate(dt.getDate() + 1);
    out.push({ day: dt.getDate(), month: dt.getMonth(), date: dateISO(dt) });
  }
  return out;
}
function dateISO(d) {
  const y = d.getFullYear(), m = String(d.getMonth() + 1).padStart(2, '0'), day = String(d.getDate()).padStart(2, '0');
  return `${y}-${m}-${day}`;
}
function monthOffset({ y, m }, n) {
  const d = new Date(y, m + n, 1);
  return { y: d.getFullYear(), m: d.getMonth() };
}
function groupBy(arr, fn) {
  const out = {};
  for (const it of (arr || [])) {
    const k = fn(it);
    (out[k] = out[k] || []).push(it);
  }
  return out;
}

Object.assign(window, { CalendarScreen });
