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

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

const OurJourneyLayoutOne = ({ attributes }) => {

    if ( ! attributes ) {
        return null;
    }

    const device = useActiveDevice();

    const {
        className = '',
        sectionItemContentBgColor = '',
        headingFontFamily = '',
        headingFontWeight = '',
        headingFontColor = '',
        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 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;
            }

            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(); // Initial run.

        const updateUnderline = () => {
            const title = document.getElementById( uniqueJourneyTitleIdRef.current );
            const svg = document.getElementById( uniqueUnderlineIdRef.current );

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

            const titleRect = title.getBoundingClientRect();
            const fontSize = parseFloat( getComputedStyle( title ).fontSize );

            // Set SVG width equal to the h2 width.
            svg.style.width = `${titleRect.width}px`;

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

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

        // Resize handler.
        const handleResize = () => {
            initAnimations(); // Re-run animations on resize.
            updateUnderline(); // Update underline position on resize.
        };

        window.addEventListener( 'resize', handleResize );

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

    const validEntries = Array.isArray( entries ) ?
        entries.filter( entry =>
            entry.year?.trim() ||
            entry.title?.trim() ||
            entry.description?.trim() ||
            entry.imageUrl?.trim()
            ) :
        [];
    return (
        <div ref={comp} className={`journey-continer px-4 py-6 md:px-8 lg:px-5 ${className}`}>

            {showHeading && (
                <div className="w-full text-center mb-20 md:mb-24">
                    <div className="creative-title-wrapper flex flex-col items-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-3xl !mt-0 !mb-0 sm:text-4xl md:text-5xl lg:text-6xl text-purple-900 font-semibold text-center 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-[150px] h-[25px] md:w-[320px] md:h-[45px] mt-[5px] md:mt-[10px]"
                            viewBox="0 0 200 10" preserveAspectRatio="none" fill="none" xmlns="http://www.w3.org/2000/svg"
                        >
                            <path
                                id={uniqueUnderlinePathIdRef.current}
                                d="M0 5 Q 50 0 100 5 T 200 5"
                                stroke={headingFontColor || '#59168b'}
                                strokeWidth="2"
                                strokeLinecap="round"
                                fill="none"
                            />
                        </svg>
                    </div>
                </div>
            )}

            {0 < validEntries.length ? (
                <div className="relative journey-main" data-count={entries.length}>

                    {/* Curved Timeline Line. */}
                    <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 Q 55 10 50 20 Q 45 30 50 40 Q 55 50 50 60 Q 45 70 50 80 Q 55 90 50 100"
                            stroke="#59168b"
                            vectorEffect="non-scaling-stroke"
                            fill="none"
                            strokeWidth={3}
                            strokeDasharray="1 5"
                            strokeLinecap="round"
                        />
                    </svg>

                    {/* Plane. */}
                    <img
                        id={uniquePlaneIdRef.current}
                        ref={planeRef}
                        src={planeIcon}
                        alt="Plane"
                        className="absolute w-12 h-12 md:w-16 md:h-16 lg:w-20 lg:h-20 z-5 plane-img"
                    />

                    {/* Timeline Items. */}
                    <div className="relative flex flex-col gap-16 pb-20 z-10">
                        {validEntries.map( ( entry, index ) => (
                            <div
                                key={index}
                                ref={( el ) => ( timelineRef.current[index] = el )}
                                className="relative flex justify-center"
                            >
                                <div className={'w-full max-w-[300px] md:max-w-[1200px] flex flex-col items-center md:flex-row md:justify-between overflow-hidden'}>
                                    {/* Content Box. */}
                                    <div
                                        data-aos={0 === index % 2 ? 'fade-right' : 'fade-left'}
                                        className={`
                                            w-full md:w-2/5
                                            bg-white py-6 p-5 md:p-5 lg:p-6
                                            rounded-2xl border-double border-purple-900
                                            mb-8 md:mb-0 text-center ${0 === index % 2 ? 'md:order-1 md:border-l-6 md:ml-0 md:text-left' : 'md:order-3 md:border-r-6 md:mr-0 md:text-right'}
                                        `}
                                        style={{
                                            backgroundColor: sectionItemContentBgColor || 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-4xl md:text-5xl lg:text-6xl text-purple-200 font-semibold tracking-[2px] !mt-0 !mb-5 lg:!mb-10 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.
                                            );
                                        })()}

                                        {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-purple-900 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 );

                                            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
                                            );
                                        })()}
                                    </div>

                                    {/* Spacer for md screens and up. */}
                                    <div className="hidden md:block md:w-1/5 md:inline-block md:h-full md:order-2"></div>

                                    {/* Image. */}
                                    <div data-aos={0 === index % 2 ? 'fade-left' : 'fade-right'} className={`w-full md:w-2/5 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 m-auto my-5 ${0 === index % 2 ? 'md:me-auto' : 'md:ms-auto'} md:w-[80px] ojb-image`}
                                        src={entry.imageUrl}
                                        alt={entry.title}
                                        style={imgStyle}
                                        />
                                    )}
                                    </div>
                                </div>
                            </div>
                        ) )}
                    </div>
                </div>
            ) : null}
        </div>
    );
};
export default OurJourneyLayoutOne;
