(function (global) {
  global.ARQ = global.ARQ || {};
  /**
   * Borrador vectorial: elimina strokes del modelo según el trazo del borrador.
   * Compatibilidad: los proyectos antiguos pueden tener strokes con herramienta 'borrador';
   * esos siguen dibujándose con destination-out en canvasEngine hasta migración opcional.
   */

  function distSq(x1, y1, x2, y2) {
    var dx = x2 - x1, dy = y2 - y1;
    return dx * dx + dy * dy;
  }

  function distPointToSeg(px, py, x1, y1, x2, y2) {
    var l2 = distSq(x1, y1, x2, y2);
    if (l2 < 1e-20) return Math.sqrt(distSq(px, py, x1, y1));
    var t = Math.max(0, Math.min(1, ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / l2));
    var projx = x1 + t * (x2 - x1);
    var projy = y1 + t * (y2 - y1);
    return Math.sqrt(distSq(px, py, projx, projy));
  }

  /** Distancia mínima entre dos segmentos (aproximación robusta). */
  function segSegMinDist(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2) {
    return Math.min(
      distPointToSeg(ax1, ay1, bx1, by1, bx2, by2),
      distPointToSeg(ax2, ay2, bx1, by1, bx2, by2),
      distPointToSeg(bx1, by1, ax1, ay1, ax2, ay2),
      distPointToSeg(bx2, by2, ax1, ay1, ax2, ay2)
    );
  }

  function eraserSegments(eraserStroke) {
    var pts = eraserStroke.puntos || [];
    var segs = [];
    var i;
    for (i = 0; i < pts.length - 1; i++) {
      segs.push({ x1: pts[i].x, y1: pts[i].y, x2: pts[i + 1].x, y2: pts[i + 1].y });
    }
    return { pts: pts, segs: segs };
  }

  function strokeIntersectsEraser(stroke, eraserStroke, halfTol) {
    var e = eraserSegments(eraserStroke);
    var sw = (stroke.grosor || 2) / 2;
    var ew = (eraserStroke.grosor || 4) / 2;
    var tol = halfTol != null ? halfTol : sw + ew + 1;

    var pts = stroke.puntos || [];
    if (pts.length < 2) return false;

    var j, k;
    for (j = 0; j < pts.length - 1; j++) {
      var sx1 = pts[j].x, sy1 = pts[j].y, sx2 = pts[j + 1].x, sy2 = pts[j + 1].y;
      for (k = 0; k < e.segs.length; k++) {
        var es = e.segs[k];
        if (segSegMinDist(sx1, sy1, sx2, sy2, es.x1, es.y1, es.x2, es.y2) <= tol) {
          return true;
        }
      }
    }
    if (e.segs.length === 0 && e.pts.length === 1) {
      var p0 = e.pts[0];
      for (j = 0; j < pts.length - 1; j++) {
        if (distPointToSeg(p0.x, p0.y, pts[j].x, pts[j].y, pts[j + 1].x, pts[j + 1].y) <= tol) return true;
      }
    }
    return false;
  }

  ARQ.eraser = {
    /**
     * Elimina trazos de la capa cuyo trazo intersecta el camino del borrador.
     * @returns {number} cantidad de strokes eliminados
     */
    eraseStrokesByPath: function (layer, eraserStroke) {
      if (!layer || !layer.contenido) return 0;
      var strokes = layer.contenido.strokes || [];
      if (!strokes.length) return 0;
      var halfTol = (eraserStroke.grosor || 4) / 2 + 3;
      var kept = [];
      var removed = 0;
      strokes.forEach(function (s) {
        if (strokeIntersectsEraser(s, eraserStroke, halfTol)) {
          removed++;
        } else {
          kept.push(s);
        }
      });
      layer.contenido.strokes = kept;
      if (removed > 0) {
        ARQ.store.setDirty(true);
      }
      return removed;
    },
  };
})(typeof window !== 'undefined' ? window : this);
