// Tempo — Weekly page (style TradeSyncer, design system Tempo)
// Une carte par semaine ISO (lundi → dimanche), de la plus récente à la plus ancienne.
// Pour chaque semaine : P&L total, nb trades, gains, pertes, win rate, profit factor,
// moyenne/jour et 7 mini-barres jour (vert = gain, rouge = perte, gris = pas de trade).
// Réutilise les globaux : computeStats, fmtMoney. UI 100% FR, locale fr-FR, Europe/Paris.

// ── Helpers date (locaux, semaine ISO lundi → dimanche) ───────────────
const WEEKLY_JOURS = ['L', 'M', 'M', 'J', 'V', 'S', 'D'];
const WEEKLY_MOIS = ['janv.', 'févr.', 'mars', 'avril', 'mai', 'juin', 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'];

// Date d'un trade (à partir de executed_at), normalisée à minuit, dans le JOUR
// CIVIL du fuseau du profil — cohérent avec le calendrier (groupTradesByDay) et
// daily. On dérive d'abord la clé 'YYYY-MM-DD' via localDayKey (fuseau profil),
// puis on reconstruit une Date locale à minuit pour la logique de semaine.
function weeklyDateOf(t) {
  const key = (typeof localDayKey === 'function')
    ? localDayKey(t.executed_at, (typeof window !== 'undefined' && window.__appTz) || 'Europe/Paris')
    : null;
  if (key && /^\d{4}-\d{2}-\d{2}$/.test(key)) {
    const [y, m, d] = key.split('-').map(Number);
    return new Date(y, m - 1, d);
  }
  const d = new Date(t.executed_at);
  if (isNaN(d.getTime())) return null;
  return new Date(d.getFullYear(), d.getMonth(), d.getDate());
}

// Lundi (00:00) de la semaine contenant `date`.
function weeklyMondayOf(date) {
  const d = new Date(date.getFullYear(), date.getMonth(), date.getDate());
  const dow = (d.getDay() + 6) % 7; // 0 = lundi … 6 = dimanche
  d.setDate(d.getDate() - dow);
  return d;
}

// Numéro de semaine ISO (1–53).
function weeklyIsoWeekNum(date) {
  const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
  const dayNum = (d.getUTCDay() + 6) % 7;
  d.setUTCDate(d.getUTCDate() - dayNum + 3); // jeudi de la semaine
  const firstThursday = new Date(Date.UTC(d.getUTCFullYear(), 0, 4));
  const firstDayNum = (firstThursday.getUTCDay() + 6) % 7;
  firstThursday.setUTCDate(firstThursday.getUTCDate() - firstDayNum + 3);
  return 1 + Math.round((d - firstThursday) / (7 * 24 * 3600 * 1000));
}

// Clé stable de semaine (à partir du lundi) : "YYYY-MM-DD".
function weeklyKeyOf(monday) {
  const y = monday.getFullYear();
  const m = String(monday.getMonth() + 1).padStart(2, '0');
  const d = String(monday.getDate()).padStart(2, '0');
  return `${y}-${m}-${d}`;
}

// Libellé de plage "1 - 7 juin" / "29 mai - 4 juin".
function weeklyRangeLabel(monday) {
  const sunday = new Date(monday.getFullYear(), monday.getMonth(), monday.getDate() + 6);
  const dStart = monday.getDate();
  const dEnd = sunday.getDate();
  const mStart = WEEKLY_MOIS[monday.getMonth()];
  const mEnd = WEEKLY_MOIS[sunday.getMonth()];
  if (monday.getMonth() === sunday.getMonth()) {
    return `${dStart} - ${dEnd} ${mEnd}`;
  }
  return `${dStart} ${mStart} - ${dEnd} ${mEnd}`;
}

// Regroupe les trades par semaine ISO. Retourne un tableau trié du plus récent au plus ancien.
// Chaque élément : { key, weekNum, monday, rangeLabel, trades, stats, days:[7 buckets] }
function weeklyBuildWeeks(trades) {
  const buckets = {};
  for (const t of (trades || [])) {
    const date = weeklyDateOf(t);
    if (!date) continue;
    const monday = weeklyMondayOf(date);
    const key = weeklyKeyOf(monday);
    if (!buckets[key]) buckets[key] = { key, monday, trades: [] };
    buckets[key].trades.push({ _t: t, _date: date });
  }

  const weeks = Object.values(buckets).map(b => {
    // 7 buckets jour (lundi → dimanche)
    const days = [];
    for (let i = 0; i < 7; i++) {
      const dayDate = new Date(b.monday.getFullYear(), b.monday.getMonth(), b.monday.getDate() + i);
      days.push({ date: dayDate, pnl: 0, count: 0 });
    }
    for (const item of b.trades) {
      const dow = (item._date.getDay() + 6) % 7; // 0..6 lundi..dimanche
      const slot = days[dow];
      if (slot) { slot.pnl += Number(item._t.pnl) || 0; slot.count += 1; }
    }
    const rawTrades = b.trades.map(x => x._t);
    const tradedDays = days.filter(d => d.count > 0).length;
    const stats = computeStats(rawTrades);
    return {
      key: b.key,
      monday: b.monday,
      weekNum: weeklyIsoWeekNum(b.monday),
      rangeLabel: weeklyRangeLabel(b.monday),
      trades: rawTrades,
      stats,
      days,
      tradedDays,
      avgPerDay: tradedDays > 0 ? stats.netPnl / tradedDays : 0,
    };
  });

  weeks.sort((a, b) => b.monday - a.monday);
  return weeks;
}

function weeklyFmtPF(pf) {
  if (pf == null) return '—';
  if (!Number.isFinite(pf)) return '∞';
  return pf.toFixed(2).replace('.', ',');
}

function weeklyFmtPct(v) {
  return (Number(v) || 0).toFixed(0) + ' %';
}

// ── Mini-barres jour (7) ──────────────────────────────────────────────
function WeeklyDayBars({ days, height = 34, compact = false }) {
  // Échelle relative à la plus grosse amplitude de la semaine, plancher pour rester lisible.
  const maxAbs = Math.max(1, ...days.map(d => Math.abs(d.pnl)));
  return (
    <div style={{ display: 'flex', alignItems: 'flex-end', gap: compact ? 4 : 6 }}>
      {days.map((d, i) => {
        const has = d.count > 0;
        const tone = !has ? 'var(--bg-elev)' : (d.pnl > 0 ? 'var(--green)' : d.pnl < 0 ? 'var(--red)' : 'var(--fg-4)');
        const ratio = has ? Math.max(0.18, Math.abs(d.pnl) / maxAbs) : 0.14;
        return (
          <div key={i} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 5, flex: 1, minWidth: 0 }}>
            <div style={{ height, width: '100%', display: 'flex', alignItems: 'flex-end', justifyContent: 'center' }}>
              <div
                title={has ? `${WEEKLY_JOURS[i]} · ${fmtMoney(d.pnl, true)} · ${d.count} trade${d.count > 1 ? 's' : ''}` : 'Pas de trade'}
                style={{
                  width: '100%', maxWidth: compact ? 14 : 18,
                  height: `${Math.round(ratio * height)}px`,
                  minHeight: 4, borderRadius: 4,
                  background: tone, opacity: has ? 1 : 0.7,
                }}
              />
            </div>
            <span style={{ fontSize: compact ? 9 : 10, color: 'var(--fg-4)', fontWeight: 500 }}>{WEEKLY_JOURS[i]}</span>
          </div>
        );
      })}
    </div>
  );
}

