import React, { useEffect, useState } from 'react';
import { Routes, Route, Link, useLocation, useNavigate, useParams } from 'react-router-dom';
import { apiFetch, clearToken, getToken, getUsername, setToken, wsUrl } from './api.js';
import logo from './assets/colonist/logo.png';
import iconTrophy from './assets/colonist/icon_trophy.svg';
import iconFriends from './assets/colonist/icon_friends.svg';
import iconPlay from './assets/colonist/icon_play.svg';
import iconCoin from './assets/colonist/icon_coin.svg';
import iconPlayer from './assets/colonist/icon_player.svg';
import iconHamburger from './assets/colonist/icon_hamburger.svg';
import iconPlayers from './assets/colonist/icon_players.svg';
import iconRefresh from './assets/colonist/icon_refresh.svg';
import iconLanguage from './assets/colonist/icon_language.svg';
import landingMap from './assets/colonist/landing_page_map.png';
import overlay from './assets/colonist/landing_page_background_overlay.png';
import overlayMobile from './assets/colonist/landing_page_background_overlay_mobile.png';
import roadBlue from './assets/colonist/road_blue.svg';
import roadRed from './assets/colonist/road_red.svg';
import roadGreen from './assets/colonist/road_green.svg';
import roadOrange from './assets/colonist/road_orange.svg';
import settlementBlue from './assets/colonist/settlement_blue.svg';
import settlementRed from './assets/colonist/settlement_red.svg';
import settlementGreen from './assets/colonist/settlement_green.svg';
import settlementOrange from './assets/colonist/settlement_orange.svg';

const RESOURCE_COLORS = {
  brick: '#c46a44',
  lumber: '#4a6d4a',
  wool: '#8cc071',
  grain: '#e2c065',
  ore: '#7a7c83',
  desert: '#d8c18f',
};

const SIDEBAR_ITEMS = [
  { key: 'leaderboards', label: 'Leaderboards', icon: iconTrophy, to: '/analytics' },
  { key: 'lobby', label: 'Lobby', icon: iconFriends, to: '/' },
  { key: 'play', label: 'Play', icon: iconPlay, to: '/' },
  { key: 'store', label: 'Store', icon: iconCoin, to: '/store' },
  { key: 'profile', label: 'Profile', icon: iconPlayer, to: '/profile' },
];

function isActiveItem(key, path) {
  if (key === 'play') {
    return path.startsWith('/game');
  }
  if (key === 'leaderboards') {
    return path.startsWith('/analytics');
  }
  if (key === 'store') {
    return path.startsWith('/store') || path.startsWith('/replays');
  }
  if (key === 'profile') {
    return path.startsWith('/profile');
  }
  if (key === 'lobby') {
    return path === '/' || path.startsWith('/lobby');
  }
  return false;
}

function Sidebar() {
  const location = useLocation();
  return (
    <aside className="web-sidebar">
      <div className="web-sidebar-logo">
        <Link to="/"><img src={logo} alt="colonist logo" /></Link>
      </div>
      <nav className="web-sidebar-nav">
        {SIDEBAR_ITEMS.map((item) => (
          <Link
            key={item.key}
            to={item.to}
            className={`web-sidebar-nav-item ${isActiveItem(item.key, location.pathname) ? 'active' : ''}`}
          >
            <img src={item.icon} alt={item.label} />
            <span>{item.label}</span>
          </Link>
        ))}
      </nav>
      <div className="web-sidebar-footer">
        <div className="language-button">
          <img src={iconLanguage} alt="Language" />
          <div>en</div>
        </div>
      </div>
    </aside>
  );
}

function Header({ user, onLogout }) {
  const navigate = useNavigate();
  return (
    <header className="web-header">
      <div className="web-header-mobile-left">
        <div className="web-header-burger-left">
          <img src={iconHamburger} alt="Menu" />
        </div>
        <div className="web-header-logo">
          <Link to="/"><img src={logo} alt="colonist logo" /></Link>
        </div>
      </div>
      <div className="web-header-left">
        <div className="web-header-profile">
          {user ? (
            <div className="web-header-profile-loggedin">
              <div className="web-header-profile-avatar">
                <img className="profile-icon" src={iconPlayers} alt="Player Icon" />
              </div>
              <div>
                <p className="web-header-username">{user}</p>
                <p className="web-header-karma">Karma 0</p>
              </div>
            </div>
          ) : (
            <div className="web-header-visitor-container">
              <p className="web-header-username">Guest</p>
              <button className="web-header-login-button" onClick={() => navigate('/login')}>
                Login
              </button>
            </div>
          )}
        </div>
        <div className="header-coins">
          <img src={iconCoin} alt="Coins" />
          <h3>0</h3>
        </div>
      </div>
      <div className="web-header-right">
        {user && (
          <button className="btn_general btn_general_secondary header-logout-button" onClick={onLogout}>
            Logout
          </button>
        )}
        <div className="web-header-burger">
          <img src={iconHamburger} alt="Menu" />
        </div>
      </div>
    </header>
  );
}

