// ViG Command Center — Achievements (profile level, daily streak, badges, leaderboard)
const { useState: useStateACH, useMemo: useMemoACH, useEffect: useEffectACH } = React;

const ACH_LEVELS = [
  [0, 'Recruit'], [200, 'Soldier'], [500, 'Veteran'], [1000, 'Captain'],
  [1800, 'Commander'], [3000, 'Warlord'], [4800, 'General'], [7200, 'Legend'],
];
function achLevel(xp) {
  let lvl = 1, title = ACH_LEVELS[0][1], cur = 0, next = ACH_LEVELS[1][0];
  for (let i = 0; i < ACH_LEVELS.length; i++) {
    if (xp >= ACH_LEVELS[i][0]) { lvl = i + 1; title = ACH_LEVELS[i][1]; cur = ACH_LEVELS[i][0]; next = ACH_LEVELS[i + 1] ? ACH_LEVELS[i + 1][0] : ACH_LEVELS[i][0]; }
  }
  const span = Math.max(1, next - cur);
  return { lvl, title, cur, next, pct: next > cur ? Math.min(100, Math.round((xp - cur) / span * 100)) : 100, max: lvl >= ACH_LEVELS.length };
}

function achStreak() {
  const today = new Date().toISOString().slice(0, 10);
  const s = LS.get('vig2_streak', null);
  if (!s) { const n = { last: today, count: 1, best: 1 }; LS.set('vig2_streak', n); return n; }
  if (s.last === today) return s;
  const yest = new Date(Date.now() - 86400000).toISOString().slice(0, 10);
  const count = s.last === yest ? s.count + 1 : 1;
  const n = { last: today, count, best: Math.max(s.best || 1, count) };
  LS.set('vig2_streak', n); return n;
}

