// Calendar page: monthly grid view of WODs scheduled by date.
// Components exposed on window: CalendarPage, CalendarGrid, CalendarDayCell, CalendarWODModal.

const { useState, useEffect, useMemo, useCallback } = React;

const WEEKDAYS = ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'];
const MONTHS = ['January','February','March','April','May','June','July','August','September','October','November','December'];

function toLocalDateStr(d) {
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, '0');
  const day = String(d.getDate()).padStart(2, '0');
  return `${y}-${m}-${day}`;
}

function parseLocalDateStr(s) {
  const [y, m, d] = s.split('-').map(Number);
  return new Date(y, m - 1, d);
}

function startOfMonth(d) { return new Date(d.getFullYear(), d.getMonth(), 1); }
function endOfMonth(d)   { return new Date(d.getFullYear(), d.getMonth() + 1, 0); }
function addMonths(d, n) { return new Date(d.getFullYear(), d.getMonth() + n, 1); }
function sameDay(a, b)   { return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate(); }

function buildGridDays(monthCursor) {
  // 6 rows × 7 cols, Sunday-start, padding the previous & next months as needed.
  const first = startOfMonth(monthCursor);
  const startOffset = first.getDay(); // 0 = Sun
  const start = new Date(first);
  start.setDate(first.getDate() - startOffset);
  const days = [];
  for (let i = 0; i < 42; i++) {
    const d = new Date(start);
    d.setDate(start.getDate() + i);
    days.push(d);
  }
  return days;
}

function CalendarPage({ user }) {
  const [monthCursor, setMonthCursor] = useState(() => startOfMonth(new Date()));
  const [entriesByDate, setEntriesByDate] = useState(() => new Map());
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [modalDate, setModalDate] = useState(null);

  const days = useMemo(() => buildGridDays(monthCursor), [monthCursor]);
  const rangeStart = days[0];
  const rangeEnd = days[days.length - 1];

  const reload = useCallback(async () => {
    if (!user) return;
    setLoading(true);
    setError(null);
    try {
      const data = await window.SnatchAPI.listCalendarWods({
        start: toLocalDateStr(rangeStart),
        end: toLocalDateStr(rangeEnd),
      });
      const map = new Map();
      for (const e of (data.entries || [])) {
        const arr = map.get(e.date) || [];
        arr.push(e);
        map.set(e.date, arr);
      }
      setEntriesByDate(map);
    } catch (err) {
      setError(err.message || 'Failed to load calendar');
    } finally {
      setLoading(false);
    }
  }, [user, rangeStart.getTime(), rangeEnd.getTime()]);

  useEffect(() => { reload(); }, [reload]);

  const today = new Date();

  return (
    <div style={{ maxWidth: 1400, margin: '0 auto', padding: '48px 32px' }}>
      <div className="mono" style={{ fontSize: 11, letterSpacing: '0.3em', color: 'var(--accent)' }}>● TRAINING SCHEDULE</div>
      <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', flexWrap: 'wrap', gap: 16, marginTop: 10 }}>
        <div className="display" style={{ fontSize: 'clamp(48px, 8vw, 104px)' }}>Calendar</div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <button className="btn btn-ghost" style={{ padding: '10px 14px', fontSize: 12 }} onClick={() => setMonthCursor(addMonths(monthCursor, -1))}>← Prev</button>
          <button className="btn btn-ghost" style={{ padding: '10px 14px', fontSize: 12 }} onClick={() => setMonthCursor(startOfMonth(new Date()))}>Today</button>
          <button className="btn btn-ghost" style={{ padding: '10px 14px', fontSize: 12 }} onClick={() => setMonthCursor(addMonths(monthCursor, 1))}>Next →</button>
        </div>
      </div>

      <div style={{ display: 'flex', alignItems: 'baseline', gap: 16, marginTop: 24, marginBottom: 12 }}>
        <div className="display" style={{ fontSize: 36 }}>
          {MONTHS[monthCursor.getMonth()]} <span style={{ color: 'var(--accent)' }}>{monthCursor.getFullYear()}</span>
        </div>
        {loading && <span className="mono" style={{ fontSize: 11, opacity: 0.5, letterSpacing: '0.2em' }}>● LOADING</span>}
      </div>

      {error && (
        <div style={{ background: 'rgba(255,45,45,0.1)', border: '1px solid rgba(255,45,45,0.35)', padding: '10px 14px', color: '#fca', fontSize: 13, marginBottom: 16, borderRadius: 3 }}>
          {error}
        </div>
      )}

      <CalendarGrid
        days={days}
        monthCursor={monthCursor}
        today={today}
        entriesByDate={entriesByDate}
        onSelectDate={(d) => setModalDate(toLocalDateStr(d))}
      />

      {modalDate && (
        <CalendarWODModal
          date={modalDate}
          entries={entriesByDate.get(modalDate) || []}
          onClose={() => setModalDate(null)}
          onChanged={reload}
        />
      )}
    </div>
  );
}

