/* global React */
/* Calendar view for Ask. Renders when query contains calendar / schedule /
   upcoming / week / this month / agenda etc. Three zoom levels: day · week ·
   month. Focus is always on the requested range; everything else fades to bg. */

const { useState, useMemo } = React;

/* ── fake schedule, punk-brain voice ────────────────────────────────
   Dates are anchored to "today" which the component computes at render.
   Offsets are in days from today (negative = past). Times are 24h.
   "tone" maps to color: pink = punk-brain / warhol, green = different-gear,
   warm = external, cool = personal. */
const AGENDA = [
  // this week (relative to today)
  { d: -2, h: '10:30', dur: 60, t: 'nadia · budget v3 review',      tone: 'green' },
  { d: -2, h: '16:00', dur: 45, t: 'sophia agent call',             tone: 'green' },
  { d: -1, h: '11:00', dur: 30, t: 'stel voice memo — back?',       tone: 'pink', soft: true },
  { d: -1, h: '14:30', dur: 90, t: 'uv · bk2 mix listen',           tone: 'pink' },
  { d:  0, h: '09:00', dur: 30, t: 'morning brain sweep',           tone: 'cool' },
  { d:  0, h: '13:00', dur: 60, t: 'warhol — artist statement',     tone: 'pink', hot: true },
  { d:  0, h: '15:30', dur: 45, t: 'lua school pickup',             tone: 'warm' },
  { d:  1, h: '10:00', dur: 60, t: 'dg weekly · q2 itinerary',      tone: 'green' },
  { d:  1, h: '19:30', dur: 90, t: 'matty dinner',                  tone: 'cool' },
  { d:  2, h: '11:30', dur: 30, t: 'legacy russell — letter nudge', tone: 'pink' },
  { d:  3, h: '12:00', dur: 60, t: 'deana haggag — letter nudge',   tone: 'pink' },
  { d:  4, h: '17:00', dur: 60, t: 'warhol — final assembly',       tone: 'pink', hot: true },
  // next week
  { d:  6, h: '09:30', dur: 60, t: 'press · zine interview',        tone: 'warm' },
  { d:  7, h: '11:00', dur: 45, t: 'nadia · budget final',          tone: 'green' },
  { d:  7, h: '17:00', dur: 0,  t: 'warhol grant — submit',         tone: 'pink', hot: true, pin: true },
  { d:  8, h: '14:00', dur: 60, t: 'sophia — brand deal decide',    tone: 'green' },
  { d:  9, h: '10:00', dur: 90, t: 'uv mix · session 4',            tone: 'pink' },
  { d: 10, h: '16:00', dur: 30, t: 'lua — spring break logistics',  tone: 'warm' },
  // week +2
  { d: 13, h: '11:00', dur: 60, t: 'dg — sophia kickoff?',          tone: 'green' },
  { d: 15, h: '20:00', dur: 120,t: 'stel show · brooklyn',          tone: 'pink' },
  { d: 17, h: '10:00', dur: 60, t: 'warhol — post-submit debrief',  tone: 'pink' },
  // week +3
  { d: 20, h: '13:00', dur: 60, t: 'q2 itinerary — lock',           tone: 'green' },
  { d: 23, h: '18:00', dur: 90, t: 'matty + lua — brooklyn museum', tone: 'cool' },
  // past week (for week mode to show context)
  { d: -6, h: '10:00', dur: 60, t: 'loi accepted · warhol',         tone: 'pink', done: true },
  { d: -5, h: '15:00', dur: 45, t: 'dg weekly',                     tone: 'green', done: true },
  { d: -4, h: '11:00', dur: 30, t: 'sophia — intro call',           tone: 'green', done: true },
  { d: -3, h: '13:00', dur: 60, t: 'uv · lyrics session',           tone: 'pink', done: true },
];

const DOW = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
const MON = ['jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec'];

function startOfWeek(d) { // sunday anchor
  const x = new Date(d); x.setHours(0,0,0,0);
  x.setDate(x.getDate() - x.getDay());
  return x;
}
function addDays(d, n) { const x = new Date(d); x.setDate(x.getDate() + n); return x; }
function sameDay(a, b) {
  return a.getFullYear()===b.getFullYear() && a.getMonth()===b.getMonth() && a.getDate()===b.getDate();
}
function daysBetween(a, b) {
  const A = new Date(a); A.setHours(0,0,0,0);
  const B = new Date(b); B.setHours(0,0,0,0);
  return Math.round((A - B) / 86400000);
}

