/**
 * Before/After Comparison Section – JavaScript
 * ITSWEBER CMS Plugin
 *
 * Provides interactive image comparison slider functionality using mouse, touch,
 * and keyboard controls with requestAnimationFrame for smooth performance.
 */

(function() {
  'use strict';

  // ──────────────────────────────────────────────────────────────────────────
  // BeforeAfterSlider Class
  // ──────────────────────────────────────────────────────────────────────────

  class BeforeAfterSlider {
    constructor(container) {
      this.container = container;
      this.beforeImg = container.querySelector('.ba-before');
      this.afterImg = container.querySelector('.ba-after');
      this.handle = container.querySelector('.ba-handle');
      this.handleLine = container.querySelector('.ba-handle-line');

      this.isDragging = false;
      this.sliderPosition = 50; // Percentage (0-100)
      this.animationFrameId = null;

      // Bind event handlers
      this.onMouseDown = this.onMouseDown.bind(this);
      this.onMouseMove = this.onMouseMove.bind(this);
      this.onMouseUp = this.onMouseUp.bind(this);
      this.onTouchStart = this.onTouchStart.bind(this);
      this.onTouchMove = this.onTouchMove.bind(this);
      this.onTouchEnd = this.onTouchEnd.bind(this);
      this.onKeyDown = this.onKeyDown.bind(this);

      this.init();
    }

    init() {
      // Mouse events – listen on ENTIRE container so clicking anywhere starts drag
      this.container.addEventListener('mousedown', this.onMouseDown);
      document.addEventListener('mousemove', this.onMouseMove);
      document.addEventListener('mouseup', this.onMouseUp);

      // Touch events
      this.container.addEventListener('touchstart', this.onTouchStart, { passive: false });
      document.addEventListener('touchmove', this.onTouchMove, { passive: false });
      document.addEventListener('touchend', this.onTouchEnd);

      // Keyboard events
      this.container.addEventListener('keydown', this.onKeyDown);
      this.container.setAttribute('tabindex', '0');
      this.container.setAttribute('role', 'slider');
      this.container.setAttribute('aria-label', 'Bildvergleich-Schieberegler');
      this.container.setAttribute('aria-valuemin', '0');
      this.container.setAttribute('aria-valuemax', '100');
      this.container.setAttribute('aria-valuenow', '50');

      // Initial position
      this.updateSliderUI();
    }

    // ────────────────────────────────────────────────────────────────────────
    // Mouse Interaction – click ANYWHERE in slider to start dragging
    // ────────────────────────────────────────────────────────────────────────

    onMouseDown(e) {
      e.preventDefault();
      this.isDragging = true;
      this.container.classList.add('dragging');
      this.updatePositionFromEvent(e);
    }

    onMouseMove(e) {
      if (!this.isDragging) return;
      e.preventDefault();
      this.updatePositionFromEvent(e);
    }

    onMouseUp() {
      if (!this.isDragging) return;
      this.isDragging = false;
      this.container.classList.remove('dragging');
    }

    // ────────────────────────────────────────────────────────────────────────
    // Touch Interaction
    // ────────────────────────────────────────────────────────────────────────

    onTouchStart(e) {
      var touch = e.touches[0];
      if (!touch) return;

      this.isDragging = true;
      this.container.classList.add('dragging');
      this.updatePositionFromEvent(touch);
      e.preventDefault();
    }

    onTouchMove(e) {
      if (!this.isDragging) return;
      var touch = e.touches[0];
      if (!touch) return;
      this.updatePositionFromEvent(touch);
      e.preventDefault();
    }

    onTouchEnd() {
      if (!this.isDragging) return;
      this.isDragging = false;
      this.container.classList.remove('dragging');
    }

    // ────────────────────────────────────────────────────────────────────────
    // Keyboard Interaction (Arrow Keys)
    // ────────────────────────────────────────────────────────────────────────

    onKeyDown(e) {
      if (e.key === 'ArrowLeft') {
        e.preventDefault();
        this.sliderPosition = Math.max(0, this.sliderPosition - 2);
        this.updateSliderUI();
      } else if (e.key === 'ArrowRight') {
        e.preventDefault();
        this.sliderPosition = Math.min(100, this.sliderPosition + 2);
        this.updateSliderUI();
      } else if (e.key === 'Home') {
        e.preventDefault();
        this.sliderPosition = 0;
        this.updateSliderUI();
      } else if (e.key === 'End') {
        e.preventDefault();
        this.sliderPosition = 100;
        this.updateSliderUI();
      }
    }

    // ────────────────────────────────────────────────────────────────────────
    // Position Updates
    // ────────────────────────────────────────────────────────────────────────

    updatePositionFromEvent(e) {
      var rect = this.container.getBoundingClientRect();

      var clientX;
      if (e.clientX !== undefined) {
        clientX = e.clientX;
      } else if (e.touches && e.touches[0]) {
        clientX = e.touches[0].clientX;
      } else {
        return;
      }

      var x = clientX - rect.left;
      var percentage = Math.max(0, Math.min(100, (x / rect.width) * 100));

      this.sliderPosition = percentage;
      this.updateSliderUI();
    }

    updateSliderUI() {
      if (this.animationFrameId) {
        cancelAnimationFrame(this.animationFrameId);
      }

      var self = this;
      this.animationFrameId = requestAnimationFrame(function() {
        var clipPercent = 100 - self.sliderPosition;

        // Update before image clip-path (only if element exists)
        if (self.beforeImg) {
          self.beforeImg.style.clipPath = 'inset(0 ' + clipPercent + '% 0 0)';
        }

        // Update handle position (handle-line is a child, moves with handle)
        if (self.handle) {
          self.handle.style.left = self.sliderPosition + '%';
        }

        // Update ARIA attributes
        self.container.setAttribute('aria-valuenow', Math.round(self.sliderPosition));
      });
    }

    destroy() {
      // Clean up event listeners
      this.container.removeEventListener('mousedown', this.onMouseDown);
      document.removeEventListener('mousemove', this.onMouseMove);
      document.removeEventListener('mouseup', this.onMouseUp);
      this.container.removeEventListener('touchstart', this.onTouchStart);
      document.removeEventListener('touchmove', this.onTouchMove);
      document.removeEventListener('touchend', this.onTouchEnd);
      this.container.removeEventListener('keydown', this.onKeyDown);

      if (this.animationFrameId) {
        cancelAnimationFrame(this.animationFrameId);
      }
    }
  }

  // ──────────────────────────────────────────────────────────────────────────
  // Initialize All Sliders
  // ──────────────────────────────────────────────────────────────────────────

  function initializeSliders() {
    var containers = document.querySelectorAll('.ba-slider-container');
    var sliders = [];

    containers.forEach(function(container) {
      // Skip if already initialized
      if (container.dataset.initialized) {
        return;
      }

      try {
        var slider = new BeforeAfterSlider(container);
        sliders.push(slider);
        container.dataset.initialized = 'true';
      } catch (err) {
        // Silently skip broken containers
      }
    });

    return sliders;
  }

  // ──────────────────────────────────────────────────────────────────────────
  // Auto-Initialize on DOM Ready
  // ──────────────────────────────────────────────────────────────────────────

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initializeSliders);
  } else {
    initializeSliders();
  }

  // ──────────────────────────────────────────────────────────────────────────
  // Expose Global API (optional)
  // ──────────────────────────────────────────────────────────────────────────

  window.BeforeAfterSlider = BeforeAfterSlider;
  window.initializeBeforeAfterSliders = initializeSliders;

})();
