// ═══════════════ TIERLIST PAGE (LIVE + drag&drop + export + share) ═══════════════
const TierlistPage = () => {
  const { data: teams, loading } = useApi('/public/teams-full', []);
  const { data: players } = useApi('/public/players-full', []);
  const [mode, setMode] = React.useState('teams');
  const [view, setView] = React.useState('mine'); // 'mine' or 'myg'
  const [pseudo, setPseudo] = React.useState(() => localStorage.getItem('czf_pseudo') || '');
  const [adminToken, setAdminToken] = React.useState(() => sessionStorage.getItem('czf_admin_token'));
  const [board, setBoard] = React.useState(() => {
    try { const saved = localStorage.getItem('czf_tierlist_local'); return saved ? JSON.parse(saved) : null; } catch { return null; }
  });
  const [mygBoard, setMygBoard] = React.useState(null);
  const [dragId, setDragId] = React.useState(null);
  const [shareStatus, setShareStatus] = React.useState('');

  const isAdmin = !!adminToken;

  const items = mode === 'teams'
    ? (teams || []).map(t => ({ id: t.team_name, name: t.team_name, division: t.division, tag: (t.team_name || '?').split(/\s+/).map(s => s[0]).join('').toUpperCase().slice(0,3) }))
    : (players || []).map(p => ({ id: p.discord_tag, name: p.discord_nick || p.discord_tag?.split('#')[0] || '?', division: p.division, tag: (p.discord_nick || p.discord_tag?.split('#')[0] || '?').slice(0, 2).toUpperCase() }));

  // Fetch MYG tierlist when view = 'myg'
  React.useEffect(() => {
    if (view !== 'myg') return;
    if (!window.CZF || !CZF.USE_LIVE_DATA) return;
    fetch(`${CZF.API_BASE}/public/tierlist-myg?mode=${mode}`)
      .then(r => r.ok ? r.json() : null)
      .then(setMygBoard)
      .catch(() => setMygBoard(null));
  }, [view, mode]);

  React.useEffect(() => {
    if (!board || board.mode !== mode) {
      setBoard({ mode, S: [], A: [], B: [], C: [], D: [], F: [], pool: items.map(it => it.id) });
    } else {
      const placed = new Set();
      ['S','A','B','C','D','F','pool'].forEach(k => (board[k] || []).forEach(id => placed.add(id)));
      const missing = items.map(i => i.id).filter(id => !placed.has(id));
      if (missing.length) setBoard({ ...board, pool: [...(board.pool || []), ...missing] });
    }
  }, [mode, items.length]);

  const activeBoard = view === 'myg' ? (mygBoard || { mode, S: [], A: [], B: [], C: [], D: [], F: [], pool: [] }) : board;
  const canEdit = view === 'mine' || (view === 'myg' && isAdmin);

  const save = async () => {
    if (!activeBoard) return;
    if (view === 'mine') {
      localStorage.setItem('czf_tierlist_local', JSON.stringify(activeBoard));
      if (pseudo.trim() && window.CZF && CZF.USE_LIVE_DATA) {
        postApi('/save-tierlist', { pseudo: pseudo.trim(), mode, state: activeBoard }).catch(() => {});
        localStorage.setItem('czf_pseudo', pseudo.trim());
      }
    } else if (view === 'myg' && isAdmin) {
      await postApi('/admin-api/tierlist-myg', { mode, state: activeBoard }, adminToken).catch(() => {});
    }
  };
  const reset = () => {
    const empty = { mode, S: [], A: [], B: [], C: [], D: [], F: [], pool: items.map(it => it.id) };
    if (view === 'mine') setBoard(empty);
    else setMygBoard(empty);
  };

  const moveItem = (id, toTier) => {
    if (!canEdit || !activeBoard) return;
    const next = { mode: activeBoard.mode };
    ['S','A','B','C','D','F','pool'].forEach(k => { next[k] = (activeBoard[k] || []).filter(x => x !== id); });
    (next[toTier] = next[toTier] || []).push(id);
    if (view === 'mine') setBoard(next);
    else setMygBoard(next);
  };

  const lookup = (id) => items.find(it => it.id === id);

  // Export as PNG
  const exportPng = async () => {
    if (!window.html2canvas) {
      await new Promise((res, rej) => {
        const s = document.createElement('script');
        s.src = 'https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js';
        s.onload = res; s.onerror = rej;
        document.head.appendChild(s);
      });
    }
    const el = document.getElementById('tierlist-board');
    if (!el) return;
    const canvas = await window.html2canvas(el, { backgroundColor: '#0E0A06', scale: 2 });
    const link = document.createElement('a');
    link.download = `czf-tierlist-${mode}-${pseudo || 'anonyme'}.png`;
    link.href = canvas.toDataURL('image/png');
    link.click();
  };

  // Share to Discord (uploads PNG to worker → bot posts in channel 1506283336014762004)
  const shareDiscord = async () => {
    setShareStatus('exporting');
    try {
      if (!window.html2canvas) {
        await new Promise((res, rej) => {
          const s = document.createElement('script');
          s.src = 'https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js';
          s.onload = res; s.onerror = rej;
          document.head.appendChild(s);
        });
      }
      const el = document.getElementById('tierlist-board');
      const canvas = await window.html2canvas(el, { backgroundColor: '#0E0A06', scale: 2 });
      const dataUrl = canvas.toDataURL('image/png');
      setShareStatus('sending');
      await postApi('/share-tierlist', { pseudo: pseudo.trim() || 'Anonyme', mode, image_data_url: dataUrl });
      setShareStatus('done');
      setTimeout(() => setShareStatus(''), 2500);
    } catch (e) { setShareStatus('error'); setTimeout(() => setShareStatus(''), 2500); }
  };

  const tiers = [
    { l: 'S', c: '#E63946' }, { l: 'A', c: '#D4A84B' },
    { l: 'B', c: '#4eb6a6' }, { l: 'C', c: '#8fb9e8' },
    { l: 'D', c: '#8B79E8' }, { l: 'F', c: '#7E7460' },
  ];

  return (
    <div className="page-frame grain" data-screen-label="Tierlist">
      <CZFHeader active="tierlist" />
      <main style={{ padding: '2.5rem 2.5rem 3rem', position: 'relative' }}>
        <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', marginBottom: '1.5rem' }}>
          <div>
            <div className="eyebrow" style={{ marginBottom: '.6rem' }}>Glisse-dépose les {mode === 'teams' ? 'équipes' : 'joueurs'}</div>
            <h1 className="display" style={{ fontSize: '3.2rem' }}>TIERLIST</h1>
          </div>
          <div style={{ display: 'flex', gap: '.4rem', alignItems: 'center', flexWrap: 'wrap' }}>
            <button className={`filter-btn ${mode === 'teams' ? 'on' : ''}`} onClick={() => setMode('teams')}>Équipes <span style={{ opacity: .55, marginLeft: 4 }}>· {(teams || []).length}</span></button>
            <button className={`filter-btn ${mode === 'players' ? 'on' : ''}`} onClick={() => setMode('players')}>Joueurs <span style={{ opacity: .55, marginLeft: 4 }}>· {(players || []).length}</span></button>
            <span style={{ width: 1, height: 16, background: 'var(--border-2)', margin: '0 .25rem' }} />
            <button className={`filter-btn ${view === 'mine' ? 'on' : ''}`} onClick={() => setView('mine')}>La mienne</button>
            <button className={`filter-btn ${view === 'myg' ? 'on' : ''}`} onClick={() => setView('myg')}>Tierlist MYG{isAdmin && view === 'myg' ? ' ✎' : ''}</button>
          </div>
        </div>

        <div style={{
          display: 'flex', gap: '.5rem', alignItems: 'center', flexWrap: 'wrap',
          padding: '.65rem .85rem', background: 'var(--char)',
          border: '1px solid var(--border)', borderRadius: 3, marginBottom: '1.25rem',
        }}>
          {view === 'mine' && (
            <input value={pseudo} onChange={e => setPseudo(e.target.value)} placeholder="Ton pseudo Discord…" style={{
              fontFamily: 'var(--fc)', fontSize: '.82rem',
              background: 'rgba(0,0,0,.3)', border: '1px solid var(--border)',
              color: 'var(--bone)', padding: '.35rem .85rem',
              borderRadius: 2, outline: 'none', width: 220,
            }} />
          )}
          {view === 'myg' && !isAdmin && (
            <span style={{ fontFamily: 'var(--fc)', fontSize: '.75rem', color: 'var(--muted)', letterSpacing: '.04em' }}>
              ⓘ La tierlist MYG est éditable uniquement par les admins
            </span>
          )}
          {canEdit && <button onClick={save} className="btn btn-ghost" style={{ padding: '.4rem .85rem' }}>Sauvegarder</button>}
          {canEdit && <button onClick={reset} className="filter-btn">Reset</button>}
          <div style={{ marginLeft: 'auto', display: 'flex', gap: '.4rem', alignItems: 'center' }}>
            {shareStatus && (
              <span style={{ fontFamily: 'var(--fc)', fontSize: '.7rem',
                color: shareStatus === 'done' ? 'var(--ok)' : shareStatus === 'error' ? 'var(--red)' : 'var(--muted)',
                letterSpacing: '.06em',
              }}>{shareStatus === 'exporting' ? 'Génération…' : shareStatus === 'sending' ? 'Envoi…' : shareStatus === 'done' ? '✓ Partagé' : '✗ Erreur'}</span>
            )}
            <button onClick={exportPng} className="btn btn-ghost" style={{ padding: '.4rem .85rem' }}>⬇ Exporter PNG</button>
            <button onClick={shareDiscord} className="btn btn-gold" style={{ padding: '.4rem .85rem' }}>
              <Icon.Discord style={{ color: '#5865F2' }} /> Partager Discord
            </button>
          </div>
        </div>

        {loading
          ? <Loading />
          : items.length === 0
            ? <Empty title={`AUCUN${mode === 'teams' ? 'E ÉQUIPE' : ' JOUEUR'}`} sub="Tout sera rempli quand des données seront disponibles." />
            : (
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 270px', gap: '1rem' }}>
                <div id="tierlist-board" style={{ background: 'var(--char)', border: '1px solid var(--border)', borderRadius: 4, overflow: 'hidden' }}>
                  {tiers.map(t => (
                    <DropZone key={t.l} tier={t.l} canEdit={canEdit} onDrop={(id) => moveItem(id, t.l)} dragId={dragId}>
                      <div style={{ display: 'flex', minHeight: 86, borderBottom: '1px solid var(--border)' }}>
                        <div style={{
                          width: 90, flexShrink: 0,
                          background: t.c, color: '#0E0A06',
                          display: 'flex', alignItems: 'center', justifyContent: 'center',
                          fontFamily: 'var(--fd)', fontSize: '3rem', letterSpacing: '.04em',
                        }}>{t.l}</div>
                        <div style={{
                          flex: 1, padding: '.7rem .85rem',
                          display: 'flex', flexWrap: 'wrap', gap: '.5rem', alignItems: 'center',
                          background: `${t.c}06`,
                        }}>
                          {(activeBoard?.[t.l] || []).length === 0 && (
                            <div style={{ fontFamily: 'var(--fc)', fontSize: '.7rem', color: 'var(--muted-2)', letterSpacing: '.12em', textTransform: 'uppercase' }}>— vide —</div>
                          )}
                          {(activeBoard?.[t.l] || []).map(id => {
                            const it = lookup(id);
                            if (!it) return null;
                            const divColor = DIV_COLOR[it.division] || 'var(--gold)';
                            return <TierPill key={id} item={it} divColor={divColor} canEdit={canEdit}
                              onMove={(to) => moveItem(id, to)}
                              onDragStart={() => setDragId(id)} onDragEnd={() => setDragId(null)} />;
                          })}
                        </div>
                      </div>
                    </DropZone>
                  ))}
                </div>

                <DropZone tier="pool" canEdit={canEdit} onDrop={(id) => moveItem(id, 'pool')} dragId={dragId}>
                  <aside style={{
                    background: 'linear-gradient(180deg, var(--char-2), var(--char))',
                    border: '1px solid var(--border)', borderRadius: 4, padding: '1rem', alignSelf: 'flex-start',
                    minHeight: 200,
                  }}>
                    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '.85rem' }}>
                      <div className="eyebrow" style={{ color: 'var(--muted)' }}>Pool · à classer</div>
                      <span style={{ fontFamily: 'var(--fd)', fontSize: '1.1rem', color: 'var(--gold)' }}>{(activeBoard?.pool || []).length}</span>
                    </div>
                    <div style={{ display: 'flex', flexDirection: 'column', gap: '.4rem', maxHeight: 540, overflowY: 'auto' }}>
                      {(activeBoard?.pool || []).map(id => {
                        const it = lookup(id);
                        if (!it) return null;
                        const divColor = DIV_COLOR[it.division] || 'var(--gold)';
                        return <TierPill key={id} item={it} divColor={divColor} canEdit={canEdit}
                          onMove={(to) => moveItem(id, to)}
                          onDragStart={() => setDragId(id)} onDragEnd={() => setDragId(null)} />;
                      })}
                    </div>
                  </aside>
                </DropZone>
              </div>
            )}

        <div style={{ marginTop: '1rem', fontFamily: 'var(--fc)', fontSize: '.7rem', color: 'var(--muted)', letterSpacing: '.04em', textAlign: 'center' }}>
          {canEdit ? 'Glisse-dépose les items entre les tiers, ou clique-les pour ouvrir un menu rapide.' : 'Vue lecture seule.'}
        </div>
      </main>
    </div>
  );
};