// ── Une stat de la grille ─────────────────────────────────────────────
function WeeklyStat({ label, value, tone }) {
  return (
    <div>
      <div style={{ fontSize: 11, color: 'var(--fg-3)', fontWeight: 500, marginBottom: 4 }}>{label}</div>
      <div className="num" style={{ fontSize: 15, fontWeight: 600, color: tone || 'var(--fg)', letterSpacing: '-.01em' }}>{value}</div>
    </div>
  );
}

// ── Carte semaine (desktop) ───────────────────────────────────────────
function WeeklyCard({ week, openJournal }) {
  const s = week.stats;
  const pnlTone = s.netPnl > 0 ? 'var(--green)' : s.netPnl < 0 ? 'var(--red)' : 'var(--fg-2)';
  const avgTone = week.avgPerDay > 0 ? 'var(--green)' : week.avgPerDay < 0 ? 'var(--red)' : 'var(--fg)';

  return (
    <div className="card lift" style={{ padding: '20px 22px' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 20, flexWrap: 'wrap' }}>
        {/* Gauche : semaine + plage + mini-barres */}
        <div style={{ minWidth: 230, flex: '1 1 280px' }}>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 10 }}>
            <span style={{ fontSize: 16, fontWeight: 700, letterSpacing: '-.015em', color: 'var(--fg)' }}>Semaine {week.weekNum}</span>
            <span style={{ fontSize: 12.5, color: 'var(--fg-3)' }}>{week.rangeLabel}</span>
          </div>
          <div style={{ marginTop: 16, maxWidth: 320 }}>
            <WeeklyDayBars days={week.days} />
          </div>
        </div>

        {/* Droite : P&L + bouton Journal */}
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 10 }}>
          <button
            onClick={openJournal ? () => openJournal(week) : undefined}
            className="btn btn-outline-blue tap"
            style={{ cursor: openJournal ? 'pointer' : 'default' }}>
            {Ico && Ico.book ? Ico.book : null} Journal
          </button>
          <div className="num" style={{ fontSize: 30, fontWeight: 700, letterSpacing: '-.022em', color: pnlTone, lineHeight: 1 }}>
            {fmtMoney(s.netPnl, true)}
          </div>
          <div style={{ fontSize: 11.5, color: 'var(--fg-3)' }}>P&amp;L de la semaine</div>
        </div>
      </div>

      {/* Grille de stats */}
      <div style={{
        marginTop: 20, paddingTop: 18, borderTop: '1px solid var(--line)',
        display: 'grid', gridTemplateColumns: 'repeat(6, 1fr)', gap: 18,
      }}>
        <WeeklyStat label="Trades" value={<span className="num">{s.count}</span>} />
        <WeeklyStat label="Gains" value={<span className="num">{s.wins}</span>} tone="var(--green)" />
        <WeeklyStat label="Pertes" value={<span className="num">{s.losses}</span>} tone="var(--red)" />
        <WeeklyStat label="Win Rate" value={<span className="num">{weeklyFmtPct(s.winRate)}</span>} />
        <WeeklyStat label="Profit Factor" value={<span className="num">{weeklyFmtPF(s.profitFactor)}</span>} />
        <WeeklyStat label="Moyenne/jour" value={<span className="num">{fmtMoney(week.avgPerDay, true)}</span>} tone={avgTone} />
      </div>
    </div>
  );
}