function CalendarGrid({ days, monthCursor, today, entriesByDate, onSelectDate }) {
  const cursorMonth = monthCursor.getMonth();

  return (
    <div style={{ background: 'rgba(255,255,255,0.04)', border: '1px solid rgba(255,255,255,0.08)' }}>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', borderBottom: '1px solid rgba(255,255,255,0.08)' }}>
        {WEEKDAYS.map(w => (
          <div key={w} className="mono" style={{ padding: '12px 14px', fontSize: 11, letterSpacing: '0.2em', color: 'rgba(255,255,255,0.45)' }}>{w}</div>
        ))}
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gridAutoRows: 'minmax(110px, auto)' }}>
        {days.map((d, i) => {
          const key = toLocalDateStr(d);
          const inMonth = d.getMonth() === cursorMonth;
          const isToday = sameDay(d, today);
          const isPast = d < today && !isToday;
          const entries = entriesByDate.get(key) || [];
          return (
            <CalendarDayCell
              key={key + '-' + i}
              date={d}
              inMonth={inMonth}
              isToday={isToday}
              isPast={isPast}
              entries={entries}
              onClick={() => onSelectDate(d)}
            />
          );
        })}
      </div>
    </div>
  );
}

function CalendarDayCell({ date, inMonth, isToday, isPast, entries, onClick }) {
  const has = entries.length > 0;
  const bg = !inMonth
    ? 'rgba(255,255,255,0.01)'
    : has
      ? 'rgba(255,45,45,0.08)'
      : 'transparent';
  const borderColor = isToday ? 'var(--accent)' : 'rgba(255,255,255,0.05)';
  const dateColor = !inMonth
    ? 'rgba(255,255,255,0.25)'
    : isToday
      ? 'var(--accent)'
      : isPast
        ? 'rgba(255,255,255,0.5)'
        : '#fff';

  return (
    <div
      onClick={onClick}
      style={{
        position: 'relative',
        padding: 10,
        background: bg,
        borderRight: '1px solid rgba(255,255,255,0.05)',
        borderBottom: '1px solid rgba(255,255,255,0.05)',
        boxShadow: isToday ? `inset 0 0 0 2px ${borderColor}` : 'none',
        cursor: 'pointer',
        transition: 'background .12s ease',
        minHeight: 110,
        display: 'flex',
        flexDirection: 'column',
        gap: 6,
      }}
      onMouseEnter={e => { if (inMonth) e.currentTarget.style.background = has ? 'rgba(255,45,45,0.14)' : 'rgba(255,255,255,0.05)'; }}
      onMouseLeave={e => { e.currentTarget.style.background = bg; }}
    >
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <span className="display" style={{ fontSize: 18, color: dateColor }}>{date.getDate()}</span>
        {isToday && <span className="mono" style={{ fontSize: 9, letterSpacing: '0.2em', color: 'var(--accent)' }}>TODAY</span>}
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 4, minHeight: 0 }}>
        {entries.slice(0, 2).map(e => (
          <div key={e.id} style={{
            background: 'rgba(255,45,45,0.18)',
            border: '1px solid rgba(255,45,45,0.35)',
            color: '#fff',
            fontSize: 11,
            fontWeight: 600,
            padding: '4px 6px',
            borderRadius: 2,
            overflow: 'hidden',
            textOverflow: 'ellipsis',
            whiteSpace: 'nowrap',
          }} title={e.title || 'WOD'}>
            {e.title || 'WOD'}
          </div>
        ))}
        {entries.length > 2 && (
          <div className="mono" style={{ fontSize: 10, color: 'rgba(255,255,255,0.55)', letterSpacing: '0.1em' }}>+{entries.length - 2} more</div>
        )}
      </div>
    </div>
  );
}

function entryToFormState(entry) {
  const wod = entry?.wod || {};
  const content = typeof wod.content === 'string' && wod.content.trim()
    ? wod.content
    : summarizeWod(wod);
  return {
    title: entry?.title || wod.title || '',
    content,
  };
}

function summarizeWod(wod) {
  if (!wod) return '';
  if (typeof wod.content === 'string' && wod.content.trim()) return wod.content;
  const parts = [];
  if (wod.subtitle) parts.push(wod.subtitle);
  if (Array.isArray(wod.blocks)) {
    for (const b of wod.blocks) {
      const items = (b.items || []).map(i => `${i.name}${i.reps ? ' — ' + i.reps : ''}`).join('\n');
      const head = `${b.label || ''}${b.time ? ' · ' + b.time : ''}`;
      parts.push([head.trim(), b.note || '', items].filter(Boolean).join('\n'));
    }
  }
  if (wod.closer) parts.push(`"${wod.closer}"`);
  return parts.join('\n\n');
}