// ── Drop zone: handles drag & drop ──
const DropZone = ({ tier, canEdit, onDrop, dragId, children }) => {
  const [over, setOver] = React.useState(false);
  if (!canEdit) return children;
  return (
    <div
      onDragOver={e => { e.preventDefault(); setOver(true); }}
      onDragLeave={() => setOver(false)}
      onDrop={e => { e.preventDefault(); setOver(false); if (dragId) onDrop(dragId); }}
      style={{ outline: over ? '2px solid var(--gold)' : 'none', outlineOffset: -2, borderRadius: 4 }}
    >
      {children}
    </div>
  );
};

// ── Tier pill: draggable + click menu ──
const TierPill = ({ item, divColor, canEdit, onMove, onDragStart, onDragEnd }) => {
  const [openMenu, setOpenMenu] = React.useState(false);
  return (
    <div style={{ position: 'relative', display: 'inline-block' }}>
      <div
        draggable={canEdit}
        onDragStart={() => onDragStart && onDragStart()}
        onDragEnd={() => onDragEnd && onDragEnd()}
        onClick={() => canEdit && setOpenMenu(o => !o)}
        style={{
          display: 'inline-flex', alignItems: 'center', gap: '.55rem',
          background: 'var(--paper)', color: 'var(--paper-ink)',
          padding: '.3rem .7rem .3rem .3rem', borderRadius: 3,
          cursor: canEdit ? 'grab' : 'default',
          boxShadow: `inset 0 -2px 0 ${divColor}, 0 1px 3px rgba(0,0,0,.4)`,
        }}>
        <div style={{
          width: 24, height: 24, borderRadius: 2,
          background: 'var(--paper-ink)', color: divColor,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontFamily: 'var(--fd)', fontSize: '.7rem', letterSpacing: '.04em',
        }}>{item.tag}</div>
        <span style={{ fontFamily: 'var(--fd)', fontSize: '.9rem', letterSpacing: '.04em', color: 'var(--paper-ink)' }}>{item.name.toUpperCase()}</span>
      </div>
      {openMenu && (
        <div style={{
          position: 'absolute', top: '100%', left: 0, zIndex: 10, marginTop: 4,
          background: 'var(--char-2)', border: '1px solid var(--border-2)', borderRadius: 3,
          padding: '.35rem', display: 'flex', gap: '.25rem', boxShadow: '0 6px 16px rgba(0,0,0,.6)',
        }}>
          {['S','A','B','C','D','F','pool'].map(t => (
            <button key={t} onClick={() => { onMove(t); setOpenMenu(false); }} style={{
              fontFamily: 'var(--fd)', fontSize: '.85rem', padding: '.3rem .5rem',
              background: 'transparent', border: '1px solid var(--border)', color: 'var(--bone)',
              borderRadius: 2, cursor: 'pointer', letterSpacing: '.04em',
            }}>{t === 'pool' ? '↺' : t}</button>
          ))}
        </div>
      )}
    </div>
  );
};

Object.assign(window, { TierlistPage });