function CalendarView() {
  const today = useMemo(() => new Date(), []);
  const [mode, setMode] = useState('week'); // 'day' | 'week' | 'month'

  // resolve all agenda items to real Dates
  const events = useMemo(() => AGENDA.map(e => ({
    ...e,
    date: addDays(today, e.d),
  })), [today]);

  const weekStart = startOfWeek(today);
  const monthStart = new Date(today.getFullYear(), today.getMonth(), 1);
  const monthEnd   = new Date(today.getFullYear(), today.getMonth() + 1, 0);

  const kicker = mode === 'day'   ? `${DOW[today.getDay()]} · ${MON[today.getMonth()]} ${today.getDate()}`
               : mode === 'month' ? `${today.toLocaleDateString([], { month: 'long' }).toLowerCase()} ${today.getFullYear()}`
                                  : `week of ${MON[weekStart.getMonth()]} ${weekStart.getDate()}`;

  return (
    <>
      <div className="v-verdict">
        <div className="k">the week · right now</div>
        <div className="t">
          You have <em>three unmoveable things</em> this week — stel's voice memo,
          the artist statement, and the grant submit on the 25th.
          Everything else can slide.
        </div>
      </div>

      <div className="v-cal-head">
        <div className="v-cal-range">{kicker}</div>
        <div className="v-cal-switch">
          {['day','week','month'].map(m => (
            <button key={m}
              className={`sw${mode === m ? ' on' : ''}`}
              onClick={() => setMode(m)}>
              {m}
            </button>
          ))}
        </div>
      </div>

      {mode === 'week'  && <WeekGrid  today={today} events={events} weekStart={weekStart} />}
      {mode === 'day'   && <DayStrip  today={today} events={events} />}
      {mode === 'month' && <MonthGrid today={today} events={events} monthStart={monthStart} monthEnd={monthEnd} />}

      <div className="v-section">what I'd move</div>
      <div className="v-quote">
        Matty dinner is the softest thing on tuesday — if you need runway for
        the artist statement, push it to friday. Everything pink is load-bearing
        for the grant; touch it carefully.
        <span className="src">— claude, reading your week</span>
      </div>

      <div className="v-citations">
        <span className="k">sources</span>
        <span className="n">gcal · primary</span>
        <span className="n">dg · shared</span>
        <span className="n">warhol · deadlines</span>
        <span className="n">threads · #family</span>
      </div>
    </>
  );
}

/* ── WEEK MODE ─────────────────────────────────────────────────────
   Current week large at top. Below: 3 ghost weeks fading to bg.
*/
function WeekGrid({ today, events, weekStart }) {
  const days = Array.from({ length: 7 }, (_, i) => addDays(weekStart, i));
  const nextWeeks = [1, 2, 3].map(w => addDays(weekStart, w * 7));

  const eventsOn = (d) => events
    .filter(e => sameDay(e.date, d))
    .sort((a, b) => a.h.localeCompare(b.h));

  return (
    <div className="v-cal">
      {/* focused week */}
      <div className="v-cal-week focused">
        <div className="v-cal-dow-row">
          {days.map(d => (
            <div key={+d} className={`v-cal-dow${sameDay(d, today) ? ' today' : ''}`}>
              <span className="n">{DOW[d.getDay()]}</span>
              <span className="num">{d.getDate()}</span>
            </div>
          ))}
        </div>
        <div className="v-cal-col-row">
          {days.map(d => {
            const evs = eventsOn(d);
            return (
              <div key={+d} className={`v-cal-col${sameDay(d, today) ? ' today' : ''}`}>
                {evs.length === 0 && <div className="v-cal-empty">·</div>}
                {evs.map((e, i) => (
                  <div key={i} className={`v-cal-ev ${e.tone}${e.hot ? ' hot' : ''}${e.done ? ' done' : ''}${e.soft ? ' soft' : ''}${e.pin ? ' pin' : ''}`}>
                    <span className="tm">{e.h}</span>
                    <span className="tt">{e.t}</span>
                  </div>
                ))}
              </div>
            );
          })}
        </div>
      </div>

      {/* ghost weeks */}
      <div className="v-cal-fade-lbl">upcoming · fading</div>
      {nextWeeks.map((ws, wi) => (
        <div key={+ws} className="v-cal-week ghost" style={{ '--g': (wi + 1) / 4 }}>
          <div className="v-cal-ghost-lbl">
            wk of {MON[ws.getMonth()]} {ws.getDate()}
          </div>
          <div className="v-cal-col-row">
            {Array.from({ length: 7 }, (_, i) => addDays(ws, i)).map(d => {
              const evs = eventsOn(d);
              return (
                <div key={+d} className="v-cal-col ghost">
                  {evs.slice(0, 3).map((e, i) => (
                    <div key={i} className={`v-cal-ev ghost ${e.tone}${e.pin ? ' pin' : ''}`}>
                      <span className="tt">{e.t}</span>
                    </div>
                  ))}
                </div>
              );
            })}
          </div>
        </div>
      ))}
    </div>
  );
}

