/* ============================================================
   斗地主 · 弹窗面板：商城 / 任务签到 / 排行榜 / 设置 / 个人中心
   ============================================================ */
const { LEADERBOARD, SHOP_COINS, SHOP_ITEMS, TASKS, SIGN_REWARDS, FIELDS } = window.DATA;
const fmtN = window.fmt;

/* ---------------- 我的钱包（USDT 托管充提：转账到平台收款地址，服务端扫链入账） ---------------- */
function WalletPanel({ api, onClose, onToast, onRefresh }) {
  const { useState, useEffect } = React;
  const [data, setData] = useState(null);
  const [busy, setBusy] = useState('');
  const [addr, setAddr] = useState('');
  const [editing, setEditing] = useState(false);
  const [wdCoins, setWdCoins] = useState('');
  const toast = (m) => onToast && onToast(m);

  const load = async () => { const r = await api('/api/wallet'); if (r && r.ok) { setData(r); if (r.address) setAddr(r.address); } };
  useEffect(() => { load(); }, []);

  const dep = data && data.deposit;
  const rate = dep ? dep.coinsPerToken : 100;

  async function bind() {
    const a = addr.trim();
    if (!/^0x[0-9a-fA-F]{40}$/.test(a)) { toast('地址格式不对'); return; }
    setBusy('bind'); const r = await api('/api/wallet/bind', { method: 'POST', body: { address: a } }); setBusy('');
    if (r && r.ok) { toast('地址已绑定' + (r.crediteddeposits ? `，补入 ${r.crediteddeposits} 笔充值` : '')); setEditing(false); load(); onRefresh && onRefresh(); }
    else toast('绑定失败：' + (r && r.err === 'ADDRESS_TAKEN' ? '该地址已被其他账号绑定' : (r && r.err) || ''));
  }
  const copyAddr = (a) => {
    (navigator.clipboard ? navigator.clipboard.writeText(a) : Promise.reject())
      .then(() => toast('已复制地址'))
      .catch(() => toast(a));   // 剪贴板不可用时把地址打进提示条，至少能手动选中复制
  };
  async function withdraw() {
    const coins = Math.trunc(Number(wdCoins));
    if (!coins || coins <= 0) { toast('输入提现金币数'); return; }
    setBusy('withdraw');
    const r = await api('/api/wallet/withdraw', { method: 'POST', body: { coins } });
    setBusy('');
    if (!r || r.err) { toast('提现申请：' + ((r && r.err) || '失败') + (r && r.min ? `（最低 ${r.min}）` : '')); return; }
    toast(r.status === 'approved' ? '已提交，即将自动到账' : '已提交，等待人工审核');
    setWdCoins(''); load(); onRefresh && onRefresh();
  }

  if (!data) return <Modal title="我的钱包" icon="🔗" onClose={onClose}><div className="wallet-loading">加载中…</div></Modal>;
  if (!data.enabled) return <Modal title="我的钱包" icon="🔗" onClose={onClose}><div className="wallet-off">USDT 充提暂未开启</div></Modal>;

  const short = (a) => a ? a.slice(0, 6) + '…' + a.slice(-4) : '';
  const STATUS_LABEL = { pending: '待审核', approved: '处理中', sent: '已广播', confirmed: '已到账', rejected: '已拒绝' };
  return (
    <Modal title="我的钱包 · USDT 充提" icon="🔗" onClose={onClose} width={480}>
      <div className="wallet">
        <div className="w-sec">
          <div className="w-label">收款/充值地址（用于识别你的充值 + 提现到账）</div>
          {data.address && !editing
            ? <div className="w-addr bound"><span>✓ 已绑定 {short(data.address)}</span><button className="w-link" onClick={() => { setAddr(''); setEditing(true); }}>换绑</button></div>
            : <div className="w-bind">
                <input className="w-input" placeholder="0x… 你的钱包地址" value={addr} onChange={e => setAddr(e.target.value)} />
                <button className="btn primary sm" disabled={busy === 'bind'} onClick={bind}>{data.address ? '换绑' : '绑定'}</button>
              </div>}
          {data.address && editing && <button className="w-link" onClick={() => { setEditing(false); setAddr(data.address); }}>取消换绑</button>}
        </div>

        <div className="w-sec">
          <div className="w-label">充值　<span className="w-hint">1 USDT = {rate} 金币</span></div>
          {data.address ? (
            <React.Fragment>
              <div className="w-addr bound"><span>{dep.depositAddress}</span><button className="w-link" onClick={() => copyAddr(dep.depositAddress)}>复制地址</button></div>
              <div className="w-calc">从你绑定的地址 {short(data.address)} 转 USDT 到上面这个地址，系统会自动识别到账（约需数个区块确认，稍后刷新可见）</div>
            </React.Fragment>
          ) : <div className="w-calc">请先绑定你的钱包地址，充值才能被自动识别归属到你的账号</div>}
        </div>

        <div className="w-sec">
          <div className="w-label">提现　<span className="w-hint">{rate} 金币 = 1 USDT，最低 {dep ? dep.minWithdrawCoins ?? '' : ''} 金币</span></div>
          {data.address ? (
            <div className="w-row">
              <input className="w-input" type="number" min="1" placeholder="提现金币数" value={wdCoins} onChange={e => setWdCoins(e.target.value)} />
              <button className="btn sm" disabled={busy === 'withdraw'} onClick={withdraw}>{busy === 'withdraw' ? '申请中…' : '申请提现'}</button>
            </div>
          ) : <div className="w-calc">请先绑定收款地址</div>}
          {wdCoins > 0 && <div className="w-calc">≈ 得 {(Math.trunc(Number(wdCoins)) / rate).toFixed(2)} USDT</div>}
        </div>

        {data.withdrawals && data.withdrawals.length > 0 && <div className="w-sec">
          <div className="w-label">提现记录</div>
          {data.withdrawals.map(w => (
            <div className="w-item" key={w.id}>
              <span className="w-item-l">{w.coins.toLocaleString()} 金币</span>
              <span className={'w-badge ' + w.status}>{STATUS_LABEL[w.status] || w.status}</span>
            </div>
          ))}
        </div>}

        {data.deposits && data.deposits.length > 0 && <div className="w-sec">
          <div className="w-label">充值记录</div>
          {data.deposits.slice(0, 5).map((d, i) => (
            <div className="w-item" key={i}>
              <span className="w-item-l">+{d.coins.toLocaleString()} 金币</span>
              <span className={'w-badge ' + (d.credited_at ? 'redeemed' : 'pending')}>{d.credited_at ? '已入账' : '待确认'}</span>
            </div>
          ))}
        </div>}
      </div>
    </Modal>
  );
}

