const LiveGame = {
  chess: null,
  matchId: null,
  playerColor: null,
  playerId: null,
  opponentId: null,
  isGameOver: false,
  moveHistory: [],

  clockWhite: 0,
  clockBlack: 0,
  clockInterval: null,
  activeClock: null,
  lastTickTime: 0,
  increment: 0,

  currentMoveIndex: -1,

  audioCtx: null,

  openings: {
    'e4': 'King Pawn', 'e4 e5': 'Open Game',
    'e4 e5 Nf3 Nc6 Bb5': 'Ruy Lopez', 'e4 e5 Nf3 Nc6 Bc4': 'Italian Game',
    'e4 c5': 'Sicilian Defense', 'e4 e6': 'French Defense',
    'e4 c6': 'Caro-Kann Defense', 'd4': 'Queen Pawn',
    'd4 d5 c4': "Queen's Gambit", 'd4 Nf6 c4 g6': "King's Indian",
    'd4 Nf6 c4 e6 Nc3 Bb4': 'Nimzo-Indian', 'c4': 'English Opening',
    'Nf3': 'Reti Opening'
  },

  async init(matchId) {
    this.matchId = matchId;
    this.playerId = App.user ? App.user.id : null;

    const res = await App.fetch('/api/game?action=get&id=' + matchId);
    if (!res || !res.game) {
      App.toast('المباراة غير موجودة', 'error');
      setTimeout(() => window.location.href = '/play', 1500);
      return;
    }

    const match = res.game;

    if (match.white_player_id === this.playerId) {
      this.playerColor = 'w';
      this.opponentId = match.black_player_id;
    } else if (match.black_player_id === this.playerId) {
      this.playerColor = 'b';
      this.opponentId = match.white_player_id;
    } else {
      App.toast('لست طرفا في هذه المباراة', 'error');
      return;
    }

    this.clockWhite = (match.white_time_remaining_ms || match.initial_time_ms) / 1000;
    this.clockBlack = (match.black_time_remaining_ms || match.initial_time_ms) / 1000;
    this.increment = (match.increment_ms || 0) / 1000;

    this.chess = new Chess(match.current_fen || undefined);

    Board.init('board', {
      flipped: this.playerColor === 'b',
      playerColor: this.playerColor,
      onMove: (move) => this.handlePlayerMove(move)
    });
    Board.setPosition(this.chess);
    Board.pushPosition(this.chess.fen());

    this.loadExistingMoves(match);
    this.updateUI(match);
    this.updateClockDisplay();
    this.updateMoveList();

    Realtime.connect(App.token);
    Realtime.subscribe(matchId, (record) => this.onRealtimeUpdate(record));

    if (match.status === 'ready') {
      this.signalReady();
    } else if (match.status === 'in_progress') {
      this.startGame();
    }
  },

  loadExistingMoves(match) {
    let moves = match.moves;
    if (typeof moves === 'string') {
      try { moves = JSON.parse(moves); } catch(e) { moves = []; }
    }
    if (!moves || !Array.isArray(moves)) return;

    moves.forEach(m => {
      const san = typeof m === 'string' ? m : m.san;
      if (san) this.moveHistory.push(san);
    });
    this.currentMoveIndex = this.moveHistory.length - 1;
  },

  updateUI(match) {
    const playerNameEl = document.getElementById('player-name');
    const opponentNameEl = document.getElementById('opponent-name');
    const playerRatingEl = document.getElementById('player-rating');
    const opponentRatingEl = document.getElementById('opponent-rating');

    if (playerNameEl) playerNameEl.textContent = App.user?.user_metadata?.display_name || 'انت';
    if (playerRatingEl) {
      const r = this.playerColor === 'w' ? match.white_rating_before : match.black_rating_before;
      playerRatingEl.textContent = r || '1200';
    }
    if (opponentRatingEl) {
      const r = this.playerColor === 'w' ? match.black_rating_before : match.white_rating_before;
      opponentRatingEl.textContent = r || '1200';
    }
  },

  async signalReady() {
    this.updateStatus('بانتظار الخصم...');
    await App.fetch('/api/multiplayer', {
      method: 'POST',
      body: JSON.stringify({ action: 'ready', match_id: this.matchId })
    });
  },

  startGame() {
    const turn = this.chess.turn();
    if (turn === this.playerColor) {
      Board.setEnabled(true);
      this.updateStatus('دورك');
    } else {
      Board.setEnabled(false);
      this.updateStatus('دور الخصم');
      this.showThinking(true);
    }
    this.startClock(turn);
  },

  handlePlayerMove(move) {
    if (this.isGameOver) return;
    if (this.chess.turn() !== this.playerColor) return;

    const result = this.chess.move({
      from: move.from,
      to: move.to,
      promotion: move.promotion || 'q'
    });

    if (!result) return;

    this.moveHistory.push(result.san);
    this.currentMoveIndex = this.moveHistory.length - 1;
    Board.lastMove = { from: move.from, to: move.to };
    Board.setPosition(this.chess);
    Board.pushPosition(this.chess.fen());
    this.applyIncrement(this.playerColor);
    this.switchClock();
    this.updateMoveList();
    this.updateStatus('دور الخصم');
    this.showThinking(true);
    this.playMoveSound(result);
    Board.setEnabled(false);

    const myClockMs = Math.round(
      (this.playerColor === 'w' ? this.clockWhite : this.clockBlack) * 1000
    );

    App.fetch('/api/multiplayer', {
      method: 'POST',
      body: JSON.stringify({
        action: 'move',
        match_id: this.matchId,
        move: result.san,
        fen: this.chess.fen(),
        clock_remaining_ms: myClockMs
      })
    });

    if (this.chess.game_over()) {
      this.handleGameOver();
    }
  },

  onRealtimeUpdate(record) {
    if (!record) return;

    if (record.status === 'in_progress' && !this.activeClock) {
      this.startGame();
      return;
    }

    if (record.status === 'completed' || record.status === 'aborted') {
      this.onGameEnded(record);
      return;
    }

    const gameState = typeof record.game_state === 'string'
      ? JSON.parse(record.game_state || '{}') : (record.game_state || {});

    if (gameState.draw_offered_by && gameState.draw_offered_by !== this.playerId) {
      this.showDrawOffer(true);
    } else {
      this.showDrawOffer(false);
    }

    if (record.current_fen && record.current_fen !== this.chess.fen()) {
      this.applyOpponentMove(record);
    }
  },

  applyOpponentMove(record) {
    const newFen = record.current_fen;
    const tempChess = new Chess(newFen);

    let moves = record.moves;
    if (typeof moves === 'string') {
      try { moves = JSON.parse(moves); } catch(e) { moves = []; }
    }

    if (moves && moves.length > this.moveHistory.length) {
      const lastMove = moves[moves.length - 1];
      const san = typeof lastMove === 'string' ? lastMove : lastMove.san;

      const result = this.chess.move(san);
      if (result) {
        this.moveHistory.push(san);
        this.currentMoveIndex = this.moveHistory.length - 1;

        Board.animateMove(result.from, result.to, () => {
          Board.lastMove = { from: result.from, to: result.to };
          Board.setPosition(this.chess);
          Board.pushPosition(this.chess.fen());
          this.updateMoveList();
          this.playMoveSound(result);
        });
      }
    }

    const opponentColor = this.playerColor === 'w' ? 'b' : 'w';
    if (opponentColor === 'w') {
      this.clockWhite = (record.white_time_remaining_ms || 0) / 1000;
    } else {
      this.clockBlack = (record.black_time_remaining_ms || 0) / 1000;
    }

    if (this.chess.turn() === this.playerColor) {
      Board.setEnabled(true);
      this.updateStatus('دورك');
      this.showThinking(false);
      this.switchClock();
    }

    if (this.chess.game_over()) {
      this.handleGameOver();
    }
  },

  onGameEnded(record) {
    this.isGameOver = true;
    this.stopClock();
    Board.setEnabled(false);
    Realtime.unsubscribe();

    let title, subtitle;
    const result = record.result;

    if (result === 'white_wins' || result === 'black_wins') {
      const winner = result === 'white_wins' ? 'w' : 'b';
      title = winner === this.playerColor ? 'فزت!' : 'خسرت';
      subtitle = 'كش مات';
    } else if (result === 'white_resign' || result === 'black_resign') {
      const resigned = result === 'white_resign' ? 'w' : 'b';
      title = resigned === this.playerColor ? 'خسرت' : 'فزت!';
      subtitle = 'استسلام';
    } else if (result === 'white_timeout' || result === 'black_timeout') {
      const timedOut = result === 'white_timeout' ? 'w' : 'b';
      title = timedOut === this.playerColor ? 'خسرت بالوقت' : 'فزت بالوقت!';
      subtitle = 'انتهى الوقت';
    } else if (result === 'mutual_draw' || result === 'stalemate' || result === 'draw') {
      title = 'تعادل';
      subtitle = result === 'mutual_draw' ? 'باتفاق' : 'جمود';
    } else if (result === 'aborted') {
      title = 'المباراة ملغاة';
      subtitle = '';
    } else {
      title = 'انتهت المباراة';
      subtitle = result || '';
    }

    this.showResult(title, subtitle);
  },

  handleGameOver() {
    if (this.isGameOver) return;
    this.isGameOver = true;
    this.stopClock();
    Board.setEnabled(false);

    let title, subtitle;
    if (this.chess.in_checkmate()) {
      const winner = this.chess.turn() === 'w' ? 'b' : 'w';
      title = winner === this.playerColor ? 'فزت!' : 'خسرت';
      subtitle = 'كش مات';
    } else if (this.chess.in_stalemate()) {
      title = 'تعادل';
      subtitle = 'جمود';
    } else if (this.chess.in_draw()) {
      title = 'تعادل';
      subtitle = 'قطع غير كافية';
    }

    this.showResult(title, subtitle);
    this.playGameEndSound(title === 'فزت!');
  },

  showResult(title, subtitle) {
    this.updateStatus(title);
    document.getElementById('game-controls').style.display = 'none';
    document.getElementById('postgame-controls').style.display = 'flex';
    const mobileControls = document.getElementById('game-controls-mobile');
    if (mobileControls) mobileControls.style.display = 'none';

    const wrapper = document.querySelector('.board-wrapper');
    if (!wrapper) return;

    const matchId = this.matchId;
    const overlay = document.createElement('div');
    overlay.className = 'game-result';
    overlay.innerHTML =
      '<div class="game-result-title">' + title + '</div>' +
      '<div class="game-result-subtitle">' + subtitle + '</div>' +
      '<div class="game-controls" style="margin-top:16px;display:flex;gap:8px;flex-wrap:wrap;justify-content:center;">' +
        '<button class="btn btn-gold" onclick="window.location.href=\'/analysis?id=' + matchId + '\'">تحليل اللعبة</button>' +
        '<button class="btn btn-cyan" onclick="window.location.href=\'/play\'">العب مرة اخرى</button>' +
      '</div>';
    wrapper.appendChild(overlay);
  },

  // --- Clock ---
  startClock(color) {
    this.stopClock();
    this.activeClock = color;
    this.lastTickTime = performance.now();

    this.clockInterval = setInterval(() => {
      const now = performance.now();
      const elapsed = (now - this.lastTickTime) / 1000;
      this.lastTickTime = now;

      if (this.activeClock === 'w') {
        this.clockWhite -= elapsed;
        if (this.clockWhite <= 0) {
          this.clockWhite = 0;
          this.onTimeout('w');
        }
      } else {
        this.clockBlack -= elapsed;
        if (this.clockBlack <= 0) {
          this.clockBlack = 0;
          this.onTimeout('b');
        }
      }
      this.updateClockDisplay();
    }, 50);
  },

  stopClock() {
    if (this.clockInterval) {
      clearInterval(this.clockInterval);
      this.clockInterval = null;
    }
  },

  switchClock() {
    const next = this.activeClock === 'w' ? 'b' : 'w';
    this.startClock(next);
  },

  applyIncrement(color) {
    if (this.increment <= 0) return;
    if (color === 'w') this.clockWhite += this.increment;
    else this.clockBlack += this.increment;
  },

  onTimeout(color) {
    this.stopClock();
    if (color !== this.playerColor) {
      App.fetch('/api/multiplayer', {
        method: 'POST',
        body: JSON.stringify({ action: 'timeout', match_id: this.matchId })
      });
    }
  },

  updateClockDisplay() {
    const topClock = document.getElementById('clock-top');
    const bottomClock = document.getElementById('clock-bottom');
    if (!topClock || !bottomClock) return;

    const topColor = this.playerColor === 'w' ? 'b' : 'w';
    const bottomColor = this.playerColor;

    const topTime = topColor === 'w' ? this.clockWhite : this.clockBlack;
    const bottomTime = bottomColor === 'w' ? this.clockWhite : this.clockBlack;

    topClock.textContent = this.formatTime(topTime);
    bottomClock.textContent = this.formatTime(bottomTime);

    topClock.className = 'game-clock' + (this.activeClock === topColor ? ' active' : '') + (topTime <= 30 ? ' low' : '');
    bottomClock.className = 'game-clock' + (this.activeClock === bottomColor ? ' active' : '') + (bottomTime <= 30 ? ' low' : '');
  },

  formatTime(seconds) {
    if (seconds <= 0) return '0:00';
    const mins = Math.floor(seconds / 60);
    const secs = Math.floor(seconds % 60);
    if (seconds < 10) {
      const tenths = Math.floor((seconds % 1) * 10);
      return secs + '.' + tenths;
    }
    if (seconds < 60) return '0:' + secs.toString().padStart(2, '0');
    return mins + ':' + secs.toString().padStart(2, '0');
  },

  // --- Actions ---
  resign() {
    if (this.isGameOver) return;
    if (!confirm('هل تريد الاستسلام؟')) return;
    App.fetch('/api/multiplayer', {
      method: 'POST',
      body: JSON.stringify({ action: 'resign', match_id: this.matchId })
    });
  },

  offerDraw() {
    if (this.isGameOver) return;
    App.fetch('/api/multiplayer', {
      method: 'POST',
      body: JSON.stringify({ action: 'draw_offer', match_id: this.matchId })
    });
    App.toast('تم ارسال عرض التعادل', 'info');
  },

  acceptDraw() {
    App.fetch('/api/multiplayer', {
      method: 'POST',
      body: JSON.stringify({ action: 'draw_accept', match_id: this.matchId })
    });
  },

  declineDraw() {
    App.fetch('/api/multiplayer', {
      method: 'POST',
      body: JSON.stringify({ action: 'draw_decline', match_id: this.matchId })
    });
    this.showDrawOffer(false);
  },

  showDrawOffer(show) {
    ['draw-offer-banner', 'draw-offer-banner-mobile'].forEach(id => {
      const el = document.getElementById(id);
      if (el) el.style.display = show ? 'flex' : 'none';
    });
  },

  // --- Move list ---
  updateMoveList() {
    const lists = [document.getElementById('move-list'), document.getElementById('move-list-mobile')].filter(Boolean);
    const history = this.moveHistory;

    lists.forEach(list => {
      list.innerHTML = '';
      for (let i = 0; i < history.length; i += 2) {
        const pair = document.createElement('div');
        pair.className = 'move-pair';

        const num = document.createElement('span');
        num.className = 'move-number';
        num.textContent = (Math.floor(i / 2) + 1) + '.';
        pair.appendChild(num);

        const white = document.createElement('span');
        white.className = 'move' + (i === this.currentMoveIndex ? ' current' : '');
        white.textContent = history[i];
        pair.appendChild(white);

        if (history[i + 1]) {
          const black = document.createElement('span');
          black.className = 'move' + (i + 1 === this.currentMoveIndex ? ' current' : '');
          black.textContent = history[i + 1];
          pair.appendChild(black);
        }

        list.appendChild(pair);
      }
      list.scrollTop = list.scrollHeight;
    });

    this.updateOpeningName(history);
  },

  updateOpeningName(history) {
    const els = [document.getElementById('opening-display'), document.getElementById('opening-display-mobile')].filter(Boolean);
    if (!history.length) { els.forEach(el => el.style.display = 'none'); return; }

    let opening = '';
    for (let len = Math.min(history.length, 10); len >= 1; len--) {
      const seq = history.slice(0, len).join(' ');
      if (this.openings[seq]) { opening = this.openings[seq]; break; }
    }

    els.forEach(el => {
      if (opening) {
        el.style.display = 'flex';
        const nameEl = el.querySelector('.opening-name');
        if (nameEl) nameEl.textContent = opening;
      } else {
        el.style.display = 'none';
      }
    });
  },

  updateStatus(text) {
    ['game-status', 'game-status-mobile'].forEach(id => {
      const el = document.getElementById(id);
      if (el) el.textContent = text;
    });
  },

  showThinking(show) {
    const el = document.getElementById('thinking-indicator');
    if (el) el.style.display = show ? 'flex' : 'none';
  },

  // --- Export ---
  exportPGN() {
    const pgn = this.chess.pgn();
    if (navigator.clipboard) {
      navigator.clipboard.writeText(pgn).then(() => App.toast('PGN copied', 'success'));
    }
  },

  copyFEN() {
    const fen = this.chess.fen();
    if (navigator.clipboard) {
      navigator.clipboard.writeText(fen).then(() => App.toast('FEN copied', 'success'));
    }
  },

  // --- Sound ---
  getAudioCtx() {
    if (!this.audioCtx) {
      try { this.audioCtx = new (window.AudioContext || window.webkitAudioContext)(); }
      catch(e) { return null; }
    }
    return this.audioCtx;
  },

  playTone(freq, duration, gain, type) {
    const ctx = this.getAudioCtx();
    if (!ctx) return;
    try {
      const osc = ctx.createOscillator();
      const g = ctx.createGain();
      osc.connect(g); g.connect(ctx.destination);
      osc.type = type || 'sine';
      osc.frequency.setValueAtTime(freq, ctx.currentTime);
      g.gain.setValueAtTime(gain || 0.1, ctx.currentTime);
      g.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + duration);
      osc.start(ctx.currentTime);
      osc.stop(ctx.currentTime + duration);
    } catch(e) {}
  },

  playMoveSound(move) {
    if (move.san === 'O-O' || move.san === 'O-O-O') {
      this.playTone(500, 0.06, 0.12, 'sine');
      setTimeout(() => this.playTone(600, 0.06, 0.12, 'sine'), 70);
    } else if (move.san && move.san.includes('+')) {
      this.playTone(880, 0.15, 0.15, 'square');
    } else if (move.captured) {
      this.playTone(180, 0.12, 0.18, 'sawtooth');
    } else {
      this.playTone(440, 0.06, 0.1, 'sine');
    }
  },

  playGameEndSound(isWin) {
    if (isWin) {
      this.playTone(523, 0.15, 0.12, 'sine');
      setTimeout(() => this.playTone(659, 0.15, 0.12, 'sine'), 150);
      setTimeout(() => this.playTone(784, 0.3, 0.15, 'sine'), 300);
    } else {
      this.playTone(400, 0.2, 0.1, 'sine');
      setTimeout(() => this.playTone(300, 0.2, 0.1, 'sine'), 200);
    }
  }
};