function PageShell({ children, side, hideAds }) {
  return (
    <div className={`web-layout-content-with-ads${hideAds ? ' content-wide' : ''}`}>
      <div className="web-layout-main-content">{children}</div>
      {!hideAds && <div className="web-layout-ad-space">{side}</div>}
    </div>
  );
}

function AuthPanel({ onAuth }) {
  const [login, setLogin] = useState({ username: '', password: '' });
  const [register, setRegister] = useState({ username: '', password: '' });
  const navigate = useNavigate();

  async function submitLogin() {
    try {
      const data = await apiFetch('/api/auth/login', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(login),
      });
      setToken(data.token, data.username);
      onAuth(data.username);
      navigate('/');
    } catch (err) {
      window.alert(err.message);
    }
  }

  async function submitRegister() {
    try {
      const data = await apiFetch('/api/auth/register', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(register),
      });
      setToken(data.token, data.username);
      onAuth(data.username);
      navigate('/');
    } catch (err) {
      window.alert(err.message);
    }
  }

  return (
    <div className="auth-panel">
      <div className="auth-card">
        <h3>Login</h3>
        <input
          className="input_general"
          placeholder="Username"
          value={login.username}
          onChange={(e) => setLogin({ ...login, username: e.target.value })}
        />
        <input
          className="input_general"
          type="password"
          placeholder="Password"
          value={login.password}
          onChange={(e) => setLogin({ ...login, password: e.target.value })}
        />
        <button className="btn_general btn_general_orange" onClick={submitLogin}>
          Enter Lobby
        </button>
      </div>
      <div className="auth-card">
        <h3>Create Account</h3>
        <input
          className="input_general"
          placeholder="Username"
          value={register.username}
          onChange={(e) => setRegister({ ...register, username: e.target.value })}
        />
        <input
          className="input_general"
          type="password"
          placeholder="Password"
          value={register.password}
          onChange={(e) => setRegister({ ...register, password: e.target.value })}
        />
        <button className="btn_general btn_general_secondary" onClick={submitRegister}>
          Register
        </button>
      </div>
    </div>
  );
}

function LandingPage({ onAuth }) {
  return (
    <div className="scene_landing_page_container">
      <div className="landing_page_left_side">
        <div className="landing_page_map_container">
          <img className="landing_page_map" src={landingMap} alt="Catan map" />
          <div className="landing_page_map_animation_container">
            <img className="landing_page_map_road landing_page_map_road_1" src={roadBlue} alt="Road" />
            <img className="landing_page_map_road landing_page_map_road_2" src={roadBlue} alt="Road" />
            <img className="landing_page_map_road landing_page_map_road_3" src={roadRed} alt="Road" />
            <img className="landing_page_map_road landing_page_map_road_4" src={roadRed} alt="Road" />
            <img className="landing_page_map_road landing_page_map_road_5" src={roadGreen} alt="Road" />
            <img className="landing_page_map_road landing_page_map_road_6" src={roadGreen} alt="Road" />
            <img className="landing_page_map_road landing_page_map_road_7" src={roadOrange} alt="Road" />
            <img className="landing_page_map_road landing_page_map_road_8" src={roadOrange} alt="Road" />
            <img className="landing_page_map_settlement_1" src={settlementBlue} alt="Settlement" />
            <img className="landing_page_map_settlement_2" src={settlementBlue} alt="Settlement" />
            <img className="landing_page_map_settlement_3" src={settlementRed} alt="Settlement" />
            <img className="landing_page_map_settlement_4" src={settlementRed} alt="Settlement" />
            <img className="landing_page_map_settlement_5" src={settlementGreen} alt="Settlement" />
            <img className="landing_page_map_settlement_6" src={settlementGreen} alt="Settlement" />
            <img className="landing_page_map_settlement_7" src={settlementOrange} alt="Settlement" />
            <img className="landing_page_map_settlement_8" src={settlementOrange} alt="Settlement" />
          </div>
        </div>
      </div>
      <div className="landing_page_right_side">
        <img className="landing_page_logo" src={logo} alt="colonist logo" />
        <div className="landing_page_right_side_content">
          <h1>#1 Catan AI Arena</h1>
          <div className="landing_page_social_proof">
            <span className="landing_page_social_proof_item">
              <b>4000</b> online
            </span>
            <span className="landing_page_social_proof_item">
              <b>180000</b> games today
            </span>
          </div>
          <div className="button_cta_landingpage_container">
            <div className="button_cta_landingpage_main">Play with Friends</div>
            <div className="button_cta_landingpage_sub">Play Online</div>
            <div className="button_cta_landingpage_sub_mobile">Continue on Web</div>
          </div>
        </div>
        <AuthPanel onAuth={onAuth} />
      </div>
      <img className="landing-page-background-overlay" src={overlay} alt="" />
      <img className="landing-page-background-overlay-mobile" src={overlayMobile} alt="" />
    </div>
  );
}