function Modal({ title, icon, onClose, children, width }) {
  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" style={width ? { width } : null} onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <h3>{icon && <span>{icon}</span>}{title}</h3>
          <div className="x" onClick={onClose}>✕</div>
        </div>
        <div className="modal-body">{children}</div>
      </div>
    </div>
  );
}

/* ---------------- 商城（金币充值走 USDT 托管：转账到平台收款地址，见"我的钱包"面板） ---------------- */
function ShopPanel({ profile, usdt, onClose, onEquip, onToast, onOpenWallet }) {
  const { useState } = React;
  const [tab, setTab] = useState('coins');
  const owned = profile.owned || [];
  const equipped = profile.equipped || {};
  const rate = (usdt && usdt.coinsPerToken) || 100;
  return (
    <Modal title="商城" icon="🛒" onClose={onClose}>
      <div className="tabs">
        <div className={`tab ${tab === 'coins' ? 'on' : ''}`} onClick={() => setTab('coins')}>金币充值</div>
        <div className={`tab ${tab === 'items' ? 'on' : ''}`} onClick={() => setTab('items')}>道具装扮</div>
      </div>
      {tab === 'coins' ? (
        usdt && usdt.enabled ? (
          <React.Fragment>
            <div className="coin-grid">
              {SHOP_COINS.map(p => (
                <div className="pack" key={p.id} onClick={() => { onClose(); onOpenWallet && onOpenWallet(); }}>
                  {p.hot && <span className="hot-tag">超值</span>}
                  <div className="pic">🪙</div>
                  <div className="amt">{fmtN(Math.trunc(p.usdt * rate))}</div>
                  <div className="buy">{p.usdt} USDT</div>
                </div>
              ))}
            </div>
            <div className="w-calc" style={{ textAlign: 'center', margin: '10px 0' }}>点任意档位 → 打开"我的钱包"转账到平台收款地址即可到账</div>
          </React.Fragment>
        ) : <div className="wallet-off">充值暂未开启</div>
      ) : (
        <div className="item-grid">
          {SHOP_ITEMS.map(it => {
            const isOwned = owned.includes(it.id);
            const isOn = it.slot && equipped[it.slot] && isOwned;
            return (
              <div className={`pack item ${isOn ? 'equipped' : ''}`} key={it.id} onClick={async () => {
                const ok = await onEquip(it);
                if (!ok) { onToast('钻石不足'); return; }
                window.SFX && window.SFX.play('coin');
                onToast(it.slot ? `已装备「${it.name}」` : `已获得「${it.name}」`);
              }}>
                <div className="pic">{it.icon}</div>
                <div className="it-main">
                  <div className="it-name">{it.name}{isOn && <span className="eq-badge">已装备</span>}</div>
                  <div className="it-desc">{it.desc}</div>
                </div>
                {isOwned ? <div className="it-cost owned">{it.slot ? '装备' : '已拥有'}</div> : <div className="it-cost">{it.cost}</div>}
              </div>
            );
          })}
        </div>
      )}
    </Modal>
  );
}

