(function () {
  'use strict';
  var base = document.body.getAttribute('data-base-path') || '';

  function buildStatusIconHtml(status) {
    var s = String(status || '').toLowerCase();
    if (s === 'running' || s === 'queued') {
      return '<span class="build-status-icon build-status-icon--running" role="img" aria-label="In progress">'
        + '<span class="build-status-spinner"></span></span>';
    }
    if (s === 'passed') {
      return '<span class="build-status-icon build-status-icon--passed" role="img" aria-label="Succeeded"></span>';
    }
    return '<span class="build-status-icon build-status-icon--failed" role="img" aria-label="Failed or cancelled">'
      + '<span class="build-status-fail-mark" aria-hidden="true">!</span></span>';
  }

  function updateBuildStatusCell(cell, status, phase) {
    if (!cell) return;
    var icon = cell.querySelector('.build-status-icon');
    var label = cell.querySelector('.build-status-label');
    var html = buildStatusIconHtml(status);
    if (icon) {
      icon.outerHTML = html;
    } else {
      cell.insertAdjacentHTML('afterbegin', html);
    }
    if (label) {
      label.textContent = status || '';
    }
    if (phase !== undefined) {
      var row = cell.closest('tr');
      if (row) {
        var phaseCell = row.querySelector('.build-phase-cell');
        if (phaseCell) {
          phaseCell.textContent = phase || '';
        }
      }
    }
  }

  function updateBuildRow(row, build) {
    if (!row || !build) return;
    row.setAttribute('data-build-status', build.status || '');
    var cell = row.querySelector('[data-build-status-cell="' + build.id + '"]');
    updateBuildStatusCell(cell, build.status, build.phase);
    var play = row.querySelector('.build-transport-play');
    var stop = row.querySelector('.build-transport-stop');
    var active = build.status === 'running' || build.status === 'queued';
    if (play) {
      play.setAttribute('data-build-status', build.status || '');
    }
    if (stop) {
      stop.setAttribute('data-build-status', build.status || '');
      stop.disabled = !active;
    }
  }

  function refreshRecentBuilds() {
    var tbody = document.getElementById('builds-recent-tbody');
    if (!tbody) return;
    var xhr = new XMLHttpRequest();
    xhr.open('GET', base + '/api/builds.php', true);
    xhr.onload = function () {
      var j = null;
      try { j = JSON.parse(xhr.responseText); } catch (e) { j = null; }
      if (!j || !j.ok || !j.builds) return;
      j.builds.forEach(function (b) {
        var row = tbody.querySelector('tr[data-build-id="' + b.id + '"]');
        updateBuildRow(row, b);
      });
    };
    xhr.send();
    setTimeout(refreshRecentBuilds, 1000);
  }

  function bindBuildListTransport() {
    var tbody = document.getElementById('builds-recent-tbody');
    if (!tbody) return;
    tbody.addEventListener('click', function (ev) {
      var play = ev.target.closest('.build-transport-play');
      var stop = ev.target.closest('.build-transport-stop');
      if (play) {
        var pid = Number(play.getAttribute('data-build-id'));
        var pst = play.getAttribute('data-build-status') || '';
        if (!pid) return;
        var msg = pst === 'running' || pst === 'queued'
          ? 'Force re-run? This stops the current run and starts a new build with the same parameters.'
          : null;
        if (msg && !confirm(msg)) return;
        postBuildAction({ action: 'force_rerun', build_id: pid }).then(function (j) {
          if (j.build && j.build.id) {
            window.location.href = base + '/?view=build&id=' + j.build.id;
          }
        }).catch(function (err) {
          alert(err.message || 'Re-run failed');
        });
        return;
      }
      if (stop) {
        var sid = Number(stop.getAttribute('data-build-id'));
        if (!sid || stop.disabled) return;
        if (!confirm('Stop this build now?')) return;
        postBuildAction({ action: 'stop', build_id: sid }).then(function () {
          refreshRecentBuilds();
        }).catch(function (err) {
          alert(err.message || 'Stop failed');
        });
      }
    });
  }

  if (document.body.getAttribute('data-view') === 'home' && document.getElementById('builds-recent-tbody')) {
    bindBuildListTransport();
    refreshRecentBuilds();
  }

  var themeSel = document.getElementById('theme-select');
  if (themeSel) {
    var cur = localStorage.getItem('crash_console_theme') || 'dark';
    themeSel.value = cur;
    themeSel.addEventListener('change', function () {
      document.documentElement.setAttribute('data-theme', themeSel.value);
      localStorage.setItem('crash_console_theme', themeSel.value);
    });
  }

  var form = document.getElementById('build-trigger-form');
  if (form) {
    form.addEventListener('submit', function (ev) {
      ev.preventDefault();
      var status = document.getElementById('build-trigger-status');
      var fd = new FormData(form);
      var payload = {
        git_ref: fd.get('git_ref') || 'next',
        gradle_task: fd.get('gradle_task') || 'assembleDebug',
        ota_channel: fd.get('ota_channel') || 'staging',
        run_tests: !!form.querySelector('[name=run_tests]').checked,
        run_native: !!form.querySelector('[name=run_native]').checked,
        run_apk: !!form.querySelector('[name=run_apk]').checked,
        auto_ota: !!form.querySelector('[name=auto_ota]').checked,
        auto_deploy: !!form.querySelector('[name=auto_deploy]').checked
      };
      status.textContent = 'Starting…';
      fetch(base + '/api/build_trigger.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        credentials: 'same-origin',
        body: JSON.stringify(payload)
      }).then(function (r) {
        return r.text().then(function (text) {
          var j = null;
          try {
            j = JSON.parse(text);
          } catch (e) {
            throw new Error(r.status + ': ' + (text.slice(0, 120) || r.statusText));
          }
          if (!r.ok) {
            throw new Error((j && j.error) || ('HTTP ' + r.status));
          }
          return j;
        });
      }).then(function (j) {
        if (j.ok && j.build && j.build.id) {
          window.location.href = base + '/?view=build&id=' + j.build.id;
        } else {
          status.textContent = j.error || 'Failed';
        }
      }).catch(function (err) {
        status.textContent = err && err.message ? err.message : 'Network error';
      });
    });
  }

  function postBuildAction(payload) {
    return fetch(base + '/api/build_actions.php', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      credentials: 'same-origin',
      body: JSON.stringify(payload)
    }).then(function (r) {
      return r.text().then(function (text) {
        var j = null;
        try { j = JSON.parse(text); } catch (e) {
          throw new Error(r.status + ': ' + (text.slice(0, 120) || r.statusText));
        }
        if (!r.ok || !j.ok) {
          throw new Error((j && j.error) || ('HTTP ' + r.status));
        }
        return j;
      });
    });
  }

  var rerunBtn = document.getElementById('build-rerun-btn');
  var rerunFailedBtn = document.getElementById('build-rerun-failed-btn');
  var rerunSshBtn = document.getElementById('build-rerun-ssh-btn');
  var stopBtn = document.getElementById('build-stop-btn');
  var rerunAsToggle = document.getElementById('build-rerun-as-toggle');
  var rerunAsForm = document.getElementById('build-rerun-as-form');
  var actionStatus = document.getElementById('build-action-status');

  function goToBuild(j) {
    if (j.build && j.build.id) {
      window.location.href = base + '/?view=build&id=' + j.build.id;
    }
  }

  function bindRerunAction(btn, action, confirmMsg) {
    if (!btn) return;
    btn.addEventListener('click', function () {
      var id = Number(btn.getAttribute('data-build-id'));
      if (!id) return;
      if (confirmMsg && !confirm(confirmMsg)) return;
      if (actionStatus) actionStatus.textContent = 'Starting…';
      postBuildAction({ action: action, build_id: id }).then(goToBuild).catch(function (err) {
        if (actionStatus) actionStatus.textContent = err.message || 'Failed';
      });
    });
  }
  if (rerunAsToggle && rerunAsForm) {
    rerunAsToggle.addEventListener('click', function () {
      rerunAsForm.hidden = !rerunAsForm.hidden;
    });
  }
  bindRerunAction(rerunBtn, 'rerun', null);
  bindRerunAction(rerunFailedBtn, 'rerun_from_failed', null);
  bindRerunAction(
    rerunSshBtn,
    'rerun_with_ssh',
    'Start an SSH debug session on the builder? You will need shell access to the builder host.'
  );
  if (stopBtn) {
    stopBtn.addEventListener('click', function () {
      var id = Number(stopBtn.getAttribute('data-build-id'));
      if (!id || !confirm('Stop this build?')) return;
      if (actionStatus) actionStatus.textContent = 'Stopping…';
      postBuildAction({ action: 'stop', build_id: id }).then(function () {
        window.location.reload();
      }).catch(function (err) {
        if (actionStatus) actionStatus.textContent = err.message || 'Failed';
      });
    });
  }
  if (rerunAsForm) {
    rerunAsForm.addEventListener('submit', function (ev) {
      ev.preventDefault();
      var id = Number(rerunBtn && rerunBtn.getAttribute('data-build-id'));
      if (!id) return;
      var fd = new FormData(rerunAsForm);
      var params = {
        git_ref: fd.get('git_ref') || 'next',
        gradle_task: fd.get('gradle_task') || 'assembleDebug',
        ota_channel: fd.get('ota_channel') || 'staging',
        run_tests: !!rerunAsForm.querySelector('[name=run_tests]').checked,
        run_native: !!rerunAsForm.querySelector('[name=run_native]').checked,
        run_apk: !!rerunAsForm.querySelector('[name=run_apk]').checked,
        auto_ota: !!rerunAsForm.querySelector('[name=auto_ota]').checked,
        auto_deploy: !!rerunAsForm.querySelector('[name=auto_deploy]').checked
      };
      if (actionStatus) actionStatus.textContent = 'Starting…';
      postBuildAction({ action: 'rerun_as', build_id: id, params: params }).then(function (j) {
        if (j.build && j.build.id) {
          window.location.href = base + '/?view=build&id=' + j.build.id;
        }
      }).catch(function (err) {
        if (actionStatus) actionStatus.textContent = err.message || 'Failed';
      });
    });
  }

  var buildId = document.body.getAttribute('data-build-id');
  var buildStatus = document.body.getAttribute('data-build-status') || '';
  var logEl = document.getElementById('build-log-tail');
  if (buildId && logEl) {
    var offset = 0;
    var full = '';
    var showFull = false;
    var DISPLAY_TAIL = 50000;

    function renderLog() {
      logEl.textContent = showFull ? full : full.slice(-DISPLAY_TAIL);
      logEl.scrollTop = logEl.scrollHeight;
    }

    function poll() {
      var url = base + '/api/build_log.php?id=' + encodeURIComponent(buildId) + '&offset=' + offset;
      fetch(url)
        .then(function (r) { return r.json(); })
        .then(function (j) {
          if (!j.ok) return;
          if (j.log && j.log.text) {
            full += j.log.text;
            offset = j.log.offset || offset;
            renderLog();
          }
          if (j.build) {
            var iconEl = document.getElementById('build-status-icon');
            var textEl = document.getElementById('build-status-text');
            if (iconEl) {
              iconEl.innerHTML = buildStatusIconHtml(j.build.status);
            }
            if (textEl) {
              var errEl = document.getElementById('build-error-message');
              var err = j.build.error_message ? (' · <span class="error-text" id="build-error-message">'
                + String(j.build.error_message).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
                + '</span>') : '';
              textEl.innerHTML = 'Status: <strong>' + (j.build.status || '') + '</strong> · Phase: '
                + (j.build.phase || '') + err;
            }
            document.body.setAttribute('data-build-status', j.build.status || '');
          }
          var running = j.build && j.build.status === 'running';
          var eof = j.log && j.log.eof;
          if (running || !eof) {
            setTimeout(poll, running ? 1000 : 250);
          } else if (j.build && j.build.phase === 'ssh_debug' && !document.getElementById('build-ssh-panel')) {
            window.location.reload();
          }
        }).catch(function () { setTimeout(poll, 2000); });
    }

    function loadFullLog() {
      return fetch(base + '/api/build_log.php?id=' + encodeURIComponent(buildId) + '&full=1')
        .then(function (r) { return r.json(); })
        .then(function (j) {
          if (j.ok && j.log && j.log.text) {
            full = j.log.text;
            offset = j.log.offset || 0;
            renderLog();
          }
        });
    }

    if (buildStatus && buildStatus !== 'running' && buildStatus !== 'queued') {
      loadFullLog().catch(function () { poll(); });
    } else {
      poll();
    }

    var expand = document.getElementById('build-log-expand');
    if (expand) {
      expand.addEventListener('click', function () {
        showFull = true;
        if (full === '') {
          loadFullLog().then(function () { renderLog(); });
        } else {
          renderLog();
        }
        expand.textContent = 'Showing full log';
        expand.disabled = true;
      });
    }
  }
})();