function LoginPage({ onAuth }) {
  return (
    <PageShell hideAds>
      <LandingPage onAuth={onAuth} />
    </PageShell>
  );
}

function LobbyPage() {
  const [games, setGames] = useState([]);
  const [models, setModels] = useState([]);
  const [stats, setStats] = useState(null);
  const [create, setCreate] = useState({ name: '', max_players: 4 });
  const navigate = useNavigate();

  async function load() {
    const [lobby, modelList, statsData] = await Promise.all([
      apiFetch('/api/lobby'),
      apiFetch('/api/models'),
      apiFetch('/api/stats'),
    ]);
    setGames(lobby.games || []);
    setModels(modelList.models || []);
    setStats(statsData);
  }

  useEffect(() => {
    load().catch(console.error);
  }, []);

  async function createGame() {
    const payload = {
      ...create,
      name: create.name || 'Room',
    };
    await apiFetch('/api/games', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload),
    });
    await load();
  }

  async function joinGame(id) {
    await apiFetch(`/api/games/${id}/join`, { method: 'POST' });
    navigate(`/game/${id}`);
  }

  async function joinById() {
    const id = window.prompt('Game id');
    if (!id) return;
    await joinGame(id);
  }

  async function addAi(id) {
    const type = window.prompt('AI type: random or model?', 'random');
    if (!type) return;
    const payload = { ai_type: type };
    if (type === 'model') {
      payload.model_name = window.prompt(`Model name: ${models.join(', ')}`);
    }
    await apiFetch(`/api/games/${id}/add-ai`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload),
    });
    await load();
  }

  async function startGame(id) {
    await apiFetch(`/api/games/${id}/start`, { method: 'POST' });
    navigate(`/game/${id}`);
  }

  const side = (
    <div className="side-stack">
      <div className="panel-card">
        <h3>Create Room</h3>
        <div className="form-stack">
          <input
            className="input_general"
            placeholder="Game name"
            value={create.name}
            onChange={(e) => setCreate({ ...create, name: e.target.value })}
          />
          <select
            className="input_general"
            value={create.max_players}
            onChange={(e) => setCreate({ ...create, max_players: parseInt(e.target.value, 10) })}
          >
            <option value={3}>3 players</option>
            <option value={4}>4 players</option>
          </select>
          <button className="btn_general btn_general_orange" onClick={createGame}>
            Create Room
          </button>
        </div>
      </div>
      <div className="panel-card">
        <h3>Stats</h3>
        {stats ? (
          <div className="stat-grid">
            <div>
              <strong>{stats.total_games}</strong>
              <span>Total games</span>
            </div>
            <div>
              <strong>{stats.finished_games}</strong>
              <span>Finished</span>
            </div>
            <div>
              <strong>{stats.user_games}</strong>
              <span>Your games</span>
            </div>
            <div>
              <strong>{stats.user_wins}</strong>
              <span>Your wins</span>
            </div>
            <div>
              <strong>{Number(stats.avg_turns || 0).toFixed(1)}</strong>
              <span>Avg turns</span>
            </div>
          </div>
        ) : (
          <div className="muted">Loading stats...</div>
        )}
      </div>
      <div className="panel-card">
        <h3>AI Models</h3>
        <div className="model-grid">
          {models.map((model) => (
            <span key={model} className="model-pill">
              {model}
            </span>
          ))}
          {models.length === 0 && <div className="muted">No models found.</div>}
        </div>
      </div>
    </div>
  );

  return (
    <PageShell side={side}>
      <div className="homepage-lobby-container">
        <div className="m-lobby-container">
          <div className="scene_lobby_mid_tabs">
            <div className="scene_lobby_mid_tabs_active">
              <div>Rooms</div>
            </div>
            <div className="scene_lobby_mid_tabs_inactive">
              <div>Spectate</div>
            </div>
          </div>
          <div className="lobby_center_tables_container">
            <div className="lobby-table">
              <table className="lobby-table-table">
                <thead>
                  <tr>
                    <th className="mode">
                      <div>Mode</div>
                    </th>
                    <th className="map">
                      <div>Map</div>
                    </th>
                    <th className="speed">
                      <div>Turn Timer</div>
                    </th>
                    <th className="refresh">
                      <img
                        src={iconRefresh}
                        alt="Refresh"
                        className="refresh-icon"
                        onClick={load}
                      />
                    </th>
                  </tr>
                </thead>
                <tbody>
                  {games.length === 0 && (
                    <tr>
                      <td colSpan={4} className="muted">
                        No active rooms.
                      </td>
                    </tr>
                  )}
                  {games.map((game) => (
                    <tr key={game.id}>
                      <td>
                        <div className="lobby-room-title">{game.name || 'Room'}</div>
                        <div className="lobby-room-sub">Classic - {game.status}</div>
                      </td>
                      <td>
                        <div className="lobby-room-sub">Base Map</div>
                        <div className="lobby-room-players">
                          {game.players.map((slot) => (
                            <span key={slot.slot_id} className="player-pill">
                              {slot.name || 'Open'}
                            </span>
                          ))}
                        </div>
                      </td>
                      <td>
                        <div className="lobby-room-sub">No timer</div>
                        <div>{game.max_players} players</div>
                      </td>
                      <td>
                        <div className="lobby-room-actions">
                          <button className="btn_general btn_general_secondary" onClick={() => joinGame(game.id)}>
                            Join
                          </button>
                          <button className="btn_general btn_general_secondary" onClick={() => addAi(game.id)}>
                            AI
                          </button>
                          <button className="btn_general btn_general_orange" onClick={() => startGame(game.id)}>
                            Start
                          </button>
                        </div>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>
          <div className="m-lobby-buttons-container">
            <div className="m-lobby-create-room-button" onClick={createGame}>
              Create Room
            </div>
            <div className="m-lobby-join-room-button" onClick={joinById}>
              Join Room
            </div>
          </div>
        </div>
      </div>
    </PageShell>
  );
}

function cubeToPixel(coord, scale) {
  const [x, , z] = coord;
  const sqrt3 = Math.sqrt(3);
  return {
    x: scale * (sqrt3 * x + (sqrt3 / 2) * z),
    y: scale * (1.5 * z),
  };
}

function hexCorners(cx, cy, size) {
  const points = [];
  for (let i = 0; i < 6; i += 1) {
    const angle = (Math.PI / 180) * (60 * i - 30);
    points.push([cx + size * Math.cos(angle), cy + size * Math.sin(angle)]);
  }
  return points;
}

function Board({ board, game }) {
  if (!board || !game) return null;
  const size = 46;
  const cornerScale = size / 3;
  const hexes = Object.values(board.hexes || {});
  const corners = board.corners || {};
  const edges = Object.values(board.edges || {});

  const hexPositions = hexes.map((hex) => ({ ...hex, pos: cubeToPixel(hex.coord, size) }));
  const cornerPositions = {};
  Object.entries(corners).forEach(([id, corner]) => {
    cornerPositions[id] = { ...corner, pos: cubeToPixel(corner.coord, cornerScale) };
  });

  const allPositions = [
    ...hexPositions.map((h) => h.pos),
    ...Object.values(cornerPositions).map((c) => c.pos),
  ];
  const minX = Math.min(...allPositions.map((p) => p.x));
  const maxX = Math.max(...allPositions.map((p) => p.x));
  const minY = Math.min(...allPositions.map((p) => p.y));
  const maxY = Math.max(...allPositions.map((p) => p.y));
  const padding = 80;
  const viewBox = `${minX - padding} ${minY - padding} ${maxX - minX + padding * 2} ${maxY - minY + padding * 2}`;

  const playerColors = {};
  Object.entries(game.players || {}).forEach(([name, pdata]) => {
    playerColors[name] = pdata.color || '#333';
  });

  const roadLines = edges
    .filter((edge) => edge.owner)
    .map((edge) => {
      const a = cornerPositions[edge.a];
      const b = cornerPositions[edge.b];
      if (!a || !b) return '';
      const color = playerColors[edge.owner] || '#222';
      return `<line x1="${a.pos.x}" y1="${a.pos.y}" x2="${b.pos.x}" y2="${b.pos.y}" stroke="${color}" stroke-width="6" stroke-linecap="round" />`;
    })
    .join('');

  const cornerNodes = Object.entries(cornerPositions)
    .filter(([, corner]) => corner.owner)
    .map(([, corner]) => {
      const radius = corner.building === 'city' ? 10 : 7;
      const color = playerColors[corner.owner] || '#222';
      return `<circle cx="${corner.pos.x}" cy="${corner.pos.y}" r="${radius}" fill="${color}" stroke="#fff" stroke-width="2" />`;
    })
    .join('');

  const hexShapes = hexPositions
    .map((hex) => {
      const points = hexCorners(hex.pos.x, hex.pos.y, size - 4)
        .map((pt) => pt.join(','))
        .join(' ');
      const fill = RESOURCE_COLORS[hex.resource] || '#e0c89a';
      const number = hex.number || '';
      const robber = hex.robber ? "<circle r='8' fill='rgba(0,0,0,0.35)' />" : '';
      return `
        <g>
          <polygon points="${points}" fill="${fill}" stroke="rgba(0,0,0,0.2)" stroke-width="2" />
          <text x="${hex.pos.x}" y="${hex.pos.y}" text-anchor="middle" font-size="16" fill="#3a2a1a" font-weight="600">${number}</text>
          <g transform="translate(${hex.pos.x}, ${hex.pos.y + 20})">${robber}</g>
        </g>
      `;
    })
    .join('');

  return (
    <svg
      className="board-svg"
      viewBox={viewBox}
      dangerouslySetInnerHTML={{ __html: `${hexShapes}${roadLines}${cornerNodes}` }}
    />
  );
}

function ActionForm({ action, onSubmit }) {
  const [payload, setPayload] = useState(action?.payload || {});

  useEffect(() => {
    setPayload(action?.payload || {});
  }, [action]);

  if (!action) {
    return null;
  }

  if (action.type === 'move_robber' || action.type === 'play_knight') {
    const options = action.payload.options || [];
    const selected = payload.hex ?? (options[0]?.hex ?? 0);
    const victims = (options.find((opt) => opt.hex === selected) || {}).victims || [];
    return (
      <div className="form-stack">
        <select
          className="input_general"
          value={selected}
          onChange={(e) => setPayload({ ...payload, hex: parseInt(e.target.value, 10) })}
        >
          {options.map((opt) => (
            <option key={opt.hex} value={opt.hex}>Hex {opt.hex}</option>
          ))}
        </select>
        <select
          className="input_general"
          value={payload.victim || ''}
          onChange={(e) => setPayload({ ...payload, victim: e.target.value || undefined })}
        >
          <option value="">No victim</option>
          {victims.map((victim) => (
            <option key={victim} value={victim}>{victim}</option>
          ))}
        </select>
        <button className="btn_general btn_general_orange" onClick={() => onSubmit(payload)}>
          Execute
        </button>
      </div>
    );
  }

  if (action.type === 'play_road_building') {
    const edges = action.payload.edges || [];
    return (
      <div className="form-stack">
        <div className="muted">Select two edges</div>
        <select
          className="input_general"
          multiple
          onChange={(e) => {
            const values = Array.from(e.target.selectedOptions).map((opt) => parseInt(opt.value, 10));
            setPayload({ edges: values.slice(0, 2) });
          }}
        >
          {edges.map((edge) => (
            <option key={edge} value={edge}>Edge {edge}</option>
          ))}
        </select>
        <button className="btn_general btn_general_orange" onClick={() => onSubmit(payload)}>
          Execute
        </button>
      </div>
    );
  }

  if (action.type === 'play_year_of_plenty') {
    const bank = action.payload.bank || {};
    const resources = Object.keys(bank);
    return (
      <div className="form-stack">
        <select className="input_general" onChange={(e) => setPayload({ ...payload, res1: e.target.value })}>
          {resources.map((res) => (
            <option key={res} value={res}>{res}</option>
          ))}
        </select>
        <select className="input_general" onChange={(e) => setPayload({ ...payload, res2: e.target.value })}>
          {resources.map((res) => (
            <option key={res} value={res}>{res}</option>
          ))}
        </select>
        <button
          className="btn_general btn_general_orange"
          onClick={() => onSubmit({ resources: [payload.res1 || resources[0], payload.res2 || resources[0]] })}
        >
          Execute
        </button>
      </div>
    );
  }

  if (action.type === 'play_monopoly') {
    const resources = action.payload.resources || ['brick', 'lumber', 'wool', 'grain', 'ore'];
    return (
      <div className="form-stack">
        <select className="input_general" onChange={(e) => setPayload({ resource: e.target.value })}>
          {resources.map((res) => (
            <option key={res} value={res}>{res}</option>
          ))}
        </select>
        <button
          className="btn_general btn_general_orange"
          onClick={() => onSubmit({ resource: payload.resource || resources[0] })}
        >
          Execute
        </button>
      </div>
    );
  }

  if (action.type === 'discard') {
    const resources = action.payload.resources || {};
    return (
      <div className="form-stack">
        {Object.entries(resources).map(([res, count]) => (
          <div key={res} className="form-row">
            <span className="muted">{res} ({count})</span>
            <input
              className="input_general"
              type="number"
              min="0"
              max={count}
              value={payload.cards?.[res] || 0}
              onChange={(e) => {
                setPayload({
                  ...payload,
                  cards: { ...payload.cards, [res]: parseInt(e.target.value, 10) || 0 },
                });
              }}
            />
          </div>
        ))}
        <button
          className="btn_general btn_general_orange"
          onClick={() => onSubmit({ player: getUsername(), cards: payload.cards || {} })}
        >
          Discard
        </button>
      </div>
    );
  }

  return (
    <button className="btn_general btn_general_orange" onClick={() => onSubmit(action.payload)}>
      Execute
    </button>
  );
}

function GamePage() {
  const { gameId } = useParams();
  const [state, setState] = useState(null);
  const [legalActions, setLegalActions] = useState([]);
  const [selectedIdx, setSelectedIdx] = useState(0);
  const [trade, setTrade] = useState({ to_player: '', offer: '', request: '' });

  useEffect(() => {
    let socket;
    async function load() {
      const data = await apiFetch(`/api/games/${gameId}`);
      setState(data);
      setLegalActions(data.legal_actions || []);
      socket = new WebSocket(wsUrl(`/ws/games/${gameId}`));
      socket.onmessage = (event) => {
        const msg = JSON.parse(event.data);
        if (msg.type === 'state') {
          setState(msg.data);
          setLegalActions(msg.data.legal_actions || []);
          setSelectedIdx(0);
        }
      };
    }
    load().catch(console.error);
    return () => socket && socket.close();
  }, [gameId]);

  const currentAction = legalActions[selectedIdx];

  async function submitAction(payload) {
    await apiFetch(`/api/games/${gameId}/action`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ type: currentAction.type, payload }),
    });
  }

  async function submitTrade() {
    const offer = trade.offer.split(',').reduce((acc, item) => {
      const [res, amt] = item.split(':').map((v) => v.trim());
      if (res && amt) acc[res] = parseInt(amt, 10) || 0;
      return acc;
    }, {});
    const request = trade.request.split(',').reduce((acc, item) => {
      const [res, amt] = item.split(':').map((v) => v.trim());
      if (res && amt) acc[res] = parseInt(amt, 10) || 0;
      return acc;
    }, {});
    await apiFetch(`/api/games/${gameId}/trade/offer`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        from_player: getUsername(),
        to_player: trade.to_player || null,
        offer,
        request,
      }),
    });
  }

  async function respondTrade(tradeId, accept) {
    await apiFetch(`/api/games/${gameId}/trade/${tradeId}/respond`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ player: getUsername(), accept }),
    });
  }

  if (!state) {
    return (
      <PageShell hideAds>
        <div className="screen">Loading...</div>
      </PageShell>
    );
  }

  return (
    <PageShell hideAds>
      <div className="game-layout">
        <aside className="game-panel">
          <div className="panel-card">
            <h3>Players</h3>
            <div className="panel-stack">
              {state.game && Object.entries(state.game.players).map(([name, pdata]) => (
                <div key={name} className="player-row">
                  <span className="player-dot" style={{ background: pdata.color || '#333' }} />
                  <div>
                    <strong>{name}</strong>
                    <div className="muted">VP {pdata.victory_points}</div>
                  </div>
                </div>
              ))}
            </div>
          </div>
          <div className="panel-card">
            <h3>Actions</h3>
            {legalActions.length === 0 && <div className="muted">Waiting for your turn...</div>}
            {legalActions.length > 0 && (
              <div className="form-stack">
                <select
                  className="input_general"
                  value={selectedIdx}
                  onChange={(e) => setSelectedIdx(parseInt(e.target.value, 10))}
                >
                  {legalActions.map((action, idx) => (
                    <option key={`${action.type}-${idx}`} value={idx}>{action.type}</option>
                  ))}
                </select>
                <ActionForm action={currentAction} onSubmit={submitAction} />
              </div>
            )}
          </div>
        </aside>
        <main className="game-board">
          <Board board={state.board} game={state.game} />
        </main>
        <aside className="game-panel">
          <div className="panel-card">
            <h3>Trades</h3>
            <div className="panel-stack">
              {state.pending_trades?.length === 0 && <div className="muted">No offers.</div>}
              {state.pending_trades?.map((offer) => (
                <div key={offer.id} className="trade-card">
                  <div className="muted">
                    {offer.from_player} - {offer.to_player || 'any'}
                  </div>
                  <div className="trade-line">
                    {JSON.stringify(offer.offer)} - {JSON.stringify(offer.request)}
                  </div>
                  {offer.to_player === getUsername() || offer.to_player === null ? (
                    <div className="trade-actions">
                      <button className="btn_general btn_general_orange" onClick={() => respondTrade(offer.id, true)}>
                        Accept
                      </button>
                      <button className="btn_general btn_general_secondary" onClick={() => respondTrade(offer.id, false)}>
                        Decline
                      </button>
                    </div>
                  ) : null}
                </div>
              ))}
              <div className="form-stack">
                <input
                  className="input_general"
                  placeholder="Target player (optional)"
                  value={trade.to_player}
                  onChange={(e) => setTrade({ ...trade, to_player: e.target.value })}
                />
                <input
                  className="input_general"
                  placeholder="Offer (brick:1,lumber:1)"
                  value={trade.offer}
                  onChange={(e) => setTrade({ ...trade, offer: e.target.value })}
                />
                <input
                  className="input_general"
                  placeholder="Request (grain:1)"
                  value={trade.request}
                  onChange={(e) => setTrade({ ...trade, request: e.target.value })}
                />
                <button className="btn_general btn_general_secondary" onClick={submitTrade}>
                  Propose Trade
                </button>
              </div>
            </div>
          </div>
          <div className="panel-card">
            <h3>Status</h3>
            <div className="panel-stack">
              <div>Phase: {state.game?.phase || '-'}</div>
              <div>Current: {state.game?.current_player || '-'}</div>
              <div>Last roll: {state.game?.last_roll || '-'}</div>
              <div>Winner: {state.game?.winner || '-'}</div>
            </div>
          </div>
          <div className="panel-card">
            <h3>History</h3>
            <div className="history-list">
              {(state.history || []).slice().reverse().map((entry) => (
                <div key={entry.idx} className="muted">{entry.actor}: {entry.action.type}</div>
              ))}
            </div>
          </div>
        </aside>
      </div>
    </PageShell>
  );
}

