/* Medina Fight Lab — athlete controller. Server-backed via MFLApi, offline-tolerant. */
const MONTHS_A = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
const DAYS_A = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
const MONTHS_LONG_A = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
function isoLocal(d) { d = d || new Date(); return new Date(d.getTime() - d.getTimezoneOffset() * 60000).toISOString().slice(0, 10); }
function dateLabelA() { const n = new Date(); return DAYS_A[n.getDay()] + " · " + MONTHS_LONG_A[n.getMonth()] + " " + n.getDate(); }

function AthleteApp({ onSignOut }) {
  const token = window.MFLApi.athleteToken();
  const [data, setData] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [offline, setOffline] = React.useState(false);
  const [tab, setTab] = React.useState("today");
  const [sessionIdx, setSessionIdx] = React.useState(null);

  const load = React.useCallback(async () => {
    setLoading(true);
    try {
      await window.MFLApi.flushPending(token);
      const d = await window.MFLApi.today(token, isoLocal());
      window.MFLApi.cacheToday(d);
      setData(d); setOffline(false);
    } catch (e) {
      const cached = window.MFLApi.getCachedToday();
      if (cached) { setData(cached); setOffline(true); }
      else { setData({ error: e.message }); }
    }
    setLoading(false);
  }, [token]);

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

  if (loading && !data) {
    return <div className="aa-app"><div className="aa-loading">Loading your session…</div></div>;
  }
  if (data && data.error && !data.session && !data.profile) {
    return (
      <div className="aa-app"><div className="aa-loading">
        Couldn't load. {data.error}
        <div style={{ marginTop: 16 }}><button className="aa-textbtn" onClick={load}>Retry</button> · <button className="aa-textbtn" onClick={onSignOut}>Sign out</button></div>
      </div></div>
    );
  }

  const session = data.session;
  const progress = data.progress || { done: [], logs: {}, pct: 0, finished: false };
  const done = new Set(progress.done || []);
  const logs = progress.logs || {};
  const streak = data.streak || 0;
  const history = data.history || [];

  // week stats from history
  const cutoff = isoLocal(new Date(Date.now() - 6 * 86400000));
  const inWeek = history.filter((h) => h.iso >= cutoff);
  const week = {
    sessions: inWeek.length,
    rounds: inWeek.reduce((a, h) => { const m = (h.sub || "").match(/(\d+)\s*round/); return a + (m ? +m[1] : 0); }, 0),
    adherence: inWeek.length ? Math.round(inWeek.reduce((a, h) => a + h.pct, 0) / inWeek.length) : 0,
  };

  const statsFor = (doneSet) => {
    if (!session) return { total: 0, done: 0, pct: 0, minutes: 0 };
    const total = session.rounds.length;
    const dn = session.rounds.filter((r) => doneSet.has(r.id)).length;
    const minutes = session.rounds.reduce((a, r) => a + window.MFL_parseMin(r.time), 0);
    return { total: total, done: dn, pct: total ? Math.round((dn / total) * 100) : 0, minutes: minutes };
  };
  const stats = statsFor(done);

  const sync = (nextDone, nextLogs, finished) => {
    const st = statsFor(new Set(nextDone));
    const payload = {
      date: data.today || isoLocal(),
      sessionId: session.id, title: session.title,
      done: nextDone, logs: nextLogs, pct: st.pct, minutes: st.minutes, finished: !!finished,
    };
    // optimistic local update
    setData((d) => Object.assign({}, d, { progress: { done: nextDone, logs: nextLogs, pct: st.pct, finished: !!finished } }));
    window.MFLApi.postProgress(token, payload)
      .then(() => { window.MFLApi.today(token, isoLocal()).then((d) => { window.MFLApi.cacheToday(d); setData(d); setOffline(false); }).catch(() => {}); })
      .catch(() => { window.MFLApi.queueProgress(payload); setOffline(true); });
  };

  const toggle = (id) => {
    const next = new Set(done); next.has(id) ? next.delete(id) : next.add(id);
    sync(Array.from(next), logs, progress.finished);
  };
  const setLog = (id, patch) => {
    const nextLogs = Object.assign({}, logs, { [id]: patch });
    sync(Array.from(done), nextLogs, progress.finished);
  };
  const startSession = () => {
    const next = session.rounds.findIndex((r) => !done.has(r.id));
    setSessionIdx(next === -1 ? 0 : next);
  };
  const completeRound = () => {
    const r = session.rounds[sessionIdx];
    const next = new Set(done); if (r) next.add(r.id);
    const last = sessionIdx + 1 >= session.rounds.length;
    sync(Array.from(next), logs, last ? true : progress.finished);
    if (last) setSessionIdx(null); else setSessionIdx(sessionIdx + 1);
  };

  let body;
  if (sessionIdx !== null && session && session.rounds[sessionIdx]) {
    body = (
      <SessionScreen
        rounds={session.rounds} idx={sessionIdx}
        log={logs[session.rounds[sessionIdx].id]}
        onLog={(patch) => setLog(session.rounds[sessionIdx].id, patch)}
        onComplete={completeRound} onBack={() => setSessionIdx(null)}
      />
    );
  } else {
    const screen =
      tab === "today"
        ? (session
            ? <TodayScreen session={session} stats={stats} done={done} streak={streak}
                onToggle={toggle} onStart={startSession} dateLabel={dateLabelA()} offline={offline} />
            : <RestDayScreen streak={streak} />)
        : tab === "schedule"
          ? <ScheduleScreen token={token} />
        : tab === "messages"
          ? <MessagesScreen token={token} coachName={data.profile && data.profile.coach} />
        : tab === "history"
          ? <HistoryScreen history={history} week={week} MONTHS={MONTHS_A} />
          : <ProfileScreen profile={data.profile} streak={streak} week={week} onSignOut={onSignOut}
              onUpdate={(patch) => {
                setData((d) => Object.assign({}, d, { profile: Object.assign({}, d.profile, patch) }));
                window.MFLApi.saveProfile(token, patch).catch(() => {});
              }} />;
    body = <React.Fragment>{screen}<TabBar tab={tab} setTab={setTab} /></React.Fragment>;
  }

  return <div className="aa-app">{body}</div>;
}

Object.assign(window, { AthleteApp });
