/**
 * Shape Builder with GSAP Animation Integration
 * 
 * This module handles the Shape Builder feature with advanced GSAP animations.
 * 
 * Features:
 * - Automatic shape positioning within wrappers
 * - GSAP-powered animations with multiple trigger types
 * - Support for 18 different animation effects
 * - Configurable duration, delay, easing, repeat, and yoyo options
 * 
 * Animation Trigger Types:
 * - on-load: Animation plays when the page loads
 * - on-hover: Animation plays on mouse hover
 * 
 * Available Animations:
 * - Fade: fade-in, fade-in-up, fade-in-down, fade-in-left, fade-in-right
 * - Zoom: zoom-in, zoom-out
 * - Rotate: rotate-in, flip-x, flip-y
 * - Motion: bounce, pulse, swing, shake
 * - Slide: slide-in-left, slide-in-right, slide-in-up, slide-in-down
 */

jQuery(window).on('elementor/frontend/init', () => {

  const applyShapeToWrapper = () => {
    jQuery('.bdt-shape-builder').each((i, el) => {
      const $el = jQuery(el);
      const wrapperClass = $el.data('wrapper-id');

      if (wrapperClass) {
        const $wrapper = jQuery(`.${wrapperClass}`);

        // Ensure wrapper exists before appending
        if ($wrapper.length) {
          // Move shape inside wrapper
          $wrapper.append($el);
        }
      }
    });
  };

  // GSAP Animation Handler
  const initShapeAnimations = () => {
    // Handle On Load animations (trigger when entering viewport)
    jQuery('.bdt-shape-builder[data-animation-enabled="true"]').each((i, el) => {
      const $el = jQuery(el);
      const trigger = $el.data('animation-trigger');
      
      // Skip hover animations here, they're handled separately
      if (trigger === 'on-hover') {
        return;
      }
      
      // Only handle on-load animations
      if (trigger !== 'on-load') {
        return;
      }
      
      const animationName = $el.data('animation-name');
      const duration = parseFloat($el.data('animation-duration')) || 1;
      const delay = parseFloat($el.data('animation-delay')) || 0;
      const easing = $el.data('animation-easing') || 'none';
      const repeat = parseInt($el.data('animation-repeat')) || 0;
      const yoyo = $el.data('animation-yoyo');
      const viewport = parseFloat($el.data('animation-viewport')) || 0.1;

      // Get animation properties based on animation name
      const getAnimationProps = (name) => {
        const animations = {
          'fade-in': { opacity: 0 },
          'fade-in-up': { opacity: 0, y: 50 },
          'fade-in-down': { opacity: 0, y: -50 },
          'fade-in-left': { opacity: 0, x: -50 },
          'fade-in-right': { opacity: 0, x: 50 },
          'zoom-in': { scale: 0 },
          'zoom-out': { scale: 2 },
          'rotate-in': { rotation: -360 },
          'flip-x': { rotationX: 180 },
          'flip-y': { rotationY: 180 },
          'bounce': { y: -30 },
          'pulse': { scale: 0.9 },
          'swing': { rotation: 15 },
          'shake': { x: -10 },
          'slide-in-left': { x: -100 },
          'slide-in-right': { x: 100 },
          'slide-in-up': { y: 100 },
          'slide-in-down': { y: -100 }
        };
        return animations[name] || { opacity: 0 };
      };

      const fromProps = getAnimationProps(animationName);
      
      // Build toProps dynamically - only include properties that were in fromProps
      const toProps = {
        duration: duration,
        delay: delay,
        ease: easing,
        repeat: repeat,
        yoyo: yoyo,
        transformOrigin: 'center center'
      };
      
      // Only reset the properties that were animated
      if ('opacity' in fromProps) toProps.opacity = 1;
      if ('x' in fromProps) toProps.x = 0;
      if ('y' in fromProps) toProps.y = 0;
      if ('scale' in fromProps) toProps.scale = 1;
      if ('rotation' in fromProps) toProps.rotation = 0;
      if ('rotationX' in fromProps) toProps.rotationX = 0;
      if ('rotationY' in fromProps) toProps.rotationY = 0;

      // Set transform origin first
      gsap.set(el, { transformOrigin: 'center center' });
      
      // Use Intersection Observer to trigger animation when element enters viewport
      const observer = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
          if (entry.isIntersecting) {
            // Element is in viewport, start animation using fromTo for better control
            gsap.fromTo(el, 
              { ...fromProps, transformOrigin: 'center center' }, 
              toProps
            );
            // Unobserve after animation triggers (one-time animation)
            observer.unobserve(el);
          }
        });
      }, {
        threshold: viewport, // Use dynamic viewport value
        rootMargin: '0px'
      });
      
      // Start observing
      observer.observe(el);
    });
    
    // Handle On Hover animations - Parse data-settings from parent elements
    jQuery('.elementor-element[data-settings]').each((i, parentEl) => {
      const $parent = jQuery(parentEl);
      const settingsAttr = $parent.attr('data-settings');
      
      if (!settingsAttr) {
        return;
      }
      
      let settings;
      try {
        // Decode HTML entities and parse JSON
        const decodedSettings = jQuery('<textarea/>').html(settingsAttr).text();
        settings = JSON.parse(decodedSettings);
      } catch (e) {
        return; // Invalid JSON, skip
      }
      
      // Check if there are shape builder settings with hover animations
      if (!settings.bdt_shape_builder_list || !Array.isArray(settings.bdt_shape_builder_list)) {
        return;
      }
      
      const hoverShapes = settings.bdt_shape_builder_list.filter(shape => 
        shape.shape_builder_animation_popover === 'yes' && shape.animation_trigger_type === 'on-hover'
      );
      
      if (hoverShapes.length === 0) {
        return; // No hover animations in this element
      }
      
      // Create timelines for each hover shape
      const timelines = [];
      
      hoverShapes.forEach(shapeSettings => {
        // Find the actual shape element by ID
        const shapeId = shapeSettings._id;
        const $shapeEl = $parent.find(`.bdt-shape-builder.elementor-repeater-item-${shapeId}`);
        
        if ($shapeEl.length === 0) {
          return; // Shape element not found
        }
        
        const animationName = shapeSettings.animation_name || 'fade-in';
        const duration = (shapeSettings.animation_duration && shapeSettings.animation_duration.size) 
          ? parseFloat(shapeSettings.animation_duration.size) 
          : 1;
        const easing = shapeSettings.animation_easing || 'none';
        
        // Get animation properties
        const getAnimationProps = (name) => {
          const animations = {
            'fade-in': { opacity: 0 },
            'fade-in-up': { y: 50 },
            'fade-in-down': { y: -50 },
            'fade-in-left': { x: -50 },
            'fade-in-right': { x: 50 },
            'zoom-in': { scale: 0 },
            'zoom-out': { scale: 2 },
            'rotate-in': { rotation: -360 },
            'flip-x': { rotationX: 180 },
            'flip-y': { rotationY: 180 },
            'bounce': { y: -30 },
            'pulse': { scale: 0.9 },
            'swing': { rotation: 15 },
            'shake': { x: -10 },
            'slide-in-left': { x: -100 },
            'slide-in-right': { x: 100 },
            'slide-in-up': { y: 100 },
            'slide-in-down': { y: -100 }
          };
          return animations[name] || { opacity: 0 };
        };
        
        const fromProps = getAnimationProps(animationName);
        
        // Set initial visible state
        gsap.set($shapeEl[0], { opacity: 1 });
        
        // Create timeline for this shape
        const tl = gsap.timeline({ paused: true });
        
        if (['bounce', 'pulse', 'swing', 'shake'].includes(animationName)) {
          // For repeating animations on hover
          tl.to($shapeEl[0], {
            ...fromProps,
            duration: duration / 2,
            ease: easing,
            yoyo: true,
            repeat: 1
          });
        } else {
          // For transition animations
          tl.to($shapeEl[0], {
            ...fromProps,
            duration: duration,
            ease: easing
          });
        }
        
        timelines.push(tl);
      });
      
      // Add hover listeners to parent element
      if (timelines.length > 0) {
        $parent.on('mouseenter.shapeBuilder', () => {
          timelines.forEach(tl => tl.restart());
        }).on('mouseleave.shapeBuilder', () => {
          timelines.forEach(tl => tl.reverse());
        });
      }
    });
  };

  // ✅ Trigger for Container (Flexbox layout)
  elementorFrontend.hooks.addAction('frontend/element_ready/container', () => {
    applyShapeToWrapper();
    initShapeAnimations();
  });

  // ✅ Trigger for Section (Classic layout)
  elementorFrontend.hooks.addAction('frontend/element_ready/section', () => {
    applyShapeToWrapper();
    initShapeAnimations();
  });

  // ✅ Trigger for Column
  elementorFrontend.hooks.addAction('frontend/element_ready/column', () => {
    applyShapeToWrapper();
    initShapeAnimations();
  });

  // ✅ Trigger for Inner Section (legacy structure)
  elementorFrontend.hooks.addAction('frontend/element_ready/inner-section', () => {
    applyShapeToWrapper();
    initShapeAnimations();
  });

  // ✅ Also run once when the page is fully loaded
  jQuery(window).on('load', () => {
    applyShapeToWrapper();
    initShapeAnimations();
  });
});