/* ---------------- 任务 + 签到 ---------------- */
function TasksPanel({ profile, claimed = [], tasks, onClose, onSign, onClaim, onToast }) {
  const TASK_LIST = tasks || TASKS;   // 服务端未返回时用静态目录兜底。
  return (
    <Modal title="任务 · 签到" icon="🎁" onClose={onClose}>
      <div className="ach-title">每 日 签 到</div>
      <div className="sign-row">
        {SIGN_REWARDS.map((rw, i) => {
          const day = i + 1;
          const done = day <= profile.signedDays;
          const today = day === profile.signedDays + 1;
          return (
            <div key={i} className={`sign-day ${done ? 'done' : ''} ${today && !profile.signedToday ? 'today' : ''}`}>
              <div className="d">第{day}天</div>
              <div className="gift">{done ? '✅' : (rw.includes('钻') ? '💎' : '🪙')}</div>
              <div className="rw">{rw}</div>
            </div>
          );
        })}
      </div>
      <div className="sign-cta">
        {profile.signedToday
          ? <button className="btn ghost" disabled>今日已签到</button>
          : <button className="btn primary" onClick={() => { onSign(); onToast(`签到成功 +${SIGN_REWARDS[profile.signedDays] || '6,000'}`); }}>立即签到</button>}
      </div>

      <div className="ach-title">每 日 任 务</div>
      <div className="task-list">
        {TASK_LIST.map(t => (
          <div className="task" key={t.id}>
            <div className="t-main">
              <div className="t-name">{t.name}</div>
              <div className="t-desc">{t.desc}</div>
              <div className="t-bar"><i style={{ width: `${Math.min(100, (t.progress / t.total) * 100)}%` }} /></div>
              <div className="t-prog">{t.progress} / {t.total}</div>
            </div>
            <div className="t-reward">
              <div className="t-rw">{t.reward}</div>
              {claimed.includes(t.id)
                ? <button className="claim-btn done">已领取</button>
                : t.progress >= t.total
                  ? <button className="claim-btn go" onClick={() => { onClaim(t); onToast(`领取成功 ${t.reward}`); }}>领取</button>
                  : <button className="claim-btn wait">{t.progress}/{t.total}</button>}
            </div>
          </div>
        ))}
      </div>
    </Modal>
  );
}