function CalendarWODModal({ date, entries, onClose, onChanged }) {
  const [mode, setMode] = useState('list'); // 'list' | 'add' | 'edit'
  const [editingId, setEditingId] = useState(null);
  const [form, setForm] = useState({ title: '', content: '' });
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState(null);
  const isMobile = typeof window !== 'undefined' && window.matchMedia && window.matchMedia('(max-width: 640px)').matches;

  useEffect(() => {
    if (entries.length === 0) {
      setMode('add');
      setForm({ title: '', content: '' });
      setEditingId(null);
    } else {
      setMode('list');
    }
  }, [date]);

  const friendlyDate = (() => {
    const d = parseLocalDateStr(date);
    return d.toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' });
  })();

  const startEdit = (entry) => {
    setEditingId(entry.id);
    setForm(entryToFormState(entry));
    setMode('edit');
    setErr(null);
  };

  const startAdd = () => {
    setEditingId(null);
    setForm({ title: '', content: '' });
    setMode('add');
    setErr(null);
  };

  const handleSave = async () => {
    if (!form.title.trim() && !form.content.trim()) {
      setErr('Add a title or some workout content.');
      return;
    }
    setBusy(true);
    setErr(null);
    try {
      if (mode === 'edit' && editingId) {
        await window.SnatchAPI.updateCalendarWod(editingId, {
          wodTitle: form.title.trim() || null,
          wodContent: form.content,
        });
      } else {
        await window.SnatchAPI.createCalendarWod({
          date,
          wodTitle: form.title.trim() || null,
          wodContent: form.content,
          source: 'manual',
        });
      }
      await onChanged();
      onClose();
    } catch (e) {
      setErr(e.message || 'Save failed');
    } finally {
      setBusy(false);
    }
  };

  const handleDelete = async (id) => {
    setBusy(true);
    setErr(null);
    try {
      await window.SnatchAPI.deleteCalendarWod(id);
      await onChanged();
      const remaining = entries.filter(e => e.id !== id);
      if (remaining.length === 0) onClose();
      else setMode('list');
    } catch (e) {
      setErr(e.message || 'Delete failed');
    } finally {
      setBusy(false);
    }
  };

  const sheetStyles = isMobile
    ? { position: 'fixed', left: 0, right: 0, bottom: 0, top: 0, borderRadius: 0, padding: 24, maxWidth: '100%', maxHeight: '100vh' }
    : { position: 'relative', borderRadius: 6, padding: 32, width: 'min(560px, 92vw)', maxHeight: '88vh' };

  const titleText = mode === 'add'
    ? `Add WOD to ${friendlyDate}`
    : mode === 'edit'
      ? `Modify WOD for ${friendlyDate}`
      : friendlyDate;

  return (
    <div
      onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}
      style={{
        position: 'fixed', inset: 0, zIndex: 1000,
        background: 'rgba(0,0,0,0.65)',
        backdropFilter: 'blur(6px)',
        display: 'flex',
        alignItems: isMobile ? 'stretch' : 'center',
        justifyContent: 'center',
        padding: isMobile ? 0 : 24,
      }}
    >
      <div style={{
        background: '#0f0f0f',
        border: '1px solid rgba(255,255,255,0.1)',
        color: '#fff',
        overflowY: 'auto',
        ...sheetStyles,
      }}>
        <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 12, marginBottom: 16 }}>
          <div>
            <div className="mono" style={{ fontSize: 10, letterSpacing: '0.25em', color: 'var(--accent)' }}>● CALENDAR</div>
            <div className="display" style={{ fontSize: 26, marginTop: 4, lineHeight: 1.1 }}>{titleText}</div>
          </div>
          <button onClick={onClose} aria-label="Close" style={{ background: 'transparent', border: 0, color: 'rgba(255,255,255,0.5)', fontSize: 22, cursor: 'pointer' }}>×</button>
        </div>

        {err && (
          <div style={{ background: 'rgba(255,45,45,0.12)', border: '1px solid rgba(255,45,45,0.35)', padding: '8px 12px', color: '#fca', fontSize: 13, marginBottom: 14, borderRadius: 3 }}>{err}</div>
        )}

        {mode === 'list' && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            {entries.map(e => (
              <div key={e.id} style={{ border: '1px solid rgba(255,255,255,0.1)', padding: 14, borderRadius: 3 }}>
                <div className="display" style={{ fontSize: 22 }}>{e.title || 'WOD'}</div>
                <div style={{ marginTop: 8, fontSize: 13, color: 'rgba(255,255,255,0.7)', whiteSpace: 'pre-wrap', lineHeight: 1.45 }}>{summarizeWod(e.wod)}</div>
                <div style={{ display: 'flex', gap: 8, marginTop: 12 }}>
                  <button className="btn btn-ghost" style={{ padding: '8px 12px', fontSize: 12 }} onClick={() => startEdit(e)} disabled={busy}>Edit</button>
                  <button className="btn btn-ghost" style={{ padding: '8px 12px', fontSize: 12, borderColor: 'rgba(255,45,45,0.5)' }} onClick={() => handleDelete(e.id)} disabled={busy}>Remove</button>
                </div>
              </div>
            ))}
            <button className="btn btn-primary" style={{ padding: '12px 16px', fontSize: 13, marginTop: 4 }} onClick={startAdd} disabled={busy}>+ Add another WOD</button>
          </div>
        )}

        {(mode === 'add' || mode === 'edit') && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            <label className="mono" style={{ fontSize: 10, letterSpacing: '0.2em', color: 'rgba(255,255,255,0.55)' }}>WOD TITLE</label>
            <input
              value={form.title}
              onChange={e => setForm({ ...form, title: e.target.value })}
              placeholder="e.g. AMRAP 20"
              style={{ background: 'rgba(255,255,255,0.06)', border: '1.5px solid rgba(255,255,255,0.18)', color: '#fff', padding: '12px 14px', fontSize: 15, borderRadius: 3, outline: 'none', fontFamily: 'Archivo' }}
            />

            <label className="mono" style={{ fontSize: 10, letterSpacing: '0.2em', color: 'rgba(255,255,255,0.55)', marginTop: 8 }}>WOD CONTENT</label>
            <textarea
              value={form.content}
              onChange={e => setForm({ ...form, content: e.target.value })}
              placeholder="20 min AMRAP: 10 pull-ups, 15 push-ups, 20 air squats"
              rows={8}
              style={{ background: 'rgba(255,255,255,0.06)', border: '1.5px solid rgba(255,255,255,0.18)', color: '#fff', padding: '12px 14px', fontSize: 14, borderRadius: 3, outline: 'none', fontFamily: 'Archivo', resize: 'vertical', lineHeight: 1.5 }}
            />

            <div style={{ display: 'flex', gap: 8, marginTop: 8, flexWrap: 'wrap', alignItems: 'center' }}>
              <button className="btn btn-primary" style={{ padding: '12px 18px', fontSize: 13 }} onClick={handleSave} disabled={busy}>
                {busy ? 'Saving…' : (mode === 'edit' ? 'Save changes' : 'Save')}
              </button>
              <button className="btn btn-ghost" style={{ padding: '12px 18px', fontSize: 13 }} onClick={() => entries.length > 0 ? setMode('list') : onClose()} disabled={busy}>Cancel</button>
              {mode === 'edit' && editingId && (
                <button
                  className="btn btn-ghost"
                  style={{ padding: '12px 18px', fontSize: 13, borderColor: 'rgba(255,45,45,0.5)' }}
                  onClick={() => handleDelete(editingId)}
                  disabled={busy}
                >Remove from calendar</button>
              )}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

function ReplaceTodayModal({ existing, onChoose, onClose }) {
  return (
    <div
      onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}
      style={{
        position: 'fixed', inset: 0, zIndex: 1100,
        background: 'rgba(0,0,0,0.65)', backdropFilter: 'blur(6px)',
        display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24,
      }}
    >
      <div style={{ background: '#0f0f0f', border: '1px solid rgba(255,255,255,0.1)', color: '#fff', borderRadius: 6, padding: 28, width: 'min(480px, 92vw)' }}>
        <div className="mono" style={{ fontSize: 10, letterSpacing: '0.25em', color: 'var(--accent)' }}>● TODAY ALREADY HAS A WOD</div>
        <div className="display" style={{ fontSize: 26, marginTop: 6 }}>You already have a WOD saved for today.</div>
        <p style={{ fontSize: 14, color: 'rgba(255,255,255,0.7)', marginTop: 10 }}>
          “{existing?.title || 'WOD'}” is already on today's calendar. What do you want to do?
        </p>
        <div style={{ display: 'flex', gap: 8, marginTop: 18, flexWrap: 'wrap' }}>
          <button className="btn btn-primary" style={{ padding: '12px 16px', fontSize: 13 }} onClick={() => onChoose('add')}>Add as additional</button>
          <button className="btn btn-ghost" style={{ padding: '12px 16px', fontSize: 13 }} onClick={() => onChoose('replace')}>Replace existing</button>
          <button className="btn btn-ghost" style={{ padding: '12px 16px', fontSize: 13, marginLeft: 'auto' }} onClick={onClose}>Cancel</button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  CalendarPage,
  CalendarGrid,
  CalendarDayCell,
  CalendarWODModal,
  ReplaceTodayModal,
  toLocalDateStr,
});