/* ── DAY MODE ──────────────────────────────────────────────────────
   Today front & center as an hour column. Yesterday + tomorrow ghosted
   on either side.
*/
function DayStrip({ today, events }) {
  const prev = addDays(today, -1);
  const next = addDays(today, +1);
  const hours = Array.from({ length: 14 }, (_, i) => 7 + i); // 7am → 8pm

  const bucket = (d) => events.filter(e => sameDay(e.date, d))
    .sort((a, b) => a.h.localeCompare(b.h));

  const render = (d, ghost) => {
    const evs = bucket(d);
    const byHour = {};
    evs.forEach(e => {
      const hh = parseInt(e.h.split(':')[0], 10);
      (byHour[hh] = byHour[hh] || []).push(e);
    });
    return (
      <div className={`v-cal-day-col${ghost ? ' ghost' : ''}`}>
        <div className="v-cal-day-hdr">
          <span className="n">{DOW[d.getDay()]}</span>
          <span className="num">{MON[d.getMonth()]} {d.getDate()}</span>
          {sameDay(d, today) && <span className="pill">today</span>}
        </div>
        <div className="v-cal-hours">
          {hours.map(h => (
            <div key={h} className="v-cal-hour">
              <span className="lbl">{h <= 12 ? h : h - 12}{h < 12 ? 'a' : 'p'}</span>
              <div className="slot">
                {(byHour[h] || []).map((e, i) => (
                  <div key={i} className={`v-cal-ev ${e.tone}${e.hot ? ' hot' : ''}${e.done ? ' done' : ''}${e.soft ? ' soft' : ''}`}>
                    <span className="tm">{e.h}</span>
                    <span className="tt">{e.t}</span>
                  </div>
                ))}
              </div>
            </div>
          ))}
        </div>
      </div>
    );
  };

  return (
    <div className="v-cal v-cal-day">
      {render(prev, true)}
      {render(today, false)}
      {render(next, true)}
    </div>
  );
}

/* ── MONTH MODE ────────────────────────────────────────────────────
   Full month as grid. Current week is the focused row; other weeks
   fade to bg.
*/
function MonthGrid({ today, events, monthStart }) {
  const gridStart = startOfWeek(monthStart);
  const weeks = 6;
  const rows = Array.from({ length: weeks }, (_, w) =>
    Array.from({ length: 7 }, (_, i) => addDays(gridStart, w * 7 + i))
  );
  const todayWeekIdx = Math.floor(daysBetween(today, gridStart) / 7);

  const eventsOn = (d) => events
    .filter(e => sameDay(e.date, d))
    .sort((a, b) => a.h.localeCompare(b.h));

  return (
    <div className="v-cal v-cal-month">
      <div className="v-cal-dow-row tight">
        {DOW.map(d => <div key={d} className="v-cal-dow tight"><span className="n">{d}</span></div>)}
      </div>
      {rows.map((row, wi) => {
        const inCurrentWeek = wi === todayWeekIdx;
        return (
          <div key={wi}
            className={`v-cal-mrow${inCurrentWeek ? ' focused' : ' ghost'}`}
            style={inCurrentWeek ? null : { '--g': Math.min(Math.abs(wi - todayWeekIdx) / 3, 1) }}>
            {row.map(d => {
              const evs = eventsOn(d);
              const outside = d.getMonth() !== monthStart.getMonth();
              return (
                <div key={+d}
                  className={`v-cal-mcell${sameDay(d, today) ? ' today' : ''}${outside ? ' outside' : ''}`}>
                  <div className="num">{d.getDate()}</div>
                  <div className="dots">
                    {evs.slice(0, 4).map((e, i) => (
                      <div key={i} className={`v-cal-mev ${e.tone}${e.hot ? ' hot' : ''}${e.pin ? ' pin' : ''}`}>
                        <span className="d" />
                        <span className="t">{e.t}</span>
                      </div>
                    ))}
                    {evs.length > 4 && <div className="v-cal-more">+{evs.length - 4}</div>}
                  </div>
                </div>
              );
            })}
          </div>
        );
      })}
    </div>
  );
}

// export to window so ask.jsx can see it
Object.assign(window, { CalendarView });
