/* Home tab: hero, stats, heatmap, volume chart, upcoming */

window.Home = function({ data, progress, gotoTab }) {
  const { weeks, days } = data;
  const today = window.todayISO();
  const currentWeek = window.findCurrentWeek(weeks, days);
  const currentWeekObj = weeks.find(w => w.n === currentWeek);
  const currentWeekDays = days.filter(d => d.week === currentWeek);
  const wkStats = window.computeWeekStats(currentWeekObj, currentWeekDays, progress);

  // Today
  const todayDay = days.find(d => d.iso === today);
  const isBeforeStart = today < window.TRAIN_START;
  const isAfterRace = today > window.RACE_ISO;

  // Days to race
  const daysToRace = window.daysBetween(today, window.RACE_ISO);

  // Total stats
  const totalTargetKm = weeks.reduce((s, w) => s + w.km, 0);
  let totalActualKm = 0;
  let runDays = 0;
  let doneDays = 0;
  let runCount = 0;
  for (const d of days) {
    const p = progress[d.iso];
    if (p?.done) doneDays++;
    if (p?.km) {
      totalActualKm += Number(p.km) || 0;
      runCount++;
    }
  }
  const avgKm = runCount > 0 ? (totalActualKm / runCount).toFixed(1) : "0.0";
  const wkPct = wkStats.target > 0 ? Math.round((wkStats.actualKm / wkStats.target) * 100) : 0;

  // Next activity (next un-done day from today onward)
  const nextDay = days.find(d => d.iso >= today && !progress[d.iso]?.done);

  // Volume chart: target vs actual per week
  const maxKm = Math.max(...weeks.map(w => w.km));

  // Past weeks completion
  const pastWeeks = weeks.filter(w => {
    const wd = days.filter(d => d.week === w.n);
    return wd.every(d => d.iso < today);
  });

  return (
    <div className="page">
      <h1 className="page-title">儀表板</h1>
      <div className="page-sub">總覽 · 訓練進度 · 下一次跑步</div>

      {/* Hero */}
      <div className="hero">
        <div>
          <div className="hero-eyebrow">
            {isBeforeStart ? "訓練即將開始" : isAfterRace ? "比賽已結束" : `今日 · ${window.fmtMD(today)} ${window.dowName(today)}`}
          </div>
          <div className="hero-title">
            {todayDay ? todayDay.title : isBeforeStart ? "週二 4/28 開始 W1" : isAfterRace ? "辛苦了！🎉" : "今日休息"}
          </div>
          <div className="hero-detail">
            {todayDay ? (
              <span>{todayDay.detail} · 階段：<b>{currentWeekObj?.title}</b></span>
            ) : (
              <span>目標：<b>9/20 (日) 21.1 km @ sub-2:00</b> · 平均配速 5:40/km</span>
            )}
          </div>
          <button className="hero-cta" onClick={() => gotoTab("plan")}>
            前往本週計畫 →
          </button>
        </div>
        <div className="countdown-block">
          <div className="countdown-num">{Math.max(0, daysToRace)}</div>
          <div className="countdown-lab">距比賽 / Days</div>
          <div className="countdown-date">9/20 (日) · sub-2:00</div>
        </div>
      </div>

      {/* Stat tiles */}
      <div className="stat-grid">
        <div className="stat accent">
          <div className="lab">本週進度</div>
          <div className="val">{wkPct}<span className="unit">%</span></div>
          <div className="sub">{wkStats.actualKm.toFixed(1)} / {wkStats.target} km · {wkStats.completedDays}/{wkStats.totalDays} 天</div>
        </div>
        <div className="stat">
          <div className="lab">累計總跑量</div>
          <div className="val">{totalActualKm.toFixed(1)}<span className="unit">km</span></div>
          <div className="sub">目標 {totalTargetKm} km · {((totalActualKm/totalTargetKm)*100).toFixed(0)}%</div>
        </div>
        <div className="stat">
          <div className="lab">平均單次距離</div>
          <div className="val">{avgKm}<span className="unit">km</span></div>
          <div className="sub">{runCount} 次跑步紀錄</div>
        </div>
        <div className="stat">
          <div className="lab">完成訓練</div>
          <div className="val">{doneDays}<span className="unit">/ {days.length}</span></div>
          <div className="sub">{Math.round((doneDays/days.length)*100)}% 訓練日打卡</div>
        </div>
      </div>

      {/* Heatmap + Next activity */}
      <div className="dash-cols">
        <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
          <Heatmap data={data} progress={progress} />
          <KmHeatmap data={data} progress={progress} />
        </div>
        <NextUp days={days} progress={progress} weeks={weeks} gotoTab={gotoTab} />
      </div>

      {/* Volume chart */}
      <VolumeChart weeks={weeks} days={days} progress={progress} currentWeek={currentWeek} />

      {/* Phase progress */}
      <PhaseBar weeks={weeks} days={days} progress={progress} />
    </div>
  );
};