function AnalyticsPage() {
  const [stats, setStats] = useState(null);
  useEffect(() => {
    apiFetch('/api/stats').then(setStats).catch(console.error);
  }, []);
  return (
    <PageShell hideAds>
      <div className="panel-card">
        <h2>Global Stats</h2>
        {stats ? (
          <div className="stat-grid">
            <div>
              <strong>{stats.total_games}</strong>
              <span>Total games</span>
            </div>
            <div>
              <strong>{stats.finished_games}</strong>
              <span>Finished</span>
            </div>
            <div>
              <strong>{Number(stats.avg_turns || 0).toFixed(1)}</strong>
              <span>Average turns</span>
            </div>
          </div>
        ) : (
          <div className="muted">Loading stats...</div>
        )}
      </div>
    </PageShell>
  );
}

function ReplaysPage() {
  const [replays, setReplays] = useState([]);
  const navigate = useNavigate();
  useEffect(() => {
    apiFetch('/api/replays').then((data) => setReplays(data.replays || [])).catch(console.error);
  }, []);

  async function exportReplay(id) {
    const data = await apiFetch(`/api/replays/${id}/export`);
    const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = `catan-replay-${id}.json`;
    link.click();
    URL.revokeObjectURL(url);
  }

  return (
    <PageShell hideAds>
      <div className="panel-card">
        <h2>Replays</h2>
        <div className="replay-table">
          {replays.map((replay) => (
            <div key={replay.id} className="replay-row">
              <div>
                <strong>{replay.players.join(', ')}</strong>
                <div className="muted">Winner: {replay.winner || '-'}</div>
              </div>
              <div className="replay-actions">
                <button className="btn_general btn_general_orange" onClick={() => navigate(`/replays/${replay.id}`)}>
                  View
                </button>
                <button className="btn_general btn_general_secondary" onClick={() => exportReplay(replay.id)}>
                  Export
                </button>
              </div>
            </div>
          ))}
          {replays.length === 0 && <div className="muted">No replays yet.</div>}
        </div>
      </div>
    </PageShell>
  );
}

