(function (global) {
  global.ARQ = global.ARQ || {};
  var $panel = null;

  function normName(s) {
    return String(s || '').trim();
  }

  function uniqueSiblingName(desired, allNames, fallback) {
    desired = normName(desired) || (fallback || 'Capa');
    var set = {};
    (allNames || []).forEach(function (n) {
      n = normName(n);
      if (!n) return;
      set[n.toLowerCase()] = true;
    });
    if (!set[desired.toLowerCase()]) return desired;

    var base = desired;
    var maxN = 0;
    (allNames || []).forEach(function (n) {
      n = normName(n);
      if (!n) return;
      var m = n.match(/^(.+?)\s*\((\d+)\)$/);
      if (!m) return;
      var b = normName(m[1]);
      var k = parseInt(m[2], 10);
      if (b.toLowerCase() === base.toLowerCase() && k > maxN) maxN = k;
    });
    return base + ' (' + (maxN + 1) + ')';
  }

  ARQ.layers = {
    init: function () {
      $panel = $('#panel-layers-list');
      $panel.attr('role', 'list');
      var self = this;
      $panel.on('click', '.arq-layer-row', function (e) {
        if ($(e.target).closest('.arq-layer-name-wrap').length) return;
        var id = $(this).data('layer-id');
        ARQ.store.setActiveLayerId(id);
        self.renderPanel();
        ARQ.canvasEngine.requestRedraw();
      });
      $panel.on('click', '.js-layer-vis', function (e) {
        e.stopPropagation();
        var id = $(this).closest('.arq-layer-row').data('layer-id');
        self.toggleVisible(id);
      });
      $panel.on('click', '.js-layer-lock', function (e) {
        e.stopPropagation();
        var id = $(this).closest('.arq-layer-row').data('layer-id');
        self.toggleLock(id);
      });
      $panel.on('click', '.js-layer-del', function (e) {
        e.stopPropagation();
        var id = $(this).closest('.arq-layer-row').data('layer-id');
        var sheet = ARQ.utils.activeSheet(ARQ.store.getProject());
        if (!sheet) return;
        var layer = null;
        (sheet.capas || []).forEach(function (l) { if (l.id === id) layer = l; });
        if (!layer) return;
        if (!ARQ.guards || !ARQ.guards.canDeleteLayer || !ARQ.guards.canDeleteLayer(layer)) {
          ARQ.bus.emit(ARQ.EVENTS.TOAST, 'No se puede eliminar esta capa');
          return;
        }
        ARQ.dialog.confirm('¿Eliminar la capa "' + (layer.nombre || 'Capa') + '"?').then(function (ok) {
          if (ok) self.removeLayerById(id);
        });
      });
      $panel.on('click', '.js-layer-import', function (e) {
        e.stopPropagation();
        var id = $(this).closest('.arq-layer-row').data('layer-id');
        $('#layer-import-file').data('layer-id', id).trigger('click');
      });
      $panel.on('click', '.js-layer-clear-img', function (e) {
        e.stopPropagation();
        var id = $(this).closest('.arq-layer-row').data('layer-id');
        ARQ.dialog.confirm('¿Quitar la imagen o documento de esta capa?').then(function (ok) {
          if (ok && ARQ.assets && ARQ.assets.removeImageFromLayer) ARQ.assets.removeImageFromLayer(id);
        });
      });
      $panel.on('keydown', '.js-layer-name', function (e) {
        if (e.key === 'Enter') {
          e.preventDefault();
          this.blur();
        } else if (e.key === 'Escape') {
          e.preventDefault();
          $(this).val($(this).data('original') || '');
          this.blur();
        }
      });
      $panel.on('focus', '.js-layer-name', function (e) {
        e.stopPropagation();
        $(this).data('original', $(this).val() || '');
        try { this.select(); } catch (err) {}
      });
      $panel.on('click', '.js-layer-name', function (e) {
        e.stopPropagation();
      });
      $panel.on('blur', '.js-layer-name', function () {
        var id = $(this).closest('.arq-layer-row').data('layer-id');
        self.renameLayerById(id, $(this).val());
      });
      $panel.on('click', '.js-layer-ai', function (e) {
        e.stopPropagation();
        if (ARQ.aiGate && !ARQ.aiGate.isEnabled()) {
          ARQ.bus.emit(ARQ.EVENTS.TOAST, 'Configura la API Key de OpenAI en Configuración.');
          return;
        }
        var id = $(this).closest('.arq-layer-row').data('layer-id');
        if (ARQ.aiPerLayer && ARQ.aiPerLayer.open) ARQ.aiPerLayer.open(id);
      });
      ARQ.bus.on(ARQ.EVENTS.AI_GATE_CHANGED, function () {
        self.renderPanel();
      });

      var dragOverEl = null;
      $panel.on('click', '.js-layer-drag', function (e) {
        e.stopPropagation();
      });
      $panel.on('dragstart', '.js-layer-drag', function (e) {
        var ev = e.originalEvent;
        var id = $(this).closest('.arq-layer-row').data('layer-id');
        if (ev.dataTransfer) {
          ev.dataTransfer.setData('text/plain', String(id));
          ev.dataTransfer.effectAllowed = 'move';
        }
        $(this).closest('.arq-layer-row').addClass('arq-layer-row--dragging');
      });
      $panel.on('dragend', '.js-layer-drag', function () {
        $(this).closest('.arq-layer-row').removeClass('arq-layer-row--dragging');
        $panel.find('.arq-layer-row').removeClass('arq-layer-row--drag-over');
        dragOverEl = null;
      });
      $panel.on('dragover', '.arq-layer-row', function (e) {
        e.preventDefault();
        var ev = e.originalEvent;
        if (ev.dataTransfer) ev.dataTransfer.dropEffect = 'move';
        var el = this;
        if (dragOverEl && dragOverEl !== el) $(dragOverEl).removeClass('arq-layer-row--drag-over');
        dragOverEl = el;
        $(el).addClass('arq-layer-row--drag-over');
      });
      $panel.on('drop', '.arq-layer-row', function (e) {
        e.preventDefault();
        $panel.find('.arq-layer-row').removeClass('arq-layer-row--drag-over');
        dragOverEl = null;
        var targetId = $(this).data('layer-id');
        var sourceId = e.originalEvent.dataTransfer && e.originalEvent.dataTransfer.getData('text/plain');
        if (sourceId && targetId && sourceId !== targetId) {
          self.reorderLayers(sourceId, targetId);
        }
      });
    },
    renderPanel: function () {
      if (!$panel || !$panel.length) return;
      var sheet = ARQ.utils.activeSheet(ARQ.store.getProject());
      $panel.empty();
      if (!sheet || !sheet.capas) return;
      var sorted = ARQ.utils.sortLayers(sheet.capas).slice().reverse();
      var active = ARQ.store.getActiveLayerId();
      sorted.forEach(function (layer) {
        var row = $('<div class="arq-layer-row" role="listitem"/>').data('layer-id', layer.id);
        if (layer.id === active) row.addClass('arq-layer-row--active');
        row.append(
          $('<div class="js-layer-drag" draggable="true" title="Arrastrar para reordenar" aria-label="Reordenar capa"/>').text('⋮⋮')
        );
        row.append($('<button type="button" class="js-layer-vis" aria-label="Visibilidad"/>').text(layer.visible ? '👁' : '·'));
        if (ARQ.aiGate && ARQ.aiGate.isEnabled()) {
          row.append($('<button type="button" class="js-layer-ai" title="IA en esta capa" aria-label="IA capa"/>').text('✦'));
        } else {
          row.append($('<span class="arq-layer-icon-spacer" aria-hidden="true"/>'));
        }
        row.append($('<button type="button" class="js-layer-lock" aria-label="Bloqueo"/>').text(layer.bloqueada ? '🔒' : '○'));
        row.append(
          $('<button type="button" class="js-layer-import" title="Importar imagen o PDF a esta capa" aria-label="Importar adjunto"/>')
            .text('📎')
        );
        var $nameWrap = $('<div class="arq-layer-name-wrap"/>');
        $nameWrap.append(
          $('<input type="text" class="js-layer-name arq-layer-name-input" autocomplete="off" spellcheck="false"/>')
            .attr('aria-label', 'Nombre de capa')
            .val(layer.nombre || 'Capa')
        );
        row.append($nameWrap);
        if (layer.contenido && layer.contenido.imageSrc) {
          row.append(
            $('<button type="button" class="js-layer-clear-img" title="Quitar imagen o PDF" aria-label="Quitar imagen"/>')
              .text('⊘')
          );
        } else {
          row.append($('<span class="arq-layer-icon-spacer" aria-hidden="true"/>'));
        }
        if (ARQ.guards && ARQ.guards.canDeleteLayer && ARQ.guards.canDeleteLayer(layer)) {
          row.append($('<button type="button" class="js-layer-del" aria-label="Eliminar capa" title="Eliminar"/>').text('✕'));
        } else {
          row.append($('<span class="arq-layer-del-spacer" aria-hidden="true"/>'));
        }
        $panel.append(row);
      });
      var an = '—';
      sorted.forEach(function (l) { if (l.id === active) an = l.nombre || '—'; });
      $('#prop-active-layer').text(an);
    },
    toggleVisible: function (id) {
      var sheet = ARQ.utils.activeSheet(ARQ.store.getProject());
      if (!sheet) return;
      var layer = null;
      (sheet.capas || []).forEach(function (l) { if (l.id === id) layer = l; });
      if (!layer) return;
      ARQ.history.pushUndo();
      layer.visible = !layer.visible;
      ARQ.store.setDirty(true);
      this.renderPanel();
      ARQ.canvasEngine.redraw();
    },
    toggleLock: function (id) {
      var sheet = ARQ.utils.activeSheet(ARQ.store.getProject());
      if (!sheet) return;
      var layer = null;
      (sheet.capas || []).forEach(function (l) { if (l.id === id) layer = l; });
      if (!layer) return;
      ARQ.history.pushUndo();
      layer.bloqueada = !layer.bloqueada;
      ARQ.store.setDirty(true);
      this.renderPanel();
    },
    addLayer: function () {
      var sheet = ARQ.utils.activeSheet(ARQ.store.getProject());
      if (!sheet) return;
      ARQ.history.pushUndo();
      var z = 0;
      (sheet.capas || []).forEach(function (l) { z = Math.max(z, l.z_index || 0); });
      var layer = {
        id: ARQ.utils.uuid(),
        nombre: 'Capa ' + ((sheet.capas || []).length + 1),
        tipo: 'vector',
        visible: true,
        bloqueada: false,
        opacidad: 1,
        blend_mode: 'normal',
        z_index: z + 1,
        contenido: { strokes: [], texts: [], shapes: [], imageSrc: null },
        metadatos: {},
      };
      sheet.capas = sheet.capas || [];
      sheet.capas.push(layer);
      ARQ.store.setActiveLayerId(layer.id);
      ARQ.store.setDirty(true);
      this.renderPanel();
      ARQ.canvasEngine.redraw();
      ARQ.history.pushDescription('Nueva capa');
    },
    removeActiveLayer: function () {
      var sheet = ARQ.utils.activeSheet(ARQ.store.getProject());
      if (!sheet) return;
      var layer = ARQ.store.activeLayer();
      if (!layer || !ARQ.guards.canDeleteLayer(layer)) {
        ARQ.bus.emit(ARQ.EVENTS.TOAST, 'No se puede eliminar esta capa');
        return;
      }
      ARQ.history.pushUndo();
      sheet.capas = (sheet.capas || []).filter(function (l) { return l.id !== layer.id; });
      var sorted = ARQ.utils.sortLayers(sheet.capas);
      ARQ.store.setActiveLayerId(sorted.length ? sorted[sorted.length - 1].id : null);
      ARQ.store.setDirty(true);
      this.renderPanel();
      ARQ.canvasEngine.redraw();
    },
    removeLayerById: function (id) {
      var sheet = ARQ.utils.activeSheet(ARQ.store.getProject());
      if (!sheet) return;
      var layer = null;
      (sheet.capas || []).forEach(function (l) { if (l.id === id) layer = l; });
      if (!layer) return;
      if (!ARQ.guards || !ARQ.guards.canDeleteLayer || !ARQ.guards.canDeleteLayer(layer)) {
        ARQ.bus.emit(ARQ.EVENTS.TOAST, 'No se puede eliminar esta capa');
        return;
      }
      ARQ.history.pushUndo();
      sheet.capas = (sheet.capas || []).filter(function (l) { return l.id !== id; });
      var sorted = ARQ.utils.sortLayers(sheet.capas);
      var active = ARQ.store.getActiveLayerId();
      if (active === id) {
        ARQ.store.setActiveLayerId(sorted.length ? sorted[sorted.length - 1].id : null);
      }
      ARQ.store.setDirty(true);
      this.renderPanel();
      ARQ.canvasEngine.redraw();
      ARQ.history.pushDescription('Eliminar capa');
    },
    /**
     * Mueve la capa source justo encima de target en el panel (misma pila que el lienzo).
     */
    reorderLayers: function (sourceId, targetId) {
      var sheet = ARQ.utils.activeSheet(ARQ.store.getProject());
      if (!sheet || !sheet.capas) return;
      var sorted = ARQ.utils.sortLayers(sheet.capas);
      var visual = sorted.slice().reverse();
      var from = -1;
      var to = -1;
      var i;
      for (i = 0; i < visual.length; i++) {
        if (visual[i].id === sourceId) from = i;
        if (visual[i].id === targetId) to = i;
      }
      if (from < 0 || to < 0 || from === to) return;
      ARQ.history.pushUndo();
      var moved = visual.splice(from, 1)[0];
      visual.splice(to, 0, moved);
      for (i = 0; i < visual.length; i++) {
        visual[i].z_index = visual.length - i;
      }
      ARQ.store.setDirty(true);
      this.renderPanel();
      ARQ.canvasEngine.redraw();
      ARQ.history.pushDescription('Reordenar capas');
    },

    renameLayerById: function (id, desiredName) {
      var sheet = ARQ.utils.activeSheet(ARQ.store.getProject());
      if (!sheet) return;
      var layer = null;
      (sheet.capas || []).forEach(function (l) { if (l.id === id) layer = l; });
      if (!layer) return;
      var all = (sheet.capas || []).filter(function (l) { return l.id !== id; }).map(function (l) { return l.nombre || ''; });
      var n = uniqueSiblingName(desiredName, all, 'Capa');
      if (n === layer.nombre) {
        this.renderPanel();
        return;
      }
      ARQ.history.pushUndo();
      layer.nombre = n;
      ARQ.store.setDirty(true);
      this.renderPanel();
      ARQ.history.pushDescription('Renombrar capa');
    },

    findLayerById: function (sheet, id) {
      var found = null;
      (sheet.capas || []).forEach(function (l) {
        if (l.id === id) found = l;
      });
      return found;
    },

    maxZIndex: function (sheet) {
      var z = 0;
      (sheet.capas || []).forEach(function (l) {
        z = Math.max(z, l.z_index || 0);
      });
      return z;
    },

    shiftLayerContent: function (layer, dx, dy) {
      if (!layer || (dx === 0 && dy === 0)) return;
      var cont = layer.contenido || {};
      (cont.texts || []).forEach(function (t) {
        t.x = (t.x != null ? t.x : 0) + dx;
        t.y = (t.y != null ? t.y : 0) + dy;
      });
      (cont.shapes || []).forEach(function (s) {
        if (s.tipo === 'rect') {
          s.x = (s.x != null ? s.x : 0) + dx;
          s.y = (s.y != null ? s.y : 0) + dy;
        } else if (s.tipo === 'circulo') {
          s.cx = (s.cx != null ? s.cx : 0) + dx;
          s.cy = (s.cy != null ? s.cy : 0) + dy;
        } else if (s.tipo === 'linea' || s.tipo === 'flecha') {
          s.x1 = (s.x1 != null ? s.x1 : 0) + dx;
          s.y1 = (s.y1 != null ? s.y1 : 0) + dy;
          s.x2 = (s.x2 != null ? s.x2 : 0) + dx;
          s.y2 = (s.y2 != null ? s.y2 : 0) + dy;
        }
      });
      (cont.strokes || []).forEach(function (st) {
        (st.puntos || []).forEach(function (pt) {
          pt.x += dx;
          pt.y += dy;
        });
      });
      var tr = cont.imageTransform;
      if (tr) {
        if (tr.corners && tr.corners.length === 4) {
          tr.corners.forEach(function (c) {
            c.x += dx;
            c.y += dy;
          });
        } else {
          tr.x = (tr.x != null ? tr.x : 0) + dx;
          tr.y = (tr.y != null ? tr.y : 0) + dy;
        }
      }
      layer.contenido = cont;
    },

    duplicateActiveLayer: function () {
      var sheet = ARQ.utils.activeSheet(ARQ.store.getProject());
      if (!sheet) return;
      var layer = ARQ.store.activeLayer();
      if (!layer) {
        ARQ.bus.emit(ARQ.EVENTS.TOAST, 'No hay capa activa');
        return;
      }
      ARQ.history.pushUndo();
      var copy = ARQ.utils.deepClone(layer);
      copy.id = ARQ.utils.uuid();
      copy.nombre = uniqueSiblingName((layer.nombre || 'Capa') + ' copia', (sheet.capas || []).map(function (l) { return l.nombre || ''; }), 'Capa');
      copy.z_index = this.maxZIndex(sheet) + 1;
      delete copy.es_capa_base;
      sheet.capas = sheet.capas || [];
      sheet.capas.push(copy);
      ARQ.store.setActiveLayerId(copy.id);
      ARQ.store.setDirty(true);
      this.renderPanel();
      ARQ.canvasEngine.redraw();
      ARQ.history.pushDescription('Duplicar capa');
      if (ARQ.actionLog && ARQ.actionLog.append) {
        ARQ.actionLog.append(sheet, 'duplicate_layer', copy.id, { origen_id: layer.id });
      }
    },

    appendImageLayer: function (sheet, nombre, z) {
      var layer = {
        id: ARQ.utils.uuid(),
        nombre: nombre || 'Capa',
        tipo: 'imagen',
        visible: true,
        bloqueada: false,
        opacidad: 1,
        blend_mode: 'normal',
        z_index: z,
        contenido: { strokes: [], texts: [], shapes: [], imageSrc: null },
        metadatos: {},
      };
      sheet.capas = sheet.capas || [];
      sheet.capas.push(layer);
      return layer;
    },
  };
})(typeof window !== 'undefined' ? window : this);