// ── État vide ─────────────────────────────────────────────────────────
function WeeklyEmpty({ compact = false }) {
  return (
    <div className="card" style={{ padding: compact ? '40px 18px' : '64px 24px', textAlign: 'center' }}>
      <div style={{ fontSize: compact ? 15 : 16, fontWeight: 600, color: 'var(--fg)', marginBottom: 6 }}>
        Aucune semaine à afficher
      </div>
      <div style={{ fontSize: 13, color: 'var(--fg-3)', maxWidth: 420, margin: '0 auto' }}>
        Tes trades regroupés par semaine apparaîtront ici. Ajoute ou importe des trades pour voir tes performances hebdomadaires.
      </div>
    </div>
  );
}

// ── En-tête de stats globales (résumé toutes semaines) ───────────────
function WeeklySummary({ weeks }) {
  const totalPnl = weeks.reduce((a, w) => a + w.stats.netPnl, 0);
  const totalTrades = weeks.reduce((a, w) => a + w.stats.count, 0);
  const greenWeeks = weeks.filter(w => w.stats.netPnl > 0).length;
  const tone = totalPnl > 0 ? 'var(--green)' : totalPnl < 0 ? 'var(--red)' : 'var(--fg)';
  return (
    <div className="card" style={{ padding: '14px 18px', display: 'flex', gap: 28, flexWrap: 'wrap', alignItems: 'center' }}>
      <div>
        <div style={{ fontSize: 11, color: 'var(--fg-3)', fontWeight: 500 }}>P&amp;L cumulé</div>
        <div className="num" style={{ fontSize: 18, fontWeight: 700, color: tone, letterSpacing: '-.015em' }}>{fmtMoney(totalPnl, true)}</div>
      </div>
      <div>
        <div style={{ fontSize: 11, color: 'var(--fg-3)', fontWeight: 500 }}>Semaines</div>
        <div className="num" style={{ fontSize: 18, fontWeight: 700, letterSpacing: '-.015em' }}>{weeks.length}</div>
      </div>
      <div>
        <div style={{ fontSize: 11, color: 'var(--fg-3)', fontWeight: 500 }}>Semaines gagnantes</div>
        <div className="num" style={{ fontSize: 18, fontWeight: 700, letterSpacing: '-.015em' }}>{greenWeeks}<span style={{ fontSize: 12, color: 'var(--fg-4)', fontWeight: 500 }}> / {weeks.length}</span></div>
      </div>
      <div>
        <div style={{ fontSize: 11, color: 'var(--fg-3)', fontWeight: 500 }}>Trades</div>
        <div className="num" style={{ fontSize: 18, fontWeight: 700, letterSpacing: '-.015em' }}>{totalTrades}</div>
      </div>
    </div>
  );
}