/* ---------------- 排行榜 ---------------- */
function LeaderboardPanel({ profile, entries, myRank, onClose }) {
  const medals = ['🥇', '🥈', '🥉'];
  const list = entries || LEADERBOARD;   // 服务端未返回时用静态榜单兜底。
  const me = { rank: myRank || 26, name: profile.name, face: profile.avatar, coins: profile.coins, wins: profile.wins, isMe: true };
  return (
    <Modal title="财富排行榜" icon="🏆" onClose={onClose}>
      <div className="rank-list">
        {list.map(r => (
          <div key={r.rank} className={`rank-row ${r.rank <= 3 ? 'top' : ''}`}>
            {r.rank <= 3 ? <div className="rank-medal">{medals[r.rank - 1]}</div> : <div className="rank-no">{r.rank}</div>}
            <div className="rank-av">{r.face}</div>
            <div className="rank-name">{r.name}<div className="rank-wins">{r.wins.toLocaleString()} 胜</div></div>
            <div className="rank-coins">{fmtN(r.coins)}</div>
          </div>
        ))}
        <div className="rank-row" style={{ marginTop: 6, borderColor: 'var(--gold-deep)' }}>
          <div className="rank-no">{me.rank}</div>
          <div className="rank-av">{me.face}</div>
          <div className="rank-name">{me.name} <span style={{ fontSize: 11, color: 'var(--gold-soft)' }}>(我)</span><div className="rank-wins">{me.wins.toLocaleString()} 胜</div></div>
          <div className="rank-coins">{fmtN(me.coins)}</div>
        </div>
      </div>
    </Modal>
  );
}

/* ---------------- 设置 ---------------- */
function SettingsPanel({ settings, onToggle, onClose, onLogout }) {
  const rows = [
    { k: 'music', label: '背景音乐', sub: '大厅与对局背景音乐' },
    { k: 'sfx', label: '音效', sub: '出牌、提示等音效' },
    { k: 'autoHint', label: '出牌提示', sub: '轮到你时高亮可出的牌' },
    { k: 'shake', label: '炸弹震动', sub: '出炸弹时屏幕震动反馈' },
  ];
  return (
    <Modal title="设置" icon="⚙" onClose={onClose} width={460}>
      {rows.map(r => (
        <div className="set-row" key={r.k}>
          <div><div className="label">{r.label}</div><div className="sub">{r.sub}</div></div>
          <div className={`toggle ${settings[r.k] ? 'on' : ''}`} onClick={() => onToggle(r.k)}><i /></div>
        </div>
      ))}
      <div style={{ marginTop: 22, textAlign: 'center' }}>
        <button className="btn danger" onClick={onLogout}>退出登录</button>
      </div>
    </Modal>
  );
}