function ReplayViewer() {
  const { replayId } = useParams();
  const [detail, setDetail] = useState(null);
  const [step, setStep] = useState(0);
  const [state, setState] = useState(null);

  useEffect(() => {
    apiFetch(`/api/replays/${replayId}`).then(setDetail).catch(console.error);
  }, [replayId]);

  useEffect(() => {
    apiFetch(`/api/replays/${replayId}/state?step=${step}`).then(setState).catch(console.error);
  }, [replayId, step]);

  if (!detail) {
    return (
      <PageShell hideAds>
        <div className="screen">Loading replay...</div>
      </PageShell>
    );
  }

  return (
    <PageShell hideAds>
      <div className="panel-card replay-viewer">
        <h2>Replay {detail.id}</h2>
        <div className="panel-stack">
          <div>Players: {detail.players.join(', ')}</div>
          <div>Winner: {detail.winner || '-'}</div>
          <input
            className="input_general"
            type="range"
            min="0"
            max={detail.total_actions}
            value={step}
            onChange={(e) => setStep(parseInt(e.target.value, 10))}
          />
          <div className="muted">Step {step}</div>
        </div>
      </div>
      <div className="game-board replay-board">
        <Board board={state?.board} game={state?.game} />
      </div>
    </PageShell>
  );
}

