(function (global) {
  global.ARQ = global.ARQ || {};
  var HANDLE = 14;
  var ROT_HANDLE = 12;

  function centroid(pts) {
    var x = 0, y = 0, n = pts.length;
    for (var i = 0; i < n; i++) { x += pts[i].x; y += pts[i].y; }
    return { x: x / n, y: y / n };
  }

  function dist2(a, b) {
    var dx = a.x - b.x, dy = a.y - b.y;
    return dx * dx + dy * dy;
  }

  ARQ.transform = {
    active: false,
    layerId: null,

    isActive: function () {
      return this.active && !!this.layerId;
    },

    activate: function (layerId) {
      this.active = true;
      this.layerId = layerId;
    },

    deactivate: function () {
      this.active = false;
      this.layerId = null;
    },

    toggleForActiveLayer: function () {
      var layer = ARQ.store.activeLayer();
      if (!layer || !layer.contenido || !layer.contenido.imageSrc) {
        ARQ.bus.emit(ARQ.EVENTS.TOAST, 'Selecciona una capa con imagen o PDF');
        return;
      }
      if (!ARQ.guards.canDrawOnLayer(layer)) {
        ARQ.bus.emit(ARQ.EVENTS.TOAST, 'Desbloquea y muestra la capa para transformar');
        return;
      }
      if (this.active && this.layerId === layer.id) {
        this.deactivate();
      } else {
        this.activate(layer.id);
        this.ensureQuadCorners(layer);
      }
      ARQ.canvasEngine.redraw();
    },

    ensureQuadCorners: function (layer) {
      var cont = layer.contenido || {};
      var tr = cont.imageTransform || {};
      if (tr.corners && tr.corners.length === 4) return;
      var w = tr.w || tr.naturalW || 100;
      var h = tr.h || tr.naturalH || 100;
      tr.corners = this.boxToCorners({
        x: tr.x != null ? tr.x : 0,
        y: tr.y != null ? tr.y : 0,
        w: w,
        h: h,
        rotation: tr.rotation || 0,
      });
      cont.imageTransform = tr;
      layer.contenido = cont;
    },

    boxToCorners: function (tr) {
      var cx = tr.x + tr.w / 2;
      var cy = tr.y + tr.h / 2;
      var rad = ((tr.rotation || 0) * Math.PI) / 180;
      var hw = tr.w / 2;
      var hh = tr.h / 2;
      var cos = Math.cos(rad);
      var sin = Math.sin(rad);
      var pts = [
        { x: -hw, y: -hh },
        { x: hw, y: -hh },
        { x: hw, y: hh },
        { x: -hw, y: hh },
      ];
      return pts.map(function (p) {
        return {
          x: cx + p.x * cos - p.y * sin,
          y: cy + p.x * sin + p.y * cos,
        };
      });
    },

    getCorners: function (layer) {
      var tr = (layer.contenido && layer.contenido.imageTransform) || {};
      if (tr.corners && tr.corners.length === 4) {
        return tr.corners.map(function (c) { return { x: c.x, y: c.y }; });
      }
      var sheet = ARQ.utils.activeSheet(ARQ.store.getProject());
      var sw = (sheet && sheet.ancho) || 1920;
      var sh = (sheet && sheet.alto) || 1080;
      return this.boxToCorners({
        x: tr.x != null ? tr.x : 0,
        y: tr.y != null ? tr.y : 0,
        w: tr.w != null ? tr.w : sw,
        h: tr.h != null ? tr.h : sh,
        rotation: tr.rotation || 0,
      });
    },

    setCorners: function (layer, corners) {
      layer.contenido = layer.contenido || {};
      layer.contenido.imageTransform = layer.contenido.imageTransform || {};
      layer.contenido.imageTransform.corners = corners.map(function (c) {
        return { x: c.x, y: c.y };
      });
      delete layer.contenido.imageTransform.rotation;
    },

    rotateHandlePoint: function (corners) {
      var C = centroid(corners);
      var M = { x: (corners[0].x + corners[1].x) / 2, y: (corners[0].y + corners[1].y) / 2 };
      var outward = { x: M.x - C.x, y: M.y - C.y };
      var L = Math.hypot(outward.x, outward.y) || 1;
      return {
        x: M.x + (outward.x / L) * 48,
        y: M.y + (outward.y / L) * 48,
      };
    },

    hitTest: function (p, corners) {
      var rh = this.rotateHandlePoint(corners);
      if (dist2(p, rh) <= ROT_HANDLE * ROT_HANDLE) {
        return { kind: 'rotate' };
      }
      for (var i = 0; i < 4; i++) {
        if (dist2(p, corners[i]) <= HANDLE * HANDLE) {
          return { kind: 'corner', index: i };
        }
      }
      for (var ei = 0; ei < 4; ei++) {
        var ej = (ei + 1) % 4;
        var mx = (corners[ei].x + corners[ej].x) / 2;
        var my = (corners[ei].y + corners[ej].y) / 2;
        if (dist2(p, { x: mx, y: my }) <= HANDLE * HANDLE) {
          return { kind: 'edge', index: ei };
        }
      }
      if (this.pointInQuad(p, corners)) {
        return { kind: 'body' };
      }
      return null;
    },

    pointInQuad: function (p, c) {
      var x = p.x, y = p.y;
      var inside = false;
      for (var i = 0, j = 3; i < 4; j = i++) {
        var xi = c[i].x, yi = c[i].y;
        var xj = c[j].x, yj = c[j].y;
        var inter = ((yi > y) !== (yj > y)) &&
          (x < ((xj - xi) * (y - yi)) / (yj - yi + 1e-20) + xi);
        if (inter) inside = !inside;
      }
      return inside;
    },

    drawOverlay: function (ctx, corners) {
      ctx.save();
      ctx.strokeStyle = '#0d6efd';
      ctx.lineWidth = 1.5;
      ctx.setLineDash([4, 3]);
      ctx.beginPath();
      ctx.moveTo(corners[0].x, corners[0].y);
      for (var k = 1; k < 4; k++) ctx.lineTo(corners[k].x, corners[k].y);
      ctx.closePath();
      ctx.stroke();
      ctx.setLineDash([]);
      for (var i = 0; i < 4; i++) {
        ctx.fillStyle = '#fff';
        ctx.strokeStyle = '#0d6efd';
        ctx.lineWidth = 1.5;
        ctx.beginPath();
        ctx.rect(corners[i].x - 5, corners[i].y - 5, 10, 10);
        ctx.fill();
        ctx.stroke();
      }
      for (var ei = 0; ei < 4; ei++) {
        var ej = (ei + 1) % 4;
        var emx = (corners[ei].x + corners[ej].x) / 2;
        var emy = (corners[ei].y + corners[ej].y) / 2;
        ctx.beginPath();
        ctx.rect(emx - 4, emy - 4, 8, 8);
        ctx.fillStyle = '#fff';
        ctx.strokeStyle = '#0d6efd';
        ctx.fill();
        ctx.stroke();
      }
      var rh = this.rotateHandlePoint(corners);
      ctx.beginPath();
      ctx.arc(rh.x, rh.y, 6, 0, Math.PI * 2);
      ctx.fillStyle = '#fff';
      ctx.strokeStyle = '#0d6efd';
      ctx.fill();
      ctx.stroke();
      ctx.restore();
    },

    rotateCornersAround: function (corners, center, deltaRad) {
      var cos = Math.cos(deltaRad);
      var sin = Math.sin(deltaRad);
      return corners.map(function (c) {
        var dx = c.x - center.x;
        var dy = c.y - center.y;
        return {
          x: center.x + dx * cos - dy * sin,
          y: center.y + dx * sin + dy * cos,
        };
      });
    },

    findTopImageLayerAt: function (sheet, p) {
      var layers = ARQ.utils.sortLayers(sheet.capas || []).slice().reverse();
      for (var li = 0; li < layers.length; li++) {
        var layer = layers[li];
        if (!ARQ.guards.canDrawOnLayer(layer)) continue;
        var cont = layer.contenido || {};
        if (!cont.imageSrc) continue;
        var corners = this.getCorners(layer);
        if (this.pointInQuad(p, corners)) return layer;
      }
      return null;
    },
  };
})(typeof window !== 'undefined' ? window : this);
