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

  var C = BackgammonConstants;
  var UI = BackgammonUI;

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

  var token = null;
  var user = null;
  var matchId = null;
  var ws = null;
  var heartbeatTimer = null;
  var heartbeatRef = 0;
  var myPlayerIdx = -1;
  var topic = null;
  var reconnectAttempts = 0;

  function init(opts) {
    token = localStorage.getItem('el3ab_token');
    user = JSON.parse(localStorage.getItem('el3ab_user') || 'null');
    if (!token || !user) { window.location.href = '/login'; return; }

    if (opts.matchId) {
      matchId = opts.matchId;
      connectAndJoin();
    } else if (opts.action === 'create') {
      createRoom();
    } else if (opts.action === 'join' && opts.code) {
      joinRoom(opts.code);
    }
  }

  function apiCall(body) {
    return fetch('/api/backgammon.php', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token },
      body: JSON.stringify(body)
    }).then(function(r) { return r.json(); });
  }

  function createRoom() {
    apiCall({ action: 'create' }).then(function(data) {
      if (data.error) { alert(data.error); return; }
      matchId = data.match_id;
      showWaiting(data.room_code);
      connectAndJoin();
    });
  }

  function joinRoom(code) {
    apiCall({ action: 'join', room_code: code }).then(function(data) {
      if (data.error) { alert(data.error); return; }
      matchId = data.match_id;
      connectAndJoin();
    });
  }

  function showWaiting(code) {
    var codeEl = document.getElementById('bg-room-code');
    var msgEl = document.getElementById('bg-waiting-msg');
    if (codeEl) codeEl.textContent = code || '------';
    if (msgEl) msgEl.textContent = 'في انتظار اللاعب الآخر...';
  }

  function connectAndJoin() {
    topic = 'realtime:public:backgammon_matches:id=eq.' + matchId;

    ws = new WebSocket(WS_URL + '?apikey=' + ANON_KEY + '&vsn=1.0.0');

    ws.onopen = function() {
      reconnectAttempts = 0;
      startHeartbeat();
      joinChannel();
      fetchStatus();
    };

    ws.onmessage = function(evt) {
      var msg = JSON.parse(evt.data);
      if (msg.event === 'postgres_changes') {
        var record = msg.payload && msg.payload.data && msg.payload.data.record;
        if (record) handleUpdate(record);
      }
    };

    ws.onclose = function() {
      stopHeartbeat();
      if (reconnectAttempts < 10) {
        var delay = Math.min(1000 * Math.pow(2, reconnectAttempts), 30000);
        reconnectAttempts++;
        setTimeout(connectAndJoin, delay);
      }
    };

    ws.onerror = function() { ws.close(); };
  }

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

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

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

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

  function fetchStatus() {
    fetch('/api/backgammon.php?action=status&match_id=' + matchId, {
      headers: { 'Authorization': 'Bearer ' + token }
    }).then(function(r) { return r.json(); }).then(function(data) {
      if (data.match) handleUpdate(data.match);
    });
  }

  function handleUpdate(match) {
    var players = typeof match.players === 'string' ? JSON.parse(match.players) : match.players;
    var board = typeof match.board === 'string' ? JSON.parse(match.board) : match.board;
    var bar = typeof match.bar === 'string' ? JSON.parse(match.bar) : match.bar;
    var borneOff = typeof match.borne_off === 'string' ? JSON.parse(match.borne_off) : match.borne_off;
    var dice = match.dice ? (typeof match.dice === 'string' ? JSON.parse(match.dice) : match.dice) : null;
    var diceRemaining = typeof match.dice_remaining === 'string' ? JSON.parse(match.dice_remaining) : (match.dice_remaining || []);
    var gameState = typeof match.game_state === 'string' ? JSON.parse(match.game_state) : (match.game_state || {});
    var scores = typeof match.scores === 'string' ? JSON.parse(match.scores) : (match.scores || [0,0]);

    myPlayerIdx = -1;
    for (var i = 0; i < players.length; i++) {
      if (players[i].id === user.id) { myPlayerIdx = i; break; }
    }

    if (match.status === 'waiting') {
      showWaiting(match.room_code);
      var countEl = document.getElementById('bg-players-count');
      if (countEl) countEl.textContent = players.length + ' / 2 لاعبين';

      var startBtn = document.getElementById('bg-start-btn');
      if (startBtn && players.length >= 2 && match.host_id === user.id) {
        startBtn.style.display = '';
        startBtn.onclick = function() {
          apiCall({ action: 'start', match_id: matchId });
        };
      }
      return;
    }

    if (match.status === 'in_progress' || match.status === 'completed') {
      document.getElementById('bg-waiting').style.display = 'none';
      document.getElementById('bg-game-area').style.display = '';

      var state = {
        players: players,
        board: board,
        bar: bar,
        borneOff: borneOff,
        currentTurn: match.current_turn,
        dice: dice,
        diceRemaining: diceRemaining,
        phase: gameState.phase || 'awaiting_roll',
        scores: scores,
        doublingCube: typeof match.doubling_cube === 'string' ? JSON.parse(match.doubling_cube) : (match.doubling_cube || {value:1,owner:null}),
        matchLength: match.match_length || 1
      };

      if (!UI.getSelected) UI.init(state);
      UI.render(state);

      var nameEl0 = document.getElementById('bg-name-0');
      var nameEl1 = document.getElementById('bg-name-1');
      if (nameEl0 && players[0]) nameEl0.textContent = players[0].name;
      if (nameEl1 && players[1]) nameEl1.textContent = players[1].name;

      setupControls(state);

      if (match.status === 'completed' && gameState.winner !== undefined) {
        var winType = gameState.win_type || 'normal';
        var pts = gameState.points_awarded || 1;
        UI.showResult(players[gameState.winner].name, winType, pts);
      }
    }
  }

  function setupControls(state) {
    var rollBtn = document.getElementById('bg-roll-btn');
    if (!rollBtn) return;

    var isMyTurn = state.currentTurn === myPlayerIdx;
    var canRoll = isMyTurn && state.phase === 'awaiting_roll';

    rollBtn.style.display = canRoll ? '' : 'none';
    rollBtn.onclick = function() {
      apiCall({ action: 'roll', match_id: matchId });
    };

    var board = document.getElementById('bg-board');
    if (board && isMyTurn && state.phase === 'moving') {
      board.onclick = function(e) {
        var point = e.target.closest('[data-point]');
        var action = e.target.closest('[data-action]');
        var from = point ? parseInt(point.dataset.point) : (action ? action.dataset.action : null);
        if (from === null) return;

        var sel = UI.getSelected();
        if (sel === null) {
          UI.setSelected(from);
          UI.render(state);
        } else {
          var to = from;
          apiCall({ action: 'move', match_id: matchId, from: sel, to: to }).then(function(data) {
            if (data.error) { UI.showLog(data.error); }
            UI.clearSelected();
            UI.clearHighlights();
          });
        }
      };
    }
  }

  return { init: init };
})();