/* ---------- Heatmap ---------- */
window.Heatmap = function({ data, progress }) {
  const { weeks, days } = data;
  const today = window.todayISO();
  // Build 7 (rows) x 21 (cols) grid: rows=mon..sun, cols=weeks
  const dayOrder = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
  const rowLabels = ["一", "二", "三", "四", "五", "六", "日"];

  return (
    <div className="card heatmap-card">
      <div className="heatmap-head">
        <h3>計畫熱力圖 · 訓練類別</h3>
        <div className="legend">
          少
          <div className="scale">
            <span style={{ background: "#1a1c1f" }}></span>
            <span style={{ background: "rgba(214,255,60,.25)" }}></span>
            <span style={{ background: "rgba(214,255,60,.5)" }}></span>
            <span style={{ background: "rgba(214,255,60,.75)" }}></span>
            <span style={{ background: "var(--accent)" }}></span>
          </div>
          多
        </div>
      </div>
      <div className="heatmap-grid">
        <div></div>
        {weeks.map(w => <div key={"hh" + w.n}></div>)}
        {dayOrder.map((d, i) => (
          <React.Fragment key={d}>
            <div className="day-label">{rowLabels[i]}</div>
            {weeks.map(w => {
              const day = days.find(x => x.week === w.n && x.day === d);
              if (!day) return <div key={d + w.n} className="heatmap-cell future"></div>;
              const p = progress[day.iso] || {};
              const isToday = day.iso === today;
              const isFuture = day.iso > today;
              const isRace = day.cat === "race";
              // intensity by category: long/race darkest, then quality, then easy/swim
              let intensity = 0;
              if (p.done || (p.km && p.km > 0)) {
                if (day.cat === "long" || day.cat === "race") intensity = 1.0;
                else if (day.cat === "quality") intensity = 0.85;
                else if (day.cat === "easy") intensity = 0.6;
                else intensity = 0.45;
              }
              const bg = intensity > 0
                ? `rgba(214,255,60,${intensity})`
                : (isFuture ? "#1a1c1f" : "var(--bg-elev-2)");
              const meta = window.CAT_META[day.cat];
              return (
                <div
                  key={d + w.n}
                  className={"heatmap-cell" + (isToday ? " today" : "") + (isRace ? " race" : "") + (isFuture ? " future" : "")}
                  style={{ background: isRace ? undefined : bg }}
                >
                  <div className="heatmap-cell-tip">
                    W{w.n} · {window.fmtMD(day.iso)} · {meta.label} · {p.km ? p.km + " km" : (p.done ? "已完成" : day.title)}
                  </div>
                </div>
              );
            })}
          </React.Fragment>
        ))}
      </div>
      <div className="heatmap-week-axis">
        <div></div>
        {weeks.map(w => (
          <div key={"ax" + w.n}>{w.n % 3 === 1 || w.n === weeks.length ? "W" + w.n : ""}</div>
        ))}
      </div>
    </div>
  );
};

