/* global React, GAMES, Icon, CoinIcon, t, useProfile, useGameTokens, SHASTE_API, GAME_TOKEN_SWITCH_COOLDOWN_DAYS */

function normalizeTokens(payload) {
  if (Array.isArray(payload)) return payload;
  if (payload && Array.isArray(payload.tokens)) return payload.tokens;
  return [];
}

function getAssignedSlug(token) {
  return token.assignedSlug || token.assignedGameSlug || token.gameSlug || token.slug || token.assigned_to || '';
}

function getTokenName(token, index) {
  return token.name || token.title || token.label || token.id || `Token ${index + 1}`;
}

function GameTokensPage({ setPage }) {
  const { data: profileData } = useProfile();
  const { loading, error, data, refetch } = useGameTokens();

  const [assigningId, setAssigningId] = React.useState('');
  const [sellingId, setSellingId] = React.useState('');
  const [messages, setMessages] = React.useState({ error: '', success: '' });

  const supporterTier = String((profileData && profileData.supporter) || 'none');
  const canAssign = supporterTier !== 'none';
  const cooldownDays = Number(window.GAME_TOKEN_SWITCH_COOLDOWN_DAYS || GAME_TOKEN_SWITCH_COOLDOWN_DAYS || 30);

  const tokens = normalizeTokens(data);
  const gameBySlug = React.useMemo(() => {
    const map = new Map();
    GAMES.forEach((game) => map.set(game.slug, game));
    return map;
  }, []);

  const [selectedSlugById, setSelectedSlugById] = React.useState({});

  React.useEffect(() => {
    setSelectedSlugById((prev) => {
      const next = { ...prev };
      tokens.forEach((token) => {
        const tokenId = String(token && (token.id || token.tokenId || token.slug || token.name || ''));
        if (!tokenId) return;
        if (!next[tokenId]) {
          next[tokenId] = getAssignedSlug(token) || (GAMES[0] && GAMES[0].slug) || '';
        }
      });
      return next;
    });
  }, [tokens]);

  async function onAssign(token) {
    const tokenId = token && (token.id || token.tokenId || token.slug || token.name);
    const selectedSlug = selectedSlugById[String(tokenId)];
    if (!tokenId || !selectedSlug) return;

    if (!SHASTE_API || typeof SHASTE_API.assignGameToken !== 'function') {
      setMessages({ error: 'Token assignment is unavailable right now.', success: '' });
      return;
    }

    setAssigningId(String(tokenId));
    setMessages({ error: '', success: '' });
    try {
      await SHASTE_API.assignGameToken(tokenId, selectedSlug);
      setMessages({ error: '', success: 'Game token assigned successfully.' });
      await refetch(true);
    } catch (err) {
      setMessages({ error: (err && err.message) || 'Could not assign this token.', success: '' });
    } finally {
      setAssigningId('');
    }
  }

  async function onSell(token, currency) {
    const tokenId = token && (token.id || token.tokenId || token.slug || token.name);
    if (!tokenId) return;

    if (!SHASTE_API || typeof SHASTE_API.sellGameToken !== 'function') {
      setMessages({ error: 'Token selling is unavailable right now.', success: '' });
      return;
    }

    setSellingId(`${tokenId}:${currency}`);
    setMessages({ error: '', success: '' });
    try {
      await SHASTE_API.sellGameToken(tokenId, currency);
      setMessages({ error: '', success: `Token sold for ${currency.toUpperCase()}.` });
      await refetch(true);
    } catch (err) {
      setMessages({ error: (err && err.message) || 'Could not sell this token.', success: '' });
    } finally {
      setSellingId('');
    }
  }

  return (
    <div className="container fade-in" style={{ maxWidth: 980 }}>
      <div style={{ marginTop: 12, display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 14, flexWrap: 'wrap' }}>
        <div>
          <div className="eyebrow">Progression</div>
          <h1 className="h-display" style={{ fontSize: 'clamp(30px, 4vw, 42px)', marginTop: 6 }}>Game Tokens</h1>
          <p style={{ color: 'var(--muted)', margin: '8px 0 0' }}>Assign tokens to games or sell them for coins / XP.</p>
        </div>
        <button className="btn btn--ghost" onClick={() => setPage('profile')}>
          <Icon name="arrow" size={12} /> Back to profile
        </button>
      </div>

      <div className="card" style={{ marginTop: 16 }}>
        <div style={{ display: 'grid', gap: 6 }}>
          <strong>Assignment cooldown</strong>
          <p style={{ margin: 0, color: 'var(--muted)' }}>
            Switching a token to a different game starts a {cooldownDays}-day cooldown.
            Make sure you want to switch before confirming.
          </p>
          {!canAssign && (
            <p style={{ margin: 0, color: 'var(--pink)' }}>
              Only supporter-tier users can assign game tokens. Upgrade to Bronze, Silver, or Gold supporter to unlock assignment.
            </p>
          )}
        </div>
      </div>

      {messages.error && <div className="card" style={{ marginTop: 14, borderColor: 'rgba(255,92,169,.5)', color: '#ffc4de' }}>{messages.error}</div>}
      {messages.success && <div className="card" style={{ marginTop: 14, borderColor: 'rgba(96,220,140,.5)', color: '#ccffd9' }}>{messages.success}</div>}

      {loading && <div className="card" style={{ marginTop: 14 }}>Loading game tokens…</div>}
      {error && <div className="card" style={{ marginTop: 14, color: '#ffd7d7' }}>{error.message || 'Failed to load game tokens.'}</div>}

      {!loading && !error && (
        <div style={{ marginTop: 16, display: 'grid', gap: 12 }}>
          {!tokens.length && <div className="card">No game tokens available yet.</div>}
          {tokens.map((token, index) => {
            const tokenId = String(token && (token.id || token.tokenId || token.slug || token.name || index));
            const selectedSlug = selectedSlugById[tokenId] || '';
            const assignedSlug = getAssignedSlug(token);
            const assignedGame = gameBySlug.get(assignedSlug);
            const sellCoins = Number(token && (token.sellCoins || token.coinsValue || token.sell_coins || 0));
            const sellXp = Number(token && (token.sellXp || token.xpValue || token.sell_xp || 0));

            return (
              <div key={tokenId} className="card" style={{ display: 'grid', gap: 12 }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12, alignItems: 'center', flexWrap: 'wrap' }}>
                  <div>
                    <h3 style={{ margin: 0 }}>{getTokenName(token, index)}</h3>
                    <p style={{ margin: '4px 0 0', color: 'var(--muted)' }}>
                      Assigned to: {assignedGame ? assignedGame.title : (assignedSlug || 'Not assigned')}
                    </p>
                  </div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
                    <select
                      className="input"
                      value={selectedSlug}
                      onChange={(e) => setSelectedSlugById((prev) => ({ ...prev, [tokenId]: e.target.value }))}
                      disabled={!canAssign || assigningId === tokenId}
                      style={{ minWidth: 220 }}
                    >
                      {GAMES.map((game) => (
                        <option key={game.slug} value={game.slug}>{game.title}</option>
                      ))}
                    </select>
                    <button
                      className="btn btn--primary btn--sm"
                      disabled={!canAssign || !selectedSlug || assigningId === tokenId}
                      onClick={() => onAssign(token)}
                    >
                      {assigningId === tokenId ? 'Assigning…' : 'Assign token'} <Icon name="arrow" size={12} />
                    </button>
                  </div>
                </div>

                <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
                  <span style={{ color: 'var(--subtle)', fontSize: 12 }}>Sell token:</span>
                  <button
                    className="btn btn--ghost btn--sm"
                    disabled={sellingId === `${tokenId}:coins`}
                    onClick={() => onSell(token, 'coins')}
                  >
                    <CoinIcon size={12} /> {sellCoins > 0 ? sellCoins.toLocaleString() : ''} coins
                  </button>
                  <button
                    className="btn btn--ghost btn--sm"
                    disabled={sellingId === `${tokenId}:xp`}
                    onClick={() => onSell(token, 'xp')}
                  >
                    {sellXp > 0 ? sellXp.toLocaleString() : ''} XP
                  </button>
                </div>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

Object.assign(window, { GameTokensPage });
