(function (global) {
  global.ARQ = global.ARQ || {};
  var innerEl = null;
  var canvas = null;
  /** Tras soltar zoom/rotación, no dibujar hasta pasado este tiempo (ms). */
  var settleUntil = 0;
  var SETTLE_MS = 150;

  ARQ.viewport = {
    init: function (opts) {
      innerEl = opts.innerEl;
      canvas = opts.canvas;
    },
    /** Tras gesto de vista (pinch/rotar), evita trazos hasta que “asiente”. */
    scheduleViewportSettle: function () {
      settleUntil = Date.now() + SETTLE_MS;
    },
    /** No dibujar: gesto de dos dedos o periodo de asentamiento tras mover la vista. */
    isViewportBlockingDraw: function () {
      if (global.ARQ._twoFingerNav) return true;
      if (Date.now() < settleUntil) return true;
      return false;
    },
    syncFromSheet: function (sheet) {
      if (!sheet) return;
      sheet.pan_actual = sheet.pan_actual || { x: 0, y: 0 };
      sheet.zoom_actual = sheet.zoom_actual || 1;
      sheet.rotacion_actual = sheet.rotacion_actual || 0;
      this.applyFromSheet(sheet);
    },
    applyFromSheet: function (sheet) {
      if (!innerEl || !sheet) return;
      var p = sheet.pan_actual || { x: 0, y: 0 };
      var s = sheet.zoom_actual || 1;
      var r = sheet.rotacion_actual || 0;
      innerEl.style.transform =
        'translate(calc(-50% + ' + p.x + 'px), calc(-50% + ' + p.y + 'px)) scale(' + s + ') rotate(' + r + 'deg)';
    },
    writeToSheet: function (sheet, pan, zoom, rot) {
      if (!sheet) return;
      sheet.pan_actual = pan || sheet.pan_actual || { x: 0, y: 0 };
      if (zoom != null) sheet.zoom_actual = zoom;
      if (rot != null) sheet.rotacion_actual = rot;
    },
    /**
     * Pantalla → coordenadas de hoja (canvas interno).
     * Modelo: el centro del lienzo sigue al centro del padre + pan, luego scale(s) y rotate(r)
     * alrededor del centro (mismo criterio que translate(-50%+pan) scale rotate).
     * No usar el rect del canvas (AABB) ni offsetLeft: fallan con flex/rotación.
     */
    screenToSheet: function (clientX, clientY) {
      if (!canvas) return { x: 0, y: 0 };
      var project = ARQ.store && ARQ.store.getProject ? ARQ.store.getProject() : null;
      var sheet = project && ARQ.utils && ARQ.utils.activeSheet ? ARQ.utils.activeSheet(project) : null;
      if (!sheet) {
        var rect0 = canvas.getBoundingClientRect();
        var cw = canvas.width || 1;
        var ch = canvas.height || 1;
        return {
          x: (clientX - rect0.left) / (rect0.width || 1) * cw,
          y: (clientY - rect0.top) / (rect0.height || 1) * ch,
        };
      }
      var w = canvas.width;
      var h = canvas.height;
      var pan = sheet.pan_actual || { x: 0, y: 0 };
      var s = sheet.zoom_actual || 1;
      if (Math.abs(s) < 1e-9) s = 1;
      var rDeg = sheet.rotacion_actual || 0;
      var rad = (rDeg * Math.PI) / 180;
      var cos = Math.cos(-rad);
      var sin = Math.sin(-rad);

      function fallbackRectMap() {
        var rect = canvas.getBoundingClientRect();
        return {
          x: (clientX - rect.left) / (rect.width || 1) * w,
          y: (clientY - rect.top) / (rect.height || 1) * h,
        };
      }

      var parent = innerEl && innerEl.parentElement;
      if (!parent) return fallbackRectMap();

      var pr = parent.getBoundingClientRect();
      var cx = pr.left + pr.width / 2;
      var cy = pr.top + pr.height / 2;
      var dx = clientX - cx - pan.x;
      var dy = clientY - cy - pan.y;
      var lx = cos * dx - sin * dy;
      var ly = sin * dx + cos * dy;
      lx /= s;
      ly /= s;
      return { x: w / 2 + lx, y: h / 2 + ly };
    },
    fitToView: function (sheet, stageW, stageH) {
      if (!sheet || !canvas) return;
      if (!stageW || !stageH || stageW < 40 || stageH < 40) return;
      var sw = sheet.ancho || 1920;
      var sh = sheet.alto || 1080;
      var pad = 40;
      var zx = (stageW - pad * 2) / sw;
      var zy = (stageH - pad * 2) / sh;
      var z = Math.min(zx, zy, 2);
      if (z < 0.05) z = 0.05;
      sheet.zoom_actual = z;
      sheet.pan_actual = { x: 0, y: 0 };
      sheet.rotacion_actual = 0;
      this.applyFromSheet(sheet);
    },
    resetView: function (sheet) {
      if (!sheet) return;
      sheet.zoom_actual = 1;
      sheet.pan_actual = { x: 0, y: 0 };
      sheet.rotacion_actual = 0;
      this.applyFromSheet(sheet);
    },
  };
})(typeof window !== 'undefined' ? window : this);
