(function () {
  const fileInput = document.getElementById('fileInput');
  const preview = document.getElementById('preview');
  const previewPlaceholder = document.getElementById('previewPlaceholder');
  const statusFile = document.getElementById('statusFile');
  const statusPlotter = document.getElementById('statusPlotter');
  const printMessage = document.getElementById('printMessage');
  const scaleDims = document.getElementById('scaleDims');
  const plotterInfo = {
    port: document.getElementById('plotterPort'),
    baud: document.getElementById('plotterBaud'),
    winsizeUnits: document.getElementById('plotterWinsizeUnits'),
    winsizeMm: document.getElementById('plotterWinsizeMm'),
    bounds: document.getElementById('plotterBounds')
  };
  const buttons = {
    flip: document.getElementById('btnFlip'),
    rotate90: document.getElementById('btnRotate90'),
    rotate180: document.getElementById('btnRotate180'),
    scaleUp: document.getElementById('btnScaleUp'),
    scaleDown: document.getElementById('btnScaleDown'),
    centralize: document.getElementById('btnCentralize'),
    scaleToBounds: document.getElementById('btnScaleToBounds'),
    print: document.getElementById('btnPrint'),
    checkPlotter: document.getElementById('btnCheckPlotter')
  };

  function setMessage(el, text, type) {
    el.textContent = text || '';
    el.className = 'message' + (type ? ' ' + type : '');
  }

  function updatePreview() {
    const w = Math.min(800, window.innerWidth - 80);
    const h = Math.min(600, window.innerHeight - 120);
    preview.src = '/api/svg?width=' + w + '&height=' + h + '&scale=1&_=' + Date.now();
  }

  function updateDimensions() {
    if (!scaleDims) return;
    fetch('/api/dimensions')
      .then(function (r) {
        if (!r.ok) throw new Error();
        return r.json();
      })
      .then(function (d) {
        scaleDims.innerHTML = d.width + ' × ' + d.height + ' <span class="unit">(≈ ' + d.width_mm + ' × ' + d.height_mm + ' mm)</span>';
      })
      .catch(function () {
        scaleDims.innerHTML = '— × — <span class="unit">(≈ — × — mm)</span>';
      });
  }

  function updatePlotterInfo() {
    if (!plotterInfo.port) return;
    fetch('/api/plotter_info')
      .then(function (r) { return r.ok ? r.json() : Promise.reject(); })
      .then(function (d) {
        plotterInfo.port.textContent = d.port || '—';
        plotterInfo.baud.textContent = d.baudrate ? d.baudrate + ' baud' : '—';
        if (d.winsize_units) {
          plotterInfo.winsizeUnits.textContent = d.winsize_units.width + ' × ' + d.winsize_units.height;
        } else {
          plotterInfo.winsizeUnits.textContent = '— × —';
        }
        if (d.winsize_mm) {
          plotterInfo.winsizeMm.textContent = d.winsize_mm.width + ' × ' + d.winsize_mm.height + ' mm';
        } else {
          plotterInfo.winsizeMm.textContent = '— × —';
        }
        if (d.boundaries) {
          var b = d.boundaries;
          plotterInfo.bounds.textContent = b.xmin + ',' + b.ymin + ' … ' + b.xmax + ',' + b.ymax;
        } else {
          plotterInfo.bounds.textContent = '—';
        }
      })
      .catch(function () {
        plotterInfo.port.textContent = '—';
        plotterInfo.baud.textContent = '—';
        plotterInfo.winsizeUnits.textContent = '— × —';
        plotterInfo.winsizeMm.textContent = '— × —';
        plotterInfo.bounds.textContent = '—';
      });
  }

  function setLoaded(loaded) {
    if (loaded) {
      preview.classList.add('loaded');
      previewPlaceholder.classList.add('hidden');
      Object.keys(buttons).forEach(function (k) {
        var b = buttons[k];
        if (b) b.disabled = false;
      });
    } else {
      preview.classList.remove('loaded');
      previewPlaceholder.classList.remove('hidden');
      preview.src = '';
      Object.keys(buttons).forEach(function (k) {
        var b = buttons[k];
        if (b) b.disabled = true;
      });
    }
  }

  function refreshStatus() {
    fetch('/api/status')
      .then(function (r) { return r.json(); })
      .then(function (data) {
        statusFile.textContent = data.has_file ? (data.filename || 'File loaded') : 'No file';
        statusPlotter.textContent = 'Plotter: ' + (data.plotter_ready ? 'Ready' : 'Not connected');
        statusPlotter.classList.toggle('ready', data.plotter_ready);
        statusPlotter.classList.toggle('not-ready', !data.plotter_ready);
        updatePlotterInfo();
        if (data.has_file) {
          setLoaded(true);
          updatePreview();
          updateDimensions();
        } else {
          setLoaded(false);
          if (scaleDims) scaleDims.innerHTML = '— × — <span class="unit">(≈ — × — mm)</span>';
        }
      })
      .catch(function () {
        statusFile.textContent = 'No file';
        statusPlotter.textContent = 'Plotter: —';
        setLoaded(false);
        if (scaleDims) scaleDims.innerHTML = '— × — <span class="unit">(≈ — × — mm)</span>';
      });
  }

  fileInput.addEventListener('change', function () {
    const file = this.files && this.files[0];
    if (!file) return;
    preview.src = '';
    preview.classList.remove('loaded');
    previewPlaceholder.classList.remove('hidden');
    previewPlaceholder.textContent = 'Loading…';
    setMessage(printMessage, '');
    const form = new FormData();
    form.append('file', file);
    fetch('/api/upload', {
      method: 'POST',
      body: form
    })
      .then(function (r) {
        if (!r.ok) return r.json().then(function (d) { throw new Error(d.error || 'Upload failed'); });
        return r.json();
      })
      .then(function () {
        previewPlaceholder.textContent = 'Upload an HPGL file to preview';
        refreshStatus();
      })
      .catch(function (e) {
        previewPlaceholder.textContent = 'Upload an HPGL file to preview';
        setMessage(printMessage, e.message || 'Upload failed', 'error');
        refreshStatus();
      });
  });

  function transform(action, payload) {
    setMessage(printMessage, '');
    var body = payload || { action: action };
    fetch('/api/transform', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(body)
    })
      .then(function (r) {
        if (!r.ok) return r.json().then(function (d) { throw new Error(d.error || 'Transform failed'); });
        return r.json();
      })
      .then(function () {
        updatePreview();
        updateDimensions();
      })
      .catch(function (e) {
        setMessage(printMessage, e.message || 'Transform failed', 'error');
      });
  }

  buttons.flip.addEventListener('click', function () { transform('flip'); });
  buttons.rotate90.addEventListener('click', function () { transform('rotate', { action: 'rotate', angle: 90 }); });
  buttons.rotate180.addEventListener('click', function () { transform('rotate', { action: 'rotate', angle: 180 }); });
  buttons.scaleUp.addEventListener('click', function () { transform('scale', { action: 'scale', factor: 1.25 }); });
  buttons.scaleDown.addEventListener('click', function () { transform('scale', { action: 'scale', factor: 0.8 }); });
  buttons.centralize.addEventListener('click', function () { transform('centralize'); });
  if (buttons.scaleToBounds) {
    buttons.scaleToBounds.addEventListener('click', function () {
      setMessage(printMessage, '');
      fetch('/api/status')
        .then(function (r) { return r.json(); })
        .then(function (data) {
          if (!data.plotter_ready) {
            setMessage(printMessage, 'Plotter not connected.', 'error');
            return;
          }
          transform('scale_to_bounds', { action: 'scale_to_bounds' });
        })
        .catch(function () {
          setMessage(printMessage, 'Plotter not connected.', 'error');
        });
    });
  }

  buttons.print.addEventListener('click', function () {
    setMessage(printMessage, 'Sending to plotter…');
    fetch('/api/print', { method: 'POST' })
      .then(function (r) {
        return r.json().then(function (data) {
          if (!r.ok) throw new Error(data.error || 'Print failed');
          return data;
        });
      })
      .then(function () {
        setMessage(printMessage, 'Sent to plotter.', 'success');
      })
      .catch(function (e) {
        setMessage(printMessage, e.message || 'Print failed', 'error');
      });
  });

  if (buttons.checkPlotter) {
    buttons.checkPlotter.addEventListener('click', function () {
      setMessage(printMessage, 'Checking plotter…');
      fetch('/api/status')
        .then(function (r) { return r.json(); })
        .then(function (data) {
          statusFile.textContent = data.has_file ? (data.filename || 'File loaded') : 'No file';
          statusPlotter.textContent = 'Plotter: ' + (data.plotter_ready ? 'Ready' : 'Not connected');
          statusPlotter.classList.toggle('ready', data.plotter_ready);
          statusPlotter.classList.toggle('not-ready', !data.plotter_ready);
          updatePlotterInfo();
          setMessage(printMessage, data.plotter_ready ? 'Plotter: Ready' : 'Plotter: Not connected', data.plotter_ready ? 'success' : 'error');
        })
        .catch(function () {
          statusPlotter.textContent = 'Plotter: —';
          statusPlotter.classList.remove('ready');
          statusPlotter.classList.add('not-ready');
          updatePlotterInfo();
          setMessage(printMessage, 'Plotter: Not connected', 'error');
        });
    });
  }

  preview.addEventListener('load', function () {
    previewPlaceholder.classList.add('hidden');
  });

  refreshStatus();
  updatePlotterInfo();
  setInterval(updatePlotterInfo, 10000);
})();