function ProfilePage() {
  const [stats, setStats] = useState(null);
  useEffect(() => {
    apiFetch('/api/stats').then(setStats).catch(console.error);
  }, []);
  return (
    <PageShell hideAds>
      <div className="panel-card">
        <h2>Profile</h2>
        <div className="panel-stack">
          <div className="muted">Signed in as {getUsername() || 'Guest'}</div>
          {stats && (
            <div className="stat-grid">
              <div>
                <strong>{stats.user_games}</strong>
                <span>Your games</span>
              </div>
              <div>
                <strong>{stats.user_wins}</strong>
                <span>Your wins</span>
              </div>
            </div>
          )}
          <Link className="btn_general btn_general_orange" to="/replays">
            View Replays
          </Link>
        </div>
      </div>
    </PageShell>
  );
}

function StorePage() {
  const [models, setModels] = useState([]);
  const [replays, setReplays] = useState([]);

  useEffect(() => {
    Promise.all([apiFetch('/api/models'), apiFetch('/api/replays')])
      .then(([modelList, replayList]) => {
        setModels(modelList.models || []);
        setReplays(replayList.replays || []);
      })
      .catch(console.error);
  }, []);

  return (
    <PageShell hideAds>
      <div className="panel-card">
        <h2>Store</h2>
        <div className="panel-stack">
          <h3>AI Models</h3>
          <div className="model-grid">
            {models.map((model) => (
              <span key={model} className="model-pill">
                {model}
              </span>
            ))}
            {models.length === 0 && <div className="muted">No models found.</div>}
          </div>
          <h3>Recent Replays</h3>
          <div className="replay-list">
            {replays.slice(0, 5).map((replay) => (
              <div key={replay.id} className="replay-row compact">
                <div>
                  <strong>{replay.players.join(', ')}</strong>
                  <div className="muted">Winner: {replay.winner || '-'}</div>
                </div>
                <Link className="btn_general btn_general_secondary" to={`/replays/${replay.id}`}>
                  View
                </Link>
              </div>
            ))}
            {replays.length === 0 && <div className="muted">No replays yet.</div>}
          </div>
        </div>
      </div>
    </PageShell>
  );
}

