import React, { useEffect, useRef, createElement } from 'react';
import './../style.scss'; // Assume styles will be moved to this CSS.
import useActiveDevice from '../../hooks/useActiveDevice';
import {
  getResponsivePaddingStyle,
  getResponsiveMarginStyle,
  getResponsiveFontSize,
  getResponsiveLineHeight,
  getTextShadowStyle
} from '../../utils/styleHelpers';

import { animate, scroll, inView } from "motion";
import planeIcon from './../../assets/plane.svg';
import AOS from 'aos';
import 'aos/dist/aos.css';

const OurJourneyLayoutTwo = ({ attributes }) => {
  if ( ! attributes ) {
    return null;
  }

  const device = useActiveDevice();

  const {
      className = '',
      sectionItemContentBgColor = '',
      sectionItemYearBgColor = '',
      headingFontFamily = '',
      headingFontWeight = '',
      headingFontColor = '',
      headingBgColor = '',
      yearFontFamily = '',
      yearFontWeight = '',
      yearFontColor = '',
      titleFontFamily = '',
      titleFontWeight = '',
      titleFontColor = '',
      descriptionFontFamily = '',
      descriptionFontWeight = '',
      descriptionFontColor = '',
      imageSize,
      showHeading,
      showYear,
      showImage,
      showTitle,
      showDescription,
      entries = []
  } = attributes;

  // Get responsive image dimensions.
  const widthValue = ( imageSize?.[device]?.width ) || 'auto';
  const heightValue = ( imageSize?.[device]?.height ) || 'auto';
  const imgStyle = {
    ...( 'auto' !== widthValue && { width: widthValue }),
    ...( 'auto' !== heightValue && { height: heightValue }),
    ...( 'auto' === widthValue && 'auto' === heightValue && {

      // Default fallback style if both are auto.
      maxWidth: '100%',
      height: 'auto',
      display: 'block'
    })
  };
  const getFontStyle = ( font, weight, color ) => ({
      fontFamily: font || undefined,
      fontWeight: weight || undefined,
      color: color || undefined
  });

  const uniqueWrapperIdRef = useRef( `creativeWrapper-${Math.random().toString( 36 ).substr( 2, 9 )}` );
  const uniqueJourneyTitleIdRef = useRef( `journeyTitle-${Math.random().toString( 36 ).substr( 2, 9 )}` );
  const uniqueUnderlineIdRef = useRef( `creativeUnderline-${Math.random().toString( 36 ).substr( 2, 9 )}` );
  const uniqueUnderlinePathIdRef = useRef( `creativeUnderlinePath-${Math.random().toString( 36 ).substr( 2, 9 )}` );

  const uniquePlaneIdRef = useRef( `plane-${Math.random().toString( 36 ).substr( 2, 9 )}` );
  const uniquePathIdRef = useRef( `path-${Math.random().toString( 36 ).substr( 2, 9 )}` );

  const timelineRef = useRef([]);
  const planeRef = useRef( null );
  const pathRef = useRef( null );
  const comp = useRef();

  useEffect( () => {
    let ctx;

    const initAnimations = () => {
      if (ctx) {
        ctx = null;
      }
      // --- Plane Motion ---
      const plane = document.getElementById(uniquePlaneIdRef.current);
            const pathSvg = document.getElementById(uniquePathIdRef.current);
            const path = pathSvg ? pathSvg.querySelector("path") : null;

            if (plane && path) {
                const pathLength = path.getTotalLength();
                let lastScrollY = 0;

                const bindScroll = (scrollContainer, label) => {

                    const handleScroll = () => {
                        const rect = comp.current?.getBoundingClientRect?.();
                        if (!rect) {
                            console.warn("No rect found for comp");
                            return;
                        }

                        const windowHeight = scrollContainer === window
                            ? window.innerHeight
                            : scrollContainer.clientHeight;

                        const isVisible = rect.top < windowHeight && rect.bottom > 0;

                        if (!isVisible) return;

                        const visibleTop = Math.max(0, -rect.top);
                        const visibleHeight = Math.min(rect.height, windowHeight);
                        const scrollRange = rect.height - visibleHeight;
                        
                        let progress = scrollRange > 0 ? visibleTop / scrollRange : 0;
                        progress = Math.min(Math.max(progress, 0), 1);

                        const slowProgress = progress * 0.95;
                        const point = path.getPointAtLength(slowProgress * pathLength);

                        const ctm = path.getCTM();
                        const svgPoint = path.ownerSVGElement.createSVGPoint();
                        svgPoint.x = point.x - 3;
                        svgPoint.y = point.y;
                        const screenPoint = svgPoint.matrixTransform(ctm);

                        //Detect scroll direction
                        const currentScrollY = scrollContainer === window 
                            ? window.scrollY 
                            : scrollContainer.scrollTop;
                        let rotateDeg = 0;

                        if (currentScrollY > lastScrollY) {
                            // scrolling down
                            rotateDeg = 0;  // plane faces right/down
                        } else if (currentScrollY < lastScrollY) {
                            // scrolling up
                            rotateDeg = 180; // plane faces left/up
                        }

                        lastScrollY = currentScrollY;

                        //Apply both translate & rotate
                        plane.style.transform = `translate(${screenPoint.x}px, ${screenPoint.y}px) rotate(${rotateDeg}deg)`;
                    };
                    scrollContainer.addEventListener("scroll", handleScroll);
                };

                //Detect if we are in Gutenberg backend
                if (document.body.classList.contains("wp-admin")) {
                    // The actual scrolling wrapper in Gutenberg
                    const editorScrollContainer =
                        document.querySelector(".interface-interface-skeleton__content") ||
                        document.querySelector(".block-editor-writing-flow");

                    if (editorScrollContainer) {
                        bindScroll(editorScrollContainer, "Editor Scroll Container");
                    } else {
                        console.warn("Editor scroll container not found");
                    }
                } else {
                    bindScroll(window, "Window");
                }
            }

      const journeyTitleEl = document.querySelector(".ojb-section-heading");
                  
      if (journeyTitleEl) {
        // Animate heading, then underline sequentially
        inView(".ojb-section-heading", async (el) => {
          // Step 1: Heading text reveal
          await animate(
            el,
            {
              clipPath: ["inset(0% 100% 0% 0%)", "inset(0% 0% 0% 0%)"],
              opacity: [0, 1],
            },
            {
              duration: 1.5,
              easing: "ease-in-out",
            }
          ).finished;

          // Step 2: Find underline path (sibling or by dynamic ID)
          const pathEl = el.parentElement.querySelector("[id^='creativeUnderlinePath-']");
          if (pathEl) {
            const pathLength = pathEl.getTotalLength();
            // hide underline initially
            pathEl.style.strokeDasharray = pathLength;
            pathEl.style.strokeDashoffset = pathLength;

            const underlineAnim = pathEl.animate(
              [
                { strokeDashoffset: pathLength }, // hidden
                { strokeDashoffset: 0 }           // visible
              ],
              {
                duration: 1500,
                easing: "ease-in-out",
                fill: "forwards",  //keep final frame
              }
            );
            await underlineAnim.finished;
            pathEl.style.strokeDashoffset = 0;
          }
        });
      }
    };

    initAnimations(); // Run on mount.

    const updateCircleSize = () => {
      const wrapper = document.getElementById( uniqueWrapperIdRef.current );
      const title = document.getElementById( uniqueJourneyTitleIdRef.current );
      const svg = document.getElementById( uniqueUnderlineIdRef.current );

      if ( ! wrapper || ! title || ! svg ) {
        return;
      }

      // Get size of the h2 content.
      const titleRect = title.getBoundingClientRect();
      const style = getComputedStyle( title );
      const fontSize = parseFloat( style.fontSize );
      const padding = 30; // estimated total padding (left + right or top + bottom).

      // Calculate the desired diameter.
      const contentWidth = titleRect.width + padding;
      const contentHeight = titleRect.height + padding;

      // Set SVG width equal to the h2 width.
      svg.style.width = '50%';

      // Set SVG height proportional to font size (e.g., 30%).
      svg.style.height = `${fontSize * 0.6}px`;

      const diameter = Math.max( contentWidth, contentHeight, 100 ); // enforce min 100px

      // Apply size to the wrapper.
      wrapper.style.width = `${diameter}px`;
      wrapper.style.height = `${diameter}px`;
    };
    updateCircleSize();
    let animationCircleSize;
    requestAnimationFrame( () => {
      animationCircleSize = requestAnimationFrame( updateCircleSize );
    });

    AOS.init({ duration: 1000, once: false });

    const handleResize = () => {
      initAnimations(); // Re-run animations on resize.
      updateCircleSize(); // Update circle size on resize.
    };

    window.addEventListener( 'resize', handleResize );

    return () => {
      window.removeEventListener( 'resize', handleResize );
      if ( ctx ) {
        ctx.revert();
      } // Clean up on unmount.
    };
  }, []);

  const validEntries = Array.isArray( entries ) ?
    entries.filter( entry =>
        entry.year?.trim() ||
        entry.title?.trim() ||
        entry.description?.trim() ||
        entry.imageUrl?.trim()
        ) :
    [];

  return (

    // Attach the `comp` ref to the outermost element where animations are scoped.
    <div ref={comp} className={`journey-continer px-4 py-6 md:px-8 lg:px-5 max-md:pb-14 overflow-hidden ${className}`} >
      {showHeading && (
        <div className="w-full text-center mb-7 md:mb-9">
          <div
            id={uniqueWrapperIdRef.current}
            className="creative-title-wrapper inline-flex items-center flex-wrap content-center justify-center rounded-full bg-blue-200 p-2 md:p-4 px-8 md:px-12 border-2 border-dashed border-white min-w-[150px] min-h-[150px] shadow-2xl"
            style={{
              backgroundColor: headingBgColor || undefined
            }}
          >
            <div className="flex flex-col items-center justify-center">
              {( () => {
                  const HeadingTag = 'h2';
                  const hasHTMLHeading = /<\/?[a-z][\s\S]*>/i.test( attributes.heading ); // simple check for any HTML tag.

                  return createElement(
                  HeadingTag,
                  {
                      id: uniqueJourneyTitleIdRef.current,
                      className: 'text-xl !mt-0 !mb-0 sm:text-2xl md:text-3xl lg:text-4xl text-blue-800 font-medium text-center uppercase break-word ojb-section-heading',
                      style: {
                          ...getResponsiveFontSize( attributes.headingFontSize, attributes.headingFontSizeUnit || 'px', device ),
                          ...getResponsiveLineHeight( attributes.headingLineHeight, attributes.headingLineHeightUnit || 'px', device ),
                          ...getFontStyle( headingFontFamily, headingFontWeight, headingFontColor )
                      },
                      ...( hasHTMLHeading ? { dangerouslySetInnerHTML: { __html: attributes.heading } } : {})
                  },
                  hasHTMLHeading ? undefined : attributes.heading // only use children if not using dangerouslySetInnerHTML.
                  );
              })()}
              <svg
                id={uniqueUnderlineIdRef.current}
                className="w-[80px] h-[20px] md:w-[100px] md:h-[25px]"
                viewBox="0 0 200 10"
                preserveAspectRatio="none"
                fill="none"
                xmlns="http://www.w3.org/2000/svg"
              >
                <path
                  id={uniqueUnderlinePathIdRef.current}
                  d="M0 5 L200 5"  // ✅ straight horizontal line
                  stroke={headingFontColor || 'oklch(42.4% 0.199 265.638)'}
                  strokeWidth="2"
                  strokeLinecap="round"
                  fill="none"
                />
              </svg>
            </div>
          </div>
        </div>
      )}

      {0 < validEntries.length ? (
        <div className="relative journey-main">
          {/* Curved Timeline Line (for the plane's motion path). */}
          {/* The viewBox is 0 0 100 100, meaning 50 0 is the top center, 50 100 is bottom center. */}
          <svg
            id={uniquePathIdRef.current}
            className="absolute top-0 left-0 w-full h-full pointer-events-none z-0 motion-path"
            viewBox="0 0 100 100"
            preserveAspectRatio="none"
            ref={pathRef}
          >
            <path
              d="M 50 0 L 50 100"  // ⬅️ Straight vertical line
              stroke="#193cb8"
              vectorEffect="non-scaling-stroke"
              fill="none"
              strokeWidth={3}
              strokeLinecap="round"
            />
          </svg>
          {/* Plane Icon. */}
          <img
            id={uniquePlaneIdRef.current}
            ref={planeRef}
            src={planeIcon}
            alt="Plane"

            // Tailwind classes for positioning and size. z-5 keeps it above the path.
            // bg-white is added to ensure it covers the path if it moves over it, common for icons.
            className="absolute w-12 h-12 md:w-16 md:h-16 lg:w-20 lg:h-20 z-1 plane-img"
          />
          {/* Timeline Items Loop. */}
          {/* This section defines the layout for your milestone content. */}
          <div className="relative flex flex-col gap-12 md:gap-16 pb-20">
            {validEntries.map( ( entry, index ) => (
              <div
                key={index}
                ref={( el ) => ( timelineRef.current[index] = el )} // For AOS if needed on individual items.
                className="relative flex justify-center"
              >
                <div className={`w-full max-w-[300px] md:max-w-[1200px] flex flex-col items-center md:flex-row ${0 === index % 2 ? 'md:justify-end' : 'md:justify-start'} `}>
                  {/* Milestone Text Content. */}
                  <div className={`
                      w-full md:w-2/3 mt-7 py-3 p-5 md:p-5 lg:p-6 rounded-2xl mb-8 md:mb-0 text-center relative z-1 flex items-center max-md:flex-wrap ${0 === index % 2 ? 'md:order-1 md:ml-0 md:text-left' : 'md:order-3 md:mr-0 md:text-right'}
                  `}>
                    <div
                      data-aos={0 === index % 2 ? 'fade-right' : 'fade-left'}
                      className={`bg-blue-800 max-md:w-[60%] m-auto md:w-[100%] py-4 md:py-22 px-5 max-md:pb-8 md:px-7 md:h-[80%] md:absolute -z-10 flex items-center rounded-t-full md:rounded-[100px] justify-center ${0 === index % 2 ? 'md:order-1 md:rounded-l-[100px] md:left-[-30%] md:justify-start' : 'md:order-2 md:rounded-r-[100px] md:right-[-30%] lg:right-[-10%] md:justify-end'}`}
                      style={{
                        backgroundColor: sectionItemYearBgColor || undefined
                      }}
                    >
                      {showYear && entry.year && ( () => {
                        const YearTag = attributes.yearTag || 'p';
                        const hasHTMLYear = /<\/?[a-z][\s\S]*>/i.test( entry.year ); // simple check for any HTML tag.

                        return createElement(
                          YearTag,
                          {
                            className: 'block text-3xl !mt:0 !mb:0 md:text-5xl lg:text-6xl text-blue-200 font-semibold tracking-[2px] break-word ojb-year',
                            style: {
                              ...getResponsiveFontSize( attributes.yearFontSize, attributes.yearFontSizeUnit || 'px', device ),
                              ...getResponsiveLineHeight( attributes.yearLineHeight, attributes.yearLineHeightUnit || 'px', device ),
                              ...getFontStyle( yearFontFamily, yearFontWeight, yearFontColor ),
                              ...getTextShadowStyle( attributes.yearTextShadow, device )
                            },
                            ...( hasHTMLYear ? { dangerouslySetInnerHTML: { __html: entry.year } } : {})
                          },
                          hasHTMLYear ? undefined : entry.year // only use children if not using dangerouslySetInnerHTML.
                        );
                      })()}

                    </div>
                    <div
                      data-aos={0 === index % 2 ? 'fade-left' : 'fade-right'}
                      className={`bg-white w-[100%] lg:w-[80%] md:h-full rounded-2xl md:rounded-[100px] p-5 md:p-10 shadow-2xl max-md:mt-[-20px] ${0 === index % 2 ? 'md:order-2' : 'md:order-1'}`}
                      style={{
                          backgroundColor: sectionItemContentBgColor || undefined
                      }}
                    >
                      <div className={`w-full flex justify-center md:inline-block ${0 === index % 2 ? 'md:order-3' : 'md:order-1'}`}>
                        {showImage && entry.imageUrl && (
                            <img
                            className={`w-[50px] h-auto rounded-lg my-5 ${0 === index % 2 ? 'md:me-auto' : 'md:ms-auto'} md:w-[80px]`}
                            src={entry.imageUrl}
                            alt={entry.title}
                            style={imgStyle}
                            />
                        )}
                      </div>
                      {showTitle && entry.title && ( () => {
                        const TitleTag = attributes.titleTag || 'h4';
                        const hasHTMLTitle = /<\/?[a-z][\s\S]*>/i.test( entry.title ); // simple check for any HTML tag.

                        return createElement(
                          TitleTag,
                          {
                            className: 'block text-xl md:text-2xl lg:text-4xl text-blue-800 font-semibold !mt-1 !mb-0 tracking-[1px] md:tracking-[2px] uppercase break-word ojb-title',
                            style: {
                              ...getResponsiveFontSize( attributes.titleFontSize, attributes.titleFontSizeUnit || 'px', device ),
                              ...getResponsiveLineHeight( attributes.titleLineHeight, attributes.titleLineHeightUnit || 'px', device ),
                              ...getFontStyle( titleFontFamily, titleFontWeight, titleFontColor ),
                              ...getTextShadowStyle( attributes.titleTextShadow, device )
                            },
                            ...( hasHTMLTitle ? { dangerouslySetInnerHTML: { __html: entry.title } } : {})
                          },
                          hasHTMLTitle ? undefined : entry.title // only use children if not using dangerouslySetInnerHTML.
                        );
                      })()}

                      {showDescription && entry.description && ( () => {
                        const DescriptionTag = 'p';
                        const hasHTMLDesc = /<\/?[a-z][\s\S]*>/i.test( entry.description ); // simple check for any HTML tag.

                        return createElement(
                          DescriptionTag,
                          {
                            className: 'text-gray-600 !mt-2 !mb-0 text-[15px] md:text-[17px] break-word ojb-description',
                            style: {
                              ...getResponsiveFontSize( attributes.descriptionFontSize, attributes.descriptionFontSizeUnit || 'px', device ),
                              ...getResponsiveLineHeight( attributes.descriptionLineHeight, attributes.descriptionLineHeightUnit || 'px', device ),
                              ...getFontStyle( descriptionFontFamily, descriptionFontWeight, descriptionFontColor )
                            },
                            ...( hasHTMLDesc ? { dangerouslySetInnerHTML: { __html: entry.description } } : {})
                          },
                          hasHTMLDesc ? undefined : entry.description // only use children if not using dangerouslySetInnerHTML.
                        );
                      })()}
                    </div>
                  </div>
                  {/* Spacer div for desktop layout to push content apart. */}
                  {/* Milestone Image. */}
                </div>
              </div>
            ) )}
          </div>
        </div>
      ) : null}
    </div>
  );
};

export default OurJourneyLayoutTwo;