/* ---------------- 个人中心 ---------------- */
function ProfilePanel({ profile, api, onClose }) {
  const { useState, useEffect } = React;
  const [games, setGames] = useState(null);
  useEffect(() => { (async () => {
    try { const r = await api('/api/games?limit=30'); if (r && r.ok) setGames(r.games); } catch (e) {}
  })(); }, []);
  const fieldName = (id) => { const f = FIELDS.find(x => x.id === id); return f ? f.name : (id || '未知场次'); };
  const fmtTime = (ts) => {
    const d = new Date(ts);
    const p = (n) => String(n).padStart(2, '0');
    return `${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}`;
  };
  const winRate = profile.plays ? Math.round((profile.wins / profile.plays) * 100) : 0;
  const achievements = [
    { icon: '🏅', name: '首胜', got: true }, { icon: '🔥', name: '三连胜', got: profile.winStreak >= 3 },
    { icon: '💣', name: '炸弹王', got: true }, { icon: '👑', name: '常胜地主', got: profile.wins >= 100 },
    { icon: '💎', name: '富甲一方', got: profile.coins >= 1000000 },
  ];
  return (
    <Modal title="个人中心" icon="👤" onClose={onClose}>
      <div className="profile-top">
        <div className="profile-av">{profile.avatar}</div>
        <div className="profile-meta">
          <h3>{profile.name} <span className="pc-lv">Lv.{profile.level}</span></h3>
          <div className="uid">
            当前 {profile.winStreak} 连胜 · 信誉度{' '}
            <b className={`credit ${(profile.credit ?? 100) >= 90 ? 'good' : (profile.credit ?? 100) >= 70 ? 'mid' : 'bad'}`}>{profile.credit ?? 100}</b>
            {profile.escapes > 0 && <span className="esc"> · 逃跑 {profile.escapes} 次</span>}
          </div>
        </div>
      </div>
      <div className="stat-grid">
        <div className="stat-box"><div className="ico">🎮</div><div className="num">{profile.plays}</div><div className="lbl">总场次</div></div>
        <div className="stat-box"><div className="ico">🏆</div><div className="num">{profile.wins}</div><div className="lbl">胜场</div></div>
        <div className="stat-box"><div className="ico">📈</div><div className="num">{winRate}%</div><div className="lbl">胜率</div></div>
        <div className="stat-box"><div className="ico">🪙</div><div className="num">{fmtN(profile.coins)}</div><div className="lbl">金币</div></div>
      </div>
      <div className="ach-title">成 就 徽 章</div>
      <div className="ach-row">
        {achievements.map((a, i) => (
          <div className="ach" key={i}>
            <div className={`badge ${a.got ? '' : 'lock'}`}>{a.icon}</div>
            <div className="an">{a.name}</div>
          </div>
        ))}
      </div>
      <div className="ach-title">打 牌 记 录</div>
      {games == null
        ? <div className="w-calc">加载中…</div>
        : games.length === 0
          ? <div className="w-calc">还没有对局记录，去打一局吧</div>
          : <div className="w-hist">
              {games.map((g, i) => (
                <div className="w-hist-row" key={g.room_id + i}>
                  <span className={g.delta > 0 ? 'in' : 'out'}>{g.delta > 0 ? '赢' : '输'}</span>
                  <span>{fieldName(g.field_id)}{g.landlord_seat != null && (g.winner_side ? (g.winner_side === 'landlord' ? '·地主胜' : '·农民胜') : '')}　{fmtTime(g.created_at)}</span>
                  <span className={g.delta > 0 ? 'in' : 'out'}>{g.delta > 0 ? '+' : ''}{fmtN(g.delta)}</span>
                </div>
              ))}
            </div>}
    </Modal>
  );
}

Object.assign(window, { Modal, ShopPanel, TasksPanel, LeaderboardPanel, SettingsPanel, ProfilePanel, RankPanel, WheelPanel });

/* ---------------- 段位 ---------------- */
function RankPanel({ profile, onClose }) {
  const { RANK_TIERS, rankFromStars } = window.DATA;
  const info = rankFromStars(profile.stars || 0);
  const stars = info.starInTier, span = info.tierSpan;
  const curIdx = RANK_TIERS.indexOf(info.rank);
  return (
    <Modal title="段位" icon="🏅" onClose={onClose} width={500}>
      <div className="rank-hero">
        <div className="rank-emblem">{info.rank.icon}</div>
        <div className="rank-name-big">{info.rank.name}</div>
        <div className="rank-stars-big">
          {Array.from({ length: span }).map((_, i) => <span key={i} className={i < stars ? '' : 'empty'}>★</span>)}
        </div>
        <div className="rank-progress">
          <div className="pbar"><i style={{ width: `${span ? (stars / span) * 100 : 100}%` }} /></div>
          <div className="ptxt">{info.next ? `再赢 ${span - stars} 颗星升至「${info.next.name}」` : '已达最高段位 · 王者无敌'}</div>
        </div>
      </div>
      <div className="rank-ladder">
        {RANK_TIERS.map((r, i) => (
          <div key={r.id} className={`ladder-row ${i === curIdx ? 'cur' : ''} ${i < curIdx ? 'passed' : ''}`}>
            <div className="li">{r.icon}</div>
            <div className="ln">{r.name}</div>
            {i === curIdx ? <div className="lcur">当前段位</div> : <div className="lr">{r.minStar} ★ 解锁</div>}
          </div>
        ))}
      </div>
    </Modal>
  );
}