/* ---------- Actual km heatmap ---------- */
window.KmHeatmap = function({ data, progress }) {
  const { weeks, days } = data;
  const today = window.todayISO();
  const dayOrder = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
  const rowLabels = ["一", "二", "三", "四", "五", "六", "日"];

  // Find max km logged across all days for normalization
  let maxKm = 0;
  let totalKm = 0;
  let runCount = 0;
  for (const d of days) {
    const km = Number(progress[d.iso]?.km) || 0;
    if (km > maxKm) maxKm = km;
    if (km > 0) { totalKm += km; runCount++; }
  }
  // Floor max to a reasonable bucket so the scale doesn't oversaturate
  const scaleMax = Math.max(maxKm, 8);

  return (
    <div className="card heatmap-card">
      <div className="heatmap-head">
        <h3>實際跑量熱力圖</h3>
        <div className="legend">
          <span style={{ fontFamily: "var(--font-mono)", color: "var(--text-mute)", marginRight: 8 }}>
            總 <b style={{ color: "var(--accent)" }}>{totalKm.toFixed(1)}</b> km · {runCount} 次
          </span>
          0
          <div className="scale">
            <span style={{ background: "#1a1c1f" }}></span>
            <span style={{ background: "rgba(78,201,255,.25)" }}></span>
            <span style={{ background: "rgba(78,201,255,.5)" }}></span>
            <span style={{ background: "rgba(78,201,255,.75)" }}></span>
            <span style={{ background: "#4ec9ff" }}></span>
          </div>
          {scaleMax.toFixed(0)}+ km
        </div>
      </div>
      <div className="heatmap-grid">
        <div></div>
        {weeks.map(w => <div key={"khh" + w.n}></div>)}
        {dayOrder.map((d, i) => (
          <React.Fragment key={"k" + d}>
            <div className="day-label">{rowLabels[i]}</div>
            {weeks.map(w => {
              const day = days.find(x => x.week === w.n && x.day === d);
              if (!day) return <div key={"k" + d + w.n} className="heatmap-cell future"></div>;
              const km = Number(progress[day.iso]?.km) || 0;
              const isToday = day.iso === today;
              const isFuture = day.iso > today;
              const isRace = day.cat === "race";
              // 5-step intensity by km bucket vs scaleMax
              let intensity = 0;
              if (km > 0) {
                const ratio = km / scaleMax;
                if (ratio >= 0.85) intensity = 1.0;
                else if (ratio >= 0.6) intensity = 0.8;
                else if (ratio >= 0.35) intensity = 0.55;
                else if (ratio >= 0.15) intensity = 0.32;
                else intensity = 0.18;
              }
              const bg = intensity > 0
                ? `rgba(78,201,255,${intensity})`
                : (isFuture ? "#1a1c1f" : "var(--bg-elev-2)");
              const meta = window.CAT_META[day.cat];
              return (
                <div
                  key={"k" + d + w.n}
                  className={"heatmap-cell" + (isToday ? " today" : "") + (isRace && km > 0 ? " race" : "") + (isFuture ? " future" : "")}
                  style={{ background: (isRace && km > 0) ? undefined : bg }}
                >
                  <div className="heatmap-cell-tip">
                    W{w.n} · {window.fmtMD(day.iso)} · {meta.label} · {km > 0 ? km.toFixed(1) + " km" : (isFuture ? "未到" : "未記錄")}
                  </div>
                </div>
              );
            })}
          </React.Fragment>
        ))}
      </div>
      <div className="heatmap-week-axis">
        <div></div>
        {weeks.map(w => (
          <div key={"kax" + w.n}>{w.n % 3 === 1 || w.n === weeks.length ? "W" + w.n : ""}</div>
        ))}
      </div>
    </div>
  );
};