function AchievementsPage({ go }) {
  const V = window.VIG;
  const { isOwned, ownedByName } = (window.useOwn && useOwn()) || { isOwned: () => false, ownedByName: () => false };
  const streak = useMemoACH(() => achStreak(), []);

  const st = useMemoACH(() => {
    const gens = V.generals.filter(g => ['Ground', 'Mounted', 'Ranged', 'Siege'].includes(g.type));
    const owned = gens.filter(isOwned);
    let covComplete = 0;
    try { covComplete = V.covenants.filter(c => window.CALC.covenantStatus(c, ownedByName).complete).length; } catch (e) {}
    const types = ['Ground', 'Mounted', 'Ranged', 'Siege'].map(t => {
      const pool = gens.filter(g => g.type === t); const own = pool.filter(isOwned).length;
      return { t, pct: pool.length ? own / pool.length : 0 };
    });
    const maxType = Math.max(...types.map(t => t.pct));
    const allHalf = types.every(t => t.pct >= 0.5);
    const dragons = Object.keys(LS.get('vig2_dragon_assign', {})).filter(k => LS.get('vig2_dragon_assign', {})[k]).length;
    const usedAI = !!LS.get('vig2_ai_brief', null) || !!LS.get('vig2_wi_pred', null) || (LS.get('vig2_ai_chat', []) || []).length > 0;
    const xp = owned.length * 12 + covComplete * 60 + dragons * 25 + streak.count * 8 + (usedAI ? 40 : 0);
    return { ownedN: owned.length, totalN: gens.length, covComplete, maxType, allHalf, dragons, usedAI, xp };
  }, [isOwned, ownedByName, streak]);

  const lv = achLevel(st.xp);

  const BADGES = [
    { id: 'first', name: 'First Command', desc: 'Own your first general', icon: '🎖️', done: st.ownedN >= 1, prog: Math.min(1, st.ownedN), goal: 1, cur: st.ownedN },
    { id: 'collector', name: 'Collector', desc: 'Own 25 generals', icon: '📇', done: st.ownedN >= 25, prog: st.ownedN / 25, goal: 25, cur: st.ownedN },
    { id: 'builder', name: 'Roster Builder', desc: 'Own 50 generals', icon: '🏗️', done: st.ownedN >= 50, prog: st.ownedN / 50, goal: 50, cur: st.ownedN },
    { id: 'hoarder', name: 'Full Barracks', desc: 'Own 100 generals', icon: '🏛️', done: st.ownedN >= 100, prog: st.ownedN / 100, goal: 100, cur: st.ownedN },
    { id: 'cov1', name: 'Covenant Initiate', desc: 'Complete 1 covenant', icon: '🔗', done: st.covComplete >= 1, prog: Math.min(1, st.covComplete), goal: 1, cur: st.covComplete },
    { id: 'cov10', name: 'Covenant Master', desc: 'Complete 10 covenants', icon: '⛓️', done: st.covComplete >= 10, prog: st.covComplete / 10, goal: 10, cur: st.covComplete },
    { id: 'spec', name: 'Type Specialist', desc: '100% coverage in one troop type', icon: '🎯', done: st.maxType >= 1, prog: st.maxType, goal: 1, cur: Math.round(st.maxType * 100) + '%' },
    { id: 'balanced', name: 'Balanced Force', desc: '50%+ coverage in all four types', icon: '⚖️', done: st.allHalf, prog: st.allHalf ? 1 : 0.5, goal: 1, cur: st.allHalf ? 'Yes' : 'No' },
    { id: 'dragons', name: 'Dragon Tamer', desc: 'Assign a dragon to all 4 marches', icon: '🐉', done: st.dragons >= 4, prog: st.dragons / 4, goal: 4, cur: st.dragons },
    { id: 'ai', name: 'Intel Officer', desc: 'Use an AI feature', icon: '🤖', done: st.usedAI, prog: st.usedAI ? 1 : 0, goal: 1, cur: st.usedAI ? 'Yes' : 'No' },
    { id: 'streak3', name: 'Dedicated', desc: '3-day login streak', icon: '🔥', done: streak.count >= 3, prog: streak.count / 3, goal: 3, cur: streak.count },
    { id: 'streak7', name: 'Relentless', desc: '7-day login streak', icon: '⚡', done: streak.count >= 7, prog: streak.count / 7, goal: 7, cur: streak.count },
  ];
  const unlocked = BADGES.filter(b => b.done).length;

  // live leaderboard from alliance data
  const leaders = useMemoACH(() => {
    try {
      const A = window.ALLIANCE;
      if (!A || !A.alliances) return [];
      return A.alliances.flatMap(a => a.players.map(p => ({ ...p, aid: a.id, accent: a.accent })))
        .sort((x, y) => y.power - x.power).slice(0, 10);
    } catch (e) { return []; }
  }, []);

  return (
    <div className="space-y-4">
      {/* profile level + streak */}
      <div className="grid grid-cols-1 gap-4 lg:grid-cols-3">
        <Card className="relative overflow-hidden p-5 lg:col-span-2" style={{ background: 'linear-gradient(115deg, rgba(255,107,0,.12), transparent 65%)' }}>
          <div className="flex items-center gap-4">
            <div className="flex h-16 w-16 shrink-0 items-center justify-center rounded-2xl text-[26px] font-extrabold text-white" style={{ background: 'linear-gradient(180deg,#ff7d1a,#FF6B00)', boxShadow: '0 12px 30px -10px rgba(255,107,0,.6)' }}>{lv.lvl}</div>
            <div className="min-w-0 flex-1">
              <div className="text-[11px] font-bold uppercase tracking-wider text-brand">Level {lv.lvl} · {lv.title}</div>
              <div className="text-[18px] font-bold text-zinc-900 dark:text-white">{st.xp.toLocaleString()} XP</div>
              <div className="mt-2 h-2 overflow-hidden rounded-full bg-zinc-200 dark:bg-zinc-800"><div className="h-full rounded-full" style={{ width: lv.pct + '%', background: 'linear-gradient(90deg,#ff7d1a,#FF6B00)' }}></div></div>
              <div className="mt-1 text-[11px] text-zinc-500 dark:text-zinc-400">{lv.max ? 'Max rank reached — Legend' : `${(lv.next - st.xp).toLocaleString()} XP to next rank`}</div>
            </div>
          </div>
        </Card>
        <Card className="flex items-center gap-4 p-5">
          <div className="text-[40px]">🔥</div>
          <div>
            <div className="text-[28px] font-bold tabular-nums leading-none text-zinc-900 dark:text-white">{streak.count}<span className="text-[14px] font-medium text-zinc-400"> day{streak.count !== 1 ? 's' : ''}</span></div>
            <div className="text-[12px] font-semibold text-brand">Login streak</div>
            <div className="mt-0.5 text-[11px] text-zinc-400">Best: {streak.best || streak.count} days</div>
          </div>
        </Card>
      </div>

      {/* XP sources */}
      <Card className="flex flex-wrap items-center gap-x-6 gap-y-2 p-3.5 text-[12px]">
        <span className="font-bold uppercase tracking-wide text-zinc-400">XP from</span>
        <span className="text-zinc-600 dark:text-zinc-300"><b className="text-brand">{st.ownedN}</b> generals</span>
        <span className="text-zinc-600 dark:text-zinc-300"><b className="text-brand">{st.covComplete}</b> covenants</span>
        <span className="text-zinc-600 dark:text-zinc-300"><b className="text-brand">{st.dragons}</b> dragons assigned</span>
        <span className="text-zinc-600 dark:text-zinc-300"><b className="text-brand">{streak.count}</b>-day streak</span>
      </Card>

      {/* badges */}
      <Card className="overflow-hidden">
        <div className="flex items-center gap-2 border-b border-zinc-100 px-4 py-3 dark:border-zinc-800">
          <Icon name="trophy" size={16} className="text-brand" />
          <span className="text-[13px] font-bold uppercase tracking-wide text-zinc-900 dark:text-white">Achievements</span>
          <span className="rounded-full bg-brand/15 px-2 py-0.5 text-[11px] font-bold text-brand">{unlocked}/{BADGES.length}</span>
        </div>
        <div className="grid grid-cols-1 gap-px bg-zinc-100 dark:bg-zinc-800 sm:grid-cols-2 lg:grid-cols-3">
          {BADGES.map(b => (
            <div key={b.id} className={`flex items-center gap-3 bg-white p-3.5 dark:bg-zinc-900 ${b.done ? '' : 'opacity-90'}`}>
              <div className={`flex h-11 w-11 shrink-0 items-center justify-center rounded-xl text-[22px] ${b.done ? '' : 'grayscale'}`} style={{ background: b.done ? 'rgba(255,107,0,.14)' : 'var(--ach-locked)' }}>{b.done ? b.icon : '🔒'}</div>
              <div className="min-w-0 flex-1">
                <div className="flex items-center gap-1.5"><span className="truncate text-[13px] font-bold text-zinc-900 dark:text-white">{b.name}</span>{b.done && <Icon name="check" size={13} className="shrink-0 text-emerald-500" stroke={3} />}</div>
                <div className="truncate text-[11.5px] text-zinc-500 dark:text-zinc-400">{b.desc}</div>
                {!b.done && b.goal > 1 && typeof b.cur === 'number' && (
                  <div className="mt-1.5 flex items-center gap-2">
                    <div className="h-1 flex-1 overflow-hidden rounded-full bg-zinc-100 dark:bg-zinc-800"><div className="h-full rounded-full bg-brand" style={{ width: Math.min(100, b.prog * 100) + '%' }}></div></div>
                    <span className="text-[10px] tabular-nums text-zinc-400">{b.cur}/{b.goal}</span>
                  </div>
                )}
              </div>
            </div>
          ))}
        </div>
      </Card>

      {/* leaderboard */}
      {leaders.length > 0 && (
        <Card className="overflow-hidden">
          <div className="flex items-center gap-2 border-b border-zinc-100 px-4 py-3 dark:border-zinc-800">
            <Icon name="star" size={16} className="text-brand" />
            <span className="text-[13px] font-bold uppercase tracking-wide text-zinc-900 dark:text-white">Power leaderboard</span>
            <span className="text-[11px] text-zinc-400">top tracked commanders, all alliances</span>
            <button onClick={() => go('warroom')} className="ml-auto text-[12px] font-semibold text-brand hover:underline">War Room →</button>
          </div>
          <div className="divide-y divide-zinc-50 dark:divide-zinc-800/60">
            {leaders.map((p, i) => (
              <div key={p.aid + p.name} className="flex items-center gap-3 px-4 py-2.5">
                <span className={`w-6 text-center text-[13px] font-bold tabular-nums ${i < 3 ? 'text-brand' : 'text-zinc-400'}`}>{i + 1}</span>
                <span className="flex h-7 w-7 shrink-0 items-center justify-center rounded-full text-[11px] font-bold text-white" style={{ background: p.accent }}>{p.aid}</span>
                <span className="min-w-0 flex-1 truncate text-[13px] font-medium text-zinc-800 dark:text-zinc-100">{p.name}</span>
                <span className="text-[11.5px] text-zinc-400">{p.keep}</span>
                <span className="w-16 text-right text-[13px] font-bold tabular-nums text-zinc-900 dark:text-white">{(+p.power).toFixed(0)}M</span>
              </div>
            ))}
          </div>
        </Card>
      )}

      <style>{`:root{--ach-locked:#f1f1f4;} html.dark{--ach-locked:#161d30;}`}</style>
      <p className="px-1 text-[11.5px] text-zinc-400">XP, level and badges are computed live from your real progress — own generals, complete covenants, assign dragons and visit daily to rank up. Everything saves on this device.</p>
    </div>
  );
}
window.AchievementsPage = AchievementsPage;