export default function App() {
  const [user, setUser] = useState(getUsername());
  const hasToken = getToken();

  useEffect(() => {
    if (!hasToken) {
      setUser(null);
    }
  }, [hasToken]);

  function handleLogout() {
    clearToken();
    setUser(null);
  }

  return (
    <div className="web-layout-container" id="web-layout-container">
      <Sidebar />
      <Header user={user} onLogout={handleLogout} />
      <Routes>
        <Route path="/login" element={<LoginPage onAuth={setUser} />} />
        <Route path="/" element={user ? <LobbyPage /> : <LoginPage onAuth={setUser} />} />
        <Route path="/game/:gameId" element={user ? <GamePage /> : <LoginPage onAuth={setUser} />} />
        <Route path="/analytics" element={user ? <AnalyticsPage /> : <LoginPage onAuth={setUser} />} />
        <Route path="/replays" element={user ? <ReplaysPage /> : <LoginPage onAuth={setUser} />} />
        <Route path="/replays/:replayId" element={user ? <ReplayViewer /> : <LoginPage onAuth={setUser} />} />
        <Route path="/profile" element={user ? <ProfilePage /> : <LoginPage onAuth={setUser} />} />
        <Route path="/store" element={user ? <StorePage /> : <LoginPage onAuth={setUser} />} />
      </Routes>
    </div>
  );
}