// ── Page Weekly (desktop) ─────────────────────────────────────────────
function WeeklyPage({ state, openJournal }) {
  const trades = (state && state.trades) || [];
  const tradesLoading = !!(state && state.tradesLoading);
  const weeks = React.useMemo(() => weeklyBuildWeeks(trades), [trades]);

  return (
    <div style={{ width: '100%', height: '100%', overflow: 'auto', display: 'flex', flexDirection: 'column' }} className="scroll">
      <PageHeader title="Weekly" />
      <div style={{ padding: '20px 24px 32px', flex: 1, maxWidth: 1040, width: '100%', margin: '0 auto' }}>
        <div style={{ marginBottom: 16 }}>
          <FilterBar
            activeTab="all"
            setActiveTab={() => {}}
            tabs={[{ id: 'all', label: 'Toutes les semaines', ico: null }]}
            right={[
              <span key="acct" className="pill pill-gray">Tous les comptes</span>,
              <span key="period" className="pill pill-blue">Tout l'historique</span>,
            ]}
          />
        </div>

        {tradesLoading ? (
          <div className="card" style={{ padding: '40px 24px', textAlign: 'center', color: 'var(--fg-3)', fontSize: 13 }}>Chargement des données…</div>
        ) : weeks.length === 0 ? (
          <WeeklyEmpty />
        ) : (
          <React.Fragment>
            <div style={{ marginBottom: 16 }}>
              <WeeklySummary weeks={weeks} />
            </div>
            <div className="stagger" style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
              {weeks.map(w => (
                <WeeklyCard key={w.key} week={w} openJournal={openJournal} />
              ))}
            </div>
          </React.Fragment>
        )}
      </div>
    </div>
  );
}

// ── Carte semaine (mobile, compacte) ──────────────────────────────────
function WeeklyMobileCard({ week, openJournal }) {
  const s = week.stats;
  const pnlTone = s.netPnl > 0 ? 'var(--green)' : s.netPnl < 0 ? 'var(--red)' : 'var(--fg-2)';
  return (
    <div className="card" style={{ padding: '14px 16px' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12 }}>
        <div style={{ minWidth: 0 }}>
          <div style={{ fontSize: 14, fontWeight: 700, letterSpacing: '-.01em', color: 'var(--fg)' }}>Semaine {week.weekNum}</div>
          <div style={{ fontSize: 11.5, color: 'var(--fg-3)', marginTop: 1 }}>{week.rangeLabel}</div>
        </div>
        <div className="num" style={{ fontSize: 20, fontWeight: 700, color: pnlTone, letterSpacing: '-.018em', whiteSpace: 'nowrap' }}>
          {fmtMoney(s.netPnl, true)}
        </div>
      </div>

      <div style={{ marginTop: 12 }}>
        <WeeklyDayBars days={week.days} height={28} compact />
      </div>

      <div style={{
        marginTop: 12, paddingTop: 11, borderTop: '1px solid var(--line)',
        display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', rowGap: 10, columnGap: 10,
      }}>
        <WeeklyStat label="Trades" value={<span className="num">{s.count}</span>} />
        <WeeklyStat label="Win Rate" value={<span className="num">{weeklyFmtPct(s.winRate)}</span>} />
        <WeeklyStat label="P. Factor" value={<span className="num">{weeklyFmtPF(s.profitFactor)}</span>} />
        <WeeklyStat label="Gains" value={<span className="num">{s.wins}</span>} tone="var(--green)" />
        <WeeklyStat label="Pertes" value={<span className="num">{s.losses}</span>} tone="var(--red)" />
        <WeeklyStat label="Moy/jour" value={<span className="num">{fmtMoney(week.avgPerDay, true)}</span>} tone={week.avgPerDay >= 0 ? 'var(--green)' : 'var(--red)'} />
      </div>

      <button
        onClick={openJournal ? () => openJournal(week) : undefined}
        className="btn btn-outline-blue tap"
        style={{ marginTop: 12, width: '100%', justifyContent: 'center', cursor: openJournal ? 'pointer' : 'default' }}>
        {Ico && Ico.book ? Ico.book : null} Journal
      </button>
    </div>
  );
}

// ── Page Weekly (mobile) ──────────────────────────────────────────────
function WeeklyMobile({ state, openJournal }) {
  const trades = (state && state.trades) || [];
  const tradesLoading = !!(state && state.tradesLoading);
  const weeks = React.useMemo(() => weeklyBuildWeeks(trades), [trades]);

  return (
    <div style={{ width: '100%', height: '100%', overflow: 'auto' }} className="scroll">
      <div style={{ padding: '16px 14px 28px' }}>
        <div style={{ fontSize: 20, fontWeight: 700, letterSpacing: '-.02em', marginBottom: 14 }}>Weekly</div>

        {tradesLoading ? (
          <div className="card" style={{ padding: '32px 18px', textAlign: 'center', color: 'var(--fg-3)', fontSize: 13 }}>Chargement…</div>
        ) : weeks.length === 0 ? (
          <WeeklyEmpty compact />
        ) : (
          <div className="stagger" style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            {weeks.map(w => (
              <WeeklyMobileCard key={w.key} week={w} openJournal={openJournal} />
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

Object.assign(window, { WeeklyPage, WeeklyMobile });
