var DominoLive = (function() {
  'use strict';

  var LUDO_RT_ENDPOINT = 'wss://safe-supabase-kong.caprover.al-arcade.com/realtime/v1/websocket';
  var ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlIiwiaWF0IjoxNzM1Njg5NjAwLCJleHAiOjE4OTM0NTYwMDB9.31PF6PvP-pSrvRuQwLFptQoejR0W1A7o53lZhEbnz84';

  var state = {
    matchId: null,
    userId: null,
    token: null,
    match: null,
    myIdx: null,
    connected: false
  };

  var ws = null;
  var topic = null;
  var heartbeatInterval = null;
  var heartbeatRef = 0;
  var reconnectTimer = null;
  var reconnectAttempts = 0;

  function init(options) {
    state.matchId = options.matchId;
    state.userId = options.userId;
    state.token = options.token;

    DominoUI.init({
      onTilePlay: sendPlay,
      onDraw: sendDraw,
      onPass: sendPass
    });

    connect();
    fetchState();
  }

  // ─── WebSocket Connection ─────────────────────────────────────────────────

  function connect() {
    if (ws) { ws.onclose = null; ws.close(); }

    var url = LUDO_RT_ENDPOINT + '?apikey=' + ANON_KEY + '&vsn=1.0.0';
    ws = new WebSocket(url);

    ws.onopen = function() {
      state.connected = true;
      reconnectAttempts = 0;
      startHeartbeat();
      joinChannel();
    };

    ws.onmessage = function(evt) {
      handleMessage(evt);
    };

    ws.onclose = function() {
      state.connected = false;
      stopHeartbeat();
      scheduleReconnect();
    };

    ws.onerror = function() {};
  }

  function joinChannel() {
    topic = 'realtime:public:domino_matches:id=eq.' + state.matchId;
    send({
      topic: topic,
      event: 'phx_join',
      payload: {
        config: {
          broadcast: { self: false },
          presence: { key: '' },
          postgres_changes: [{
            event: 'UPDATE',
            schema: 'public',
            table: 'domino_matches',
            filter: 'id=eq.' + state.matchId
          }]
        }
      },
      ref: String(++heartbeatRef)
    });
  }

  function handleMessage(evt) {
    var msg;
    try { msg = JSON.parse(evt.data); } catch(e) { return; }

    if (msg.event === 'phx_reply' && msg.payload && msg.payload.status === 'ok') {
      return;
    }

    if (msg.event === 'postgres_changes') {
      var payload = msg.payload;
      if (payload && payload.data && payload.data.record) {
        handleUpdate(payload.data.record);
      }
    }

    if (msg.event === 'heartbeat' || msg.event === 'phx_reply') {
      return;
    }
  }

  function send(msg) {
    if (ws && ws.readyState === WebSocket.OPEN) {
      ws.send(JSON.stringify(msg));
    }
  }

  function startHeartbeat() {
    stopHeartbeat();
    heartbeatInterval = setInterval(function() {
      send({ topic: 'phoenix', event: 'heartbeat', payload: {}, ref: String(++heartbeatRef) });
    }, 30000);
  }

  function stopHeartbeat() {
    if (heartbeatInterval) { clearInterval(heartbeatInterval); heartbeatInterval = null; }
  }

  function scheduleReconnect() {
    if (reconnectTimer) clearTimeout(reconnectTimer);
    reconnectAttempts++;
    var delay = Math.min(1000 * Math.pow(2, reconnectAttempts), 30000);
    reconnectTimer = setTimeout(connect, delay);
  }

  // ─── State Management ─────────────────────────────────────────────────────

  function fetchState() {
    App.fetch('/api/domino.php?action=status&match_id=' + state.matchId).then(function(res) {
      if (res && res.ok && res.match) {
        handleUpdate(res.match);
      }
    }).catch(function() {});
  }

  function handleUpdate(matchData) {
    state.match = matchData;

    var players = JSON.parse(matchData.players || '[]');
    for (var i = 0; i < players.length; i++) {
      if (players[i].id === state.userId) { state.myIdx = i; break; }
    }

    var gameState = JSON.parse(matchData.game_state || '{}');
    var status = matchData.status;

    if (status === 'waiting') {
      renderWaiting(players, matchData);
      return;
    }

    // Hide waiting, show game
    var waitingEl = document.getElementById('domino-waiting');
    var gameEl = document.getElementById('domino-game-area');
    if (waitingEl) waitingEl.style.display = 'none';
    if (gameEl) gameEl.style.display = 'flex';

    renderGame(matchData, players, gameState);
  }

  function renderWaiting(players, matchData) {
    var waitingEl = document.getElementById('domino-waiting');
    var gameEl = document.getElementById('domino-game-area');
    if (waitingEl) waitingEl.style.display = 'block';
    if (gameEl) gameEl.style.display = 'none';

    var codeEl = document.getElementById('room-code-value');
    if (codeEl) codeEl.textContent = matchData.room_code;

    var listEl = document.getElementById('waiting-players');
    if (listEl) {
      var html = '';
      for (var i = 0; i < players.length; i++) {
        html += '<div class="domino-waiting-player"><span>' + players[i].name + '</span>';
        html += players[i].type === 'bot' ? '<span class="text-muted text-sm">بوت</span>' : '<span class="text-muted text-sm">لاعب</span>';
        html += '</div>';
      }
      var remaining = matchData.player_count - players.length;
      for (var r = 0; r < remaining; r++) {
        html += '<div class="domino-waiting-player domino-waiting-player--empty"><span class="text-muted">في انتظار لاعب...</span></div>';
      }
      listEl.innerHTML = html;
    }

    // Show start button only for host
    var startBtn = document.getElementById('start-game-btn');
    if (startBtn) {
      startBtn.style.display = (matchData.host_id === state.userId && players.length >= 2) ? 'block' : 'none';
    }
  }

  function renderGame(matchData, players, gameState) {
    var board = JSON.parse(matchData.board || '[]');
    var hands = JSON.parse(matchData.hands || '{}');
    var scores = JSON.parse(matchData.scores || '[]');
    var boneyard = JSON.parse(matchData.boneyard || '[]');
    var spinner = matchData.spinner ? JSON.parse(matchData.spinner) : null;
    var currentTurn = matchData.current_turn;
    var mode = matchData.mode;
    var targetScore = matchData.target_score;

    var myHand = hands[state.myIdx];
    var isMyTurn = (currentTurn === state.myIdx);
    var ends = DominoConstants.getPlayableEnds(board, spinner);

    // Render board
    DominoUI.renderBoard(board, spinner);

    // Render scores
    DominoUI.renderScores(scores, players, mode, targetScore);

    // Render my hand (if it's an array; server sends array for my hand, number for others)
    if (Array.isArray(myHand)) {
      DominoUI.renderHand(myHand, {
        isCurrentPlayer: isMyTurn,
        playableEnds: ends,
        boardEmpty: board.length === 0
      });
      DominoUI.renderEndButtons(ends, board.length === 0);
    }

    // Render opponents
    DominoUI.renderOpponentHands(hands, players, state.myIdx, players.length);

    // Boneyard
    var canDraw = isMyTurn && mode === '2p' && boneyard.length > 0 && Array.isArray(myHand) && !DominoConstants.canPlayerPlay(myHand, ends);
    DominoUI.renderBoneyard(boneyard.length, canDraw);

    // Actions
    var canPass = isMyTurn && mode === '4p_teams' && Array.isArray(myHand) && !DominoConstants.canPlayerPlay(myHand, ends);
    DominoUI.renderActions({ canPass: canPass });

    // Status
    if (matchData.status === 'completed') {
      DominoUI.renderStatus('انتهت المباراة!', 'warning');
      var roundHistory = JSON.parse(matchData.round_history || '[]');
      if (roundHistory.length > 0) {
        var lastRound = roundHistory[roundHistory.length - 1];
        var winnerName = lastRound.winner_idx !== null ? players[lastRound.winner_idx].name : 'تعادل';
        DominoUI.showRoundOverlay({
          round: matchData.round_number,
          type: lastRound.type || 'domino',
          winnerName: winnerName,
          score: lastRound.score || 0,
          matchOver: true
        });
      }
    } else if (isMyTurn) {
      DominoUI.renderStatus('دورك — اختر قطعة', 'success');
    } else {
      DominoUI.renderStatus('دور ' + players[currentTurn].name, 'info');
    }
  }

  // ─── Player Actions ───────────────────────────────────────────────────────

  function sendPlay(tileId, side) {
    App.fetch('/api/domino.php', {
      method: 'POST',
      body: JSON.stringify({
        action: 'play',
        match_id: state.matchId,
        tile_id: tileId,
        side: side === 'any' ? getFirstAvailableSide() : side
      })
    }).then(function(res) {
      if (res && res.ok) {
        handleUpdate(res.match);
      } else if (res && res.error) {
        App.toast(res.error, 'error');
      }
    }).catch(function() { App.toast('خطأ في الاتصال', 'error'); });
  }

  function sendDraw() {
    App.fetch('/api/domino.php', {
      method: 'POST',
      body: JSON.stringify({ action: 'draw', match_id: state.matchId })
    }).then(function(res) {
      if (res && res.ok) {
        handleUpdate(res.match);
      } else if (res && res.error) {
        App.toast(res.error, 'error');
      }
    }).catch(function() { App.toast('خطأ في الاتصال', 'error'); });
  }

  function sendPass() {
    App.fetch('/api/domino.php', {
      method: 'POST',
      body: JSON.stringify({ action: 'pass', match_id: state.matchId })
    }).then(function(res) {
      if (res && res.ok) {
        handleUpdate(res.match);
      } else if (res && res.error) {
        App.toast(res.error, 'error');
      }
    }).catch(function() { App.toast('خطأ في الاتصال', 'error'); });
  }

  function getFirstAvailableSide() {
    if (!state.match) return 'east';
    var board = JSON.parse(state.match.board || '[]');
    var spinner = state.match.spinner ? JSON.parse(state.match.spinner) : null;
    var ends = DominoConstants.getPlayableEnds(board, spinner);
    for (var side in ends) return side;
    return 'east';
  }

  // ─── Room Actions ─────────────────────────────────────────────────────────

  function startGame() {
    App.fetch('/api/domino.php', {
      method: 'POST',
      body: JSON.stringify({ action: 'start', match_id: state.matchId })
    }).then(function(res) {
      if (res && res.ok) handleUpdate(res.match);
      else if (res && res.error) App.toast(res.error, 'error');
    });
  }

  function leaveGame() {
    App.fetch('/api/domino.php', {
      method: 'POST',
      body: JSON.stringify({ action: 'leave', match_id: state.matchId })
    }).then(function() {
      window.location.href = '/domino';
    });
  }

  function sendChat(text) {
    App.fetch('/api/domino.php', {
      method: 'POST',
      body: JSON.stringify({ action: 'chat', match_id: state.matchId, text: text })
    });
  }

  return {
    init: init,
    startGame: startGame,
    leaveGame: leaveGame,
    sendChat: sendChat
  };
})();
