// Reusable parts: Sidebar, Topbar, Stat, Quest row, Heatmap, ConfirmModal

// ── Local helpers ─────────────────────────────────────────────────────────────
const _toDate = (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}`;
};

const _recLabel = (rec) => {
  if (!rec) return '';
  if (rec === 'daily')    return 'Todo dia';
  if (rec === 'weekdays') return 'Seg – Sex';
  if (rec === 'weekend')  return 'Sab – Dom';
  const map = { seg:'Seg', ter:'Ter', qua:'Qua', qui:'Qui', sex:'Sex', sab:'Sab', dom:'Dom' };
  return rec.split(',').map(k => map[k] || k).join(', ');
};

// Build week grid entries for a recurring quest
const getWeekGrid = (recurrence, weekCompletions) => {
  const KEYS   = ['seg','ter','qua','qui','sex','sab','dom']; // index 0=Mon
  const LABELS = ['Seg','Ter','Qua','Qui','Sex','Sab','Dom'];

  // Monday of current week
  const now   = new Date();
  const dayJS = now.getDay(); // 0=Sun
  const diff  = dayJS === 0 ? -6 : 1 - dayJS;
  const mon   = new Date(now);
  mon.setDate(now.getDate() + diff);
  mon.setHours(0, 0, 0, 0);

  let indices;
  if (recurrence === 'daily')    indices = [0,1,2,3,4,5,6];
  else if (recurrence === 'weekdays') indices = [0,1,2,3,4];
  else if (recurrence === 'weekend')  indices = [5,6];
  else indices = recurrence.split(',').map(k => KEYS.indexOf(k)).filter(i => i >= 0);

  const doneSet  = new Set(weekCompletions || []);
  const todayISO = _toDate(now);
  const todayMs  = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime();

  return indices.map(i => {
    const d      = new Date(mon); d.setDate(mon.getDate() + i);
    const dateStr = _toDate(d);
    const dMs    = d.getTime();
    return {
      date:     dateStr,
      label:    LABELS[i],
      done:     doneSet.has(dateStr),
      isToday:  dateStr === todayISO,
      isPast:   dMs < todayMs,
      isFuture: dMs > todayMs,
    };
  });
};

// ── Confirm Modal ─────────────────────────────────────────────────────────────
const ConfirmModal = ({ title, body, confirmLabel = 'Excluir', onConfirm, onCancel }) => (
  <div className="modal-back" onClick={onCancel} style={{ zIndex: 60 }}>
    <div className="confirm-modal" onClick={e => e.stopPropagation()}>
      <div className="confirm-ico"><I.x style={{ width: 22, height: 22 }} /></div>
      <h3 className="display">{title}</h3>
      <p>{body}</p>
      <div className="confirm-actions">
        <button className="btn ghost" onClick={onCancel}>Cancelar</button>
        <button className="btn danger" onClick={onConfirm}><I.x /> {confirmLabel}</button>
      </div>
    </div>
  </div>
);

// ── Sidebar ───────────────────────────────────────────────────────────────────
const Sidebar = ({ route, setRoute, unread, user, onLogout }) => {
  const items = [
    { id: 'home',     label: 'Modo Campanha',    ico: 'shield' },
    { id: 'quests',   label: 'Quest Log',        ico: 'scroll', badge: unread },
    { id: 'badges',   label: 'Salão de troféus', ico: 'trophy' },
    { id: 'rank',     label: 'Ranking',          ico: 'crown' },
    { id: 'profile',  label: 'Aventureiro',      ico: 'user' },
    { id: 'settings', label: 'Configurações',    ico: 'cog' },
  ];
  const initials = (user?.adventurerName || 'A').charAt(0).toUpperCase();
  return (
    <aside className="sidebar">
      <div className="brand">
        <div className="crest">XP</div>
        <div className="name">Produtividade<br />Gameficada<small>v2.0 · campanha</small></div>
      </div>
      <nav className="nav">
        {items.map(it => (
          <button key={it.id} className={`nav-item ${route === it.id ? 'active' : ''}`} onClick={() => setRoute(it.id)}>
            {React.createElement(I[it.ico], {})}
            <span>{it.label}</span>
            {it.badge ? <span className="badge">{it.badge}</span> : null}
          </button>
        ))}
      </nav>
      <div className="sidebar-foot">
        <div className="avatar">{initials}</div>
        <div className="who">
          <strong>{user?.adventurerName || 'Aventureiro'}</strong>
          <span>{user?.email || ''}</span>
        </div>
        <button className="icon-btn" title="Sair da campanha" onClick={onLogout}><I.logout /></button>
      </div>
    </aside>
  );
};

// ── Topbar ────────────────────────────────────────────────────────────────────
const Topbar = ({ crumb, here, streak, onForge }) => (
  <div className="topbar">
    <div>
      <div className="crumbs"><span>{crumb}</span><span style={{ margin: '0 8px', opacity: .4 }}>›</span><em>{here}</em></div>
    </div>
    <div className="top-actions">
      <div className="streak-pill" title="Streak atual">
        <I.flame className="flame" />
        <span>Streak <strong>{streak}</strong> dias</span>
      </div>
      <button className="btn primary" onClick={onForge}><I.plus /> Forjar missão</button>
    </div>
  </div>
);

// ── Stat card ─────────────────────────────────────────────────────────────────
const Stat = ({ kind, label, value, unit, sub, icoName }) => (
  <div className={`stat ${kind}`}>
    <div className="top">
      <div className="label">{label}</div>
      <div className="ico-bg">{React.createElement(I[icoName], {})}</div>
    </div>
    <div className="v">{value}{unit && <span className="u">{unit}</span>}</div>
    {sub && <div className="sub">{sub}</div>}
  </div>
);

// ── Quest row ─────────────────────────────────────────────────────────────────
const Quest = ({ q, onComplete, onCompleteDay, onDelete, compact }) => {
  const [menuOpen,    setMenuOpen]    = React.useState(false);
  const [confirmOpen, setConfirmOpen] = React.useState(false);

  const cat    = CATEGORIES.find(c => c.id === q.category) || CATEGORIES[0];
  const diff   = DIFFICULTIES.find(d => d.id === q.rarity);
  const CatIco = I[cat.ico];

  const handleDeleteConfirm = () => { setConfirmOpen(false); onDelete(q.id); };

  React.useEffect(() => {
    if (!menuOpen) return;
    const close = () => setMenuOpen(false);
    document.addEventListener('click', close);
    return () => document.removeEventListener('click', close);
  }, [menuOpen]);

  // ── Recurring quest: build week grid ──
  const weekDays    = q.recurrence ? getWeekGrid(q.recurrence, q.weekCompletions) : null;
  const allPastDone = weekDays && weekDays.filter(d => !d.isFuture).length > 0
                   && weekDays.filter(d => !d.isFuture).every(d => d.done);

  const isRegDone  = !q.recurrence && q.status === 'done';
  const questClass = ['quest', q.recurrence ? 'recurring' : '', isRegDone ? 'done' : ''].filter(Boolean).join(' ');

  return (
    <>
      <div className={questClass}>
        {/* Col 1: checkbox for one-time, ↻ badge for recurring */}
        {q.recurrence ? (
          <div className="rec-badge">↻</div>
        ) : (
          <button
            className={`check ${q.status === 'done' ? 'checked' : ''}`}
            onClick={() => q.status === 'open' && onComplete(q.id)}
            aria-label="Concluir"
          >
            <I.check />
          </button>
        )}

        {/* Col 2: meta + week grid */}
        <div className="meta">
          <div className="quest-title">{q.title}</div>
          {!compact && <div className="quest-desc">{q.desc}</div>}
          <div className="quest-tags">
            <span className={`tag ${q.rarity}`}>{diff.label}</span>
            <span className="tag" style={{ color: cat.color, borderColor: `color-mix(in srgb, ${cat.color} 30%, var(--line))` }}>
              <CatIco /> {cat.label}
            </span>
            {q.recurrence && (
              <span className="tag rec-tag">↻ {_recLabel(q.recurrence)}</span>
            )}
            {!q.recurrence && q.deadline && q.deadline !== '—' && q.deadline !== 'Sem prazo' && (
              <span className="tag"><I.calendar /> {q.deadline}</span>
            )}
          </div>

          {/* Week grid */}
          {weekDays && (
            <div className="week-grid">
              {weekDays.map(day => (
                <button
                  key={day.date}
                  className={[
                    'week-day',
                    day.done     ? 'done'    : '',
                    day.isToday  ? 'today'   : '',
                    day.isFuture ? 'future'  : '',
                    day.isPast && !day.done ? 'missed' : '',
                  ].filter(Boolean).join(' ')}
                  onClick={() => !day.done && !day.isFuture && onCompleteDay && onCompleteDay(q.id, day.date)}
                  disabled={day.done || day.isFuture}
                  title={day.date}
                >
                  <span className="wd-label">{day.label}</span>
                  <span className="wd-check">
                    {day.done && <I.check style={{ width: 10, height: 10 }} />}
                  </span>
                </button>
              ))}
              {allPastDone && <span className="week-complete">✦ Semana completa!</span>}
            </div>
          )}
        </div>

        {/* Col 3: reward */}
        <div className="reward">
          <div className="xp"><I.bolt /> +{q.xp}</div>
          <small style={{ fontFamily: 'JetBrains Mono,monospace', fontSize: 9, letterSpacing: '0.18em', color: 'var(--ink-3)', textTransform: 'uppercase', fontWeight: 500 }}>
            {q.recurrence ? 'XP / dia' : 'recompensa'}
          </small>
        </div>

        {/* Col 4: menu */}
        <button
          className="quest menu"
          style={{ position: 'relative', alignSelf: 'center' }}
          onClick={e => { e.stopPropagation(); setMenuOpen(v => !v); }}
        >
          <I.more />
          {menuOpen && (
            <div className="quest-menu-drop" onClick={e => e.stopPropagation()}>
              <button
                className="quest-menu-item danger"
                onClick={() => { setMenuOpen(false); setConfirmOpen(true); }}
              >
                <I.x style={{ width: 13, height: 13 }} /> Excluir missão
              </button>
            </div>
          )}
        </button>
      </div>

      {confirmOpen && (
        <ConfirmModal
          title="Excluir missão?"
          body={`"${q.title}" será removida permanentemente.`}
          onConfirm={handleDeleteConfirm}
          onCancel={() => setConfirmOpen(false)}
        />
      )}
    </>
  );
};

// ── Heatmap ───────────────────────────────────────────────────────────────────
const Heatmap = ({ data }) => (
  <div>
    <div className="heat">
      {data.map((lvl, i) => <div key={i} className={`cell ${lvl ? 'l'+lvl : ''}`} />)}
    </div>
    <div className="heat-legend" style={{ marginTop: 10, justifyContent: 'flex-end' }}>
      <span>Menos</span>
      <span className="swatch" style={{ background: 'var(--bg-3)', border: '1px solid var(--line)' }} />
      <span className="swatch l1" style={{ background: 'color-mix(in srgb, var(--mana) 20%, var(--bg-3))' }} />
      <span className="swatch l2" style={{ background: 'color-mix(in srgb, var(--mana) 40%, var(--bg-3))' }} />
      <span className="swatch l3" style={{ background: 'color-mix(in srgb, var(--mana) 65%, var(--bg-3))' }} />
      <span className="swatch l4" style={{ background: 'var(--mana)' }} />
      <span>Mais</span>
    </div>
  </div>
);

// ── Empty state ───────────────────────────────────────────────────────────────
const Empty = ({ ico = 'scroll', title, body }) => (
  <div className="empty-state">
    <div className="em-ico">{React.createElement(I[ico], { sw: 1 })}</div>
    <h4>{title}</h4>
    <p>{body}</p>
  </div>
);

// ── Badge ─────────────────────────────────────────────────────────────────────
const Badge = ({ b, full, state }) => {
  const unlocked = b.cond(state);
  const p        = Math.min(100, Math.round(b.progress(state) * 100));
  return (
    <div className={`badge ${full ? 'full' : ''} ${unlocked ? 'unlocked' : ''}`}>
      <div className="crest-ico">{b.glyph}</div>
      <div className="b-meta">
        <h5>{b.name}</h5>
        <div className="req">{b.req}</div>
        <div className="pcount">{unlocked ? 'Conquistada' : `${p}% concluído`}</div>
      </div>
      {!full && <div className="b-progress"><div className="fill" style={{ '--p': p+'%' }} /></div>}
    </div>
  );
};

window.ConfirmModal = ConfirmModal;
window.Sidebar      = Sidebar;
window.Topbar       = Topbar;
window.Stat         = Stat;
window.Quest        = Quest;
window.Heatmap      = Heatmap;
window.Empty        = Empty;
window.Badge        = Badge;