/* ---------------- 每日转盘 ---------------- */
function WheelPanel({ profile, onClose, onSpin, onToast }) {
  const { useState } = React;
  const { WHEEL_PRIZES } = window.DATA;
  const today = new Date().toDateString();
  const usedToday = profile.wheelDate === today;
  const [angle, setAngle] = useState(0);
  const [spinning, setSpinning] = useState(false);
  const [done, setDone] = useState(usedToday);
  const seg = 360 / WHEEL_PRIZES.length;

  // 由父级决定中奖序号: 当前联机版来自服务端权威抽奖。
  // onSpin() 返回奖品索引(Promise 或同步值); 返回 null/<0 表示今日已抽或失败。
  const spin = async () => {
    if (spinning || done) return;
    setSpinning(true);
    if (window.SFX) window.SFX.play('tick');
    let idx;
    try { idx = await onSpin(); }
    catch { setSpinning(false); onToast('抽奖失败，请稍后再试'); return; }
    if (idx == null || idx < 0) { setSpinning(false); setDone(true); onToast('今日已抽奖，明天再来~'); return; }
    const target = 360 * 5 + (360 - idx * seg - seg / 2);
    setAngle(target);
    setTimeout(() => {
      setSpinning(false); setDone(true);
      const p = WHEEL_PRIZES[idx];
      if (window.SFX) window.SFX.play(p.type === 'none' ? 'pass' : 'coin');
      onToast(p.type === 'none' ? '谢谢参与，明天再来~' : `恭喜获得 ${p.label}!`);
    }, 4300);
  };
  const COLORS = ['#f4d488', '#e2a24e'];   // 双色交替

  return (
    <Modal title="幸运转盘" icon="🎡" onClose={onClose} width={460}>
      <div className="wheel-wrap">
        <div className="wheel-stage">
          <div className="wheel-pointer" />
          <div className="wheel-disc" style={{ transform: `rotate(${angle}deg)`, background: `conic-gradient(${WHEEL_PRIZES.map((p, i) => `${COLORS[i % COLORS.length]} ${i * seg}deg ${(i + 1) * seg}deg`).join(',')})` }}>
            {WHEEL_PRIZES.map((p, i) => {
              const mid = i * seg + seg / 2;                 // 扇区中线角(自顶部顺时针)
              const rad = mid * Math.PI / 180, R = 32;        // R = 距圆心的百分比
              const x = 50 + R * Math.sin(rad), y = 50 - R * Math.cos(rad);
              const short = p.type === 'coin' ? fmtN(p.amount) : p.type === 'dia' ? `${p.amount} 钻` : '谢谢';
              return (
                <div key={i} className="wheel-label"
                  style={{ left: `${x}%`, top: `${y}%`, transform: `translate(-50%,-50%) rotate(${-angle}deg)` }}>
                  <span className="wl-ic">{p.icon}</span>
                  <span className="wl-tx">{short}</span>
                </div>
              );
            })}
          </div>
          <div className={`wheel-hub ${spinning ? 'spinning' : ''}`} onClick={spin}>{done ? '已抽' : '抽奖'}</div>
        </div>
        <div className="wheel-note">{done ? '今日已抽奖，明天再来~' : '每日一次免费抽奖机会'}</div>
      </div>
    </Modal>
  );
}