/* ---------- Next up ---------- */
window.NextUp = function({ days, progress, weeks, gotoTab }) {
  const today = window.todayISO();
  // Get next 5 upcoming events from today
  const upcoming = days.filter(d => d.iso >= today).slice(0, 6);
  return (
    <div className="card">
      <h3 className="card-title">即將到來</h3>
      <div className="feed">
        {upcoming.length === 0 && (
          <div style={{ color: "var(--text-mute)", padding: "12px 0" }}>沒有更多訓練了。</div>
        )}
        {upcoming.map(d => {
          const p = progress[d.iso] || {};
          const meta = window.CAT_META[d.cat];
          const isToday = d.iso === today;
          return (
            <div key={d.iso} className={"feed-item" + (p.done ? " done" : "")}>
              <div className="feed-date">
                {isToday ? <b style={{ color: "var(--accent)" }}>今日</b> : window.fmtMD(d.iso)}
                <div style={{ fontSize: 10, marginTop: 2 }}>{window.dowName(d.iso)}</div>
              </div>
              <div className="feed-icon" style={{ background: "rgba(255,255,255,.06)" }}>
                {meta.icon}
              </div>
              <div className="feed-body">
                <div className="feed-title">{d.title}</div>
                <div className="feed-detail">{d.detail}</div>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
};

/* ---------- Volume chart ---------- */
window.VolumeChart = function({ weeks, days, progress, currentWeek }) {
  const max = Math.max(...weeks.map(w => w.km));
  return (
    <div className="card heatmap-card" style={{ marginBottom: 18 }}>
      <div className="heatmap-head">
        <h3>每週跑量（目標 vs 實際）</h3>
        <div className="legend">
          <span style={{ display: "inline-block", width: 10, height: 10, background: "var(--bg-elev-2)", borderRadius: 3 }}></span>目標
          &nbsp;&nbsp;
          <span style={{ display: "inline-block", width: 10, height: 10, background: "var(--done)", borderRadius: 3 }}></span>實際
        </div>
      </div>
      <div className="vol-chart">
        {weeks.map(w => {
          const wd = days.filter(d => d.week === w.n);
          const actual = wd.reduce((s, d) => s + (Number(progress[d.iso]?.km) || 0), 0);
          const targetH = (w.km / max) * 100;
          const actualH = (actual / max) * 100;
          const isCur = w.n === currentWeek;
          return (
            <div key={"vbg" + w.n} className="vol-bar"
                 style={{ height: targetH + "%", background: isCur ? "rgba(214,255,60,.25)" : "var(--bg-elev-2)" }}>
              {actual > 0 && (
                <div style={{
                  position: "absolute", bottom: 0, left: 0, right: 0,
                  height: Math.min(100, (actual / w.km) * 100) + "%",
                  background: actual >= w.km ? "var(--accent)" : "var(--done)",
                  borderRadius: "3px 3px 0 0",
                  transition: "height .3s"
                }}></div>
              )}
              <div className="vol-tip">
                W{w.n} · {actual.toFixed(1)} / {w.km} km
              </div>
            </div>
          );
        })}
      </div>
      <div className="vol-axis">
        {weeks.map(w => (
          <div key={"vax" + w.n} className="vol-label">{w.n}</div>
        ))}
      </div>
    </div>
  );
};

/* ---------- Phase progress bar ---------- */
window.PhaseBar = function({ weeks, days, progress }) {
  // Group weeks by phase, compute target + actual km
  const phaseDefs = [
    { key: "base", label: "打底", color: "#4ec9ff", tint: "rgba(78,201,255,.16)" },
    { key: "build", label: "建量", color: "#54d97a", tint: "rgba(84,217,122,.16)" },
    { key: "specific", label: "強化", color: "#ff9a3c", tint: "rgba(255,154,60,.16)" },
    { key: "taper", label: "減量", color: "#b794ff", tint: "rgba(183,148,255,.16)" },
    { key: "race", label: "比賽", color: "#d6ff3c", tint: "rgba(214,255,60,.25)" }
  ];
  const cw = window.findCurrentWeek(weeks, days);
  const phases = phaseDefs.map(def => {
    const ws = weeks.filter(w => w.phase === def.key);
    const target = ws.reduce((s, w) => s + w.km, 0);
    const wDays = days.filter(d => ws.some(w => w.n === d.week));
    const actual = wDays.reduce((s, d) => s + (Number(progress[d.iso]?.km) || 0), 0);
    const isCur = ws.some(w => w.n === cw);
    const pct = target > 0 ? Math.min(1, actual / target) : 0;
    return { ...def, ws, target, actual, isCur, pct };
  });

  const totalTarget = phases.reduce((s, p) => s + p.target, 0);
  const totalActual = phases.reduce((s, p) => s + p.actual, 0);

  return (
    <div className="card">
      <div style={{ display: "flex", alignItems: "baseline", justifyContent: "space-between", marginBottom: 4 }}>
        <h3 className="card-title" style={{ margin: 0 }}>訓練階段進度</h3>
        <div style={{ fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--text-mute)" }}>
          <span style={{ color: "var(--accent)", fontWeight: 700 }}>{totalActual.toFixed(0)}</span>
          <span style={{ margin: "0 4px" }}>/</span>
          <span>{totalTarget} km</span>
          <span style={{ marginLeft: 10, color: "var(--text-dim)" }}>
            {totalTarget > 0 ? Math.round((totalActual / totalTarget) * 100) : 0}%
          </span>
        </div>
      </div>
      <div className="phase-bar">
        {phases.map(p => {
          const isRace = p.key === "race";
          const fillPct = isRace ? (p.actual >= 21 ? 100 : 0) : Math.round(p.pct * 100);
          return (
            <div
              key={p.key}
              className={"phase-cell " + p.key + (p.isCur ? " current" : "")}
              style={{ "--phase-color": p.color, "--phase-tint": p.tint }}
              title={`${p.label} · ${p.actual.toFixed(1)} / ${p.target} km`}
            >
              {!isRace && (
                <div
                  className={"phase-cell-fill" + (fillPct >= 100 ? " full" : "")}
                  style={{ width: fillPct + "%" }}
                ></div>
              )}
              <div className="phase-label">
                {p.label} · W{p.ws[0]?.n}{p.ws.length > 1 ? "–" + p.ws[p.ws.length-1].n : ""}
              </div>
              <div className="phase-num">
                {isRace ? (
                  <>21.1 <span className="pdim">km</span></>
                ) : (
                  <>{p.actual.toFixed(0)}<span className="pdim"> / {p.target} km</span></>
                )}
              </div>
            </div>
          );
        })}
      </div>
      <div className="phase-axis">
        {phases.map(p => (
          <div key={p.key + "ax"}>
            {p.target > 0 ? Math.round(p.pct * 100) + "%" : "—"}
          </div>
        ))}
      </div>
    </div>
  );
};
