//@ts-ignore: Cannot find module '@wordpress/i18n' or its corresponding type declarations.
import { __ } from '@wordpress/i18n';
import {  render, useEffect, useRef } from '@wordpress/element'
//@ts-ignore: Cannot find module '@wordpress/block-editor' or its corresponding type declarations.
import { useBlockProps, useInnerBlocksProps, store as blockEditorStore, } from '@wordpress/block-editor';
//@ts-ignore: Cannot find module '@wordpress/data' or its corresponding type declarations.
import { useSelect } from '@wordpress/data';
//@ts-ignore: Cannot find module '@wordpress/components' or its corresponding type declarations.
import { Placeholder, Button } from '@wordpress/components'

import { AttributesScene } from '../types';

import InspectorControls from './inspector-controls';
import BlockControls from './block-controls';
import getScrollsequenceFop from '../../../getScrollsequenceFop';
import RenderFunction from './render-fn';
import { DVPT } from '../../../../dbg'

/**
 * The edit function describes the structure of your block in the context of the
 * editor. This represents what the editor will render when the block is used.
 *
 * @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/#edit
 *
 * @return {WPElement} Element to render.
 */
interface EditProps {
    clientId: string,
    attributes: AttributesScene,
    setAttributes: any,
    name: string,
    onRemove: any, //  () => removeBlock(clientId)
    onReplace: any, //  (...args) => {…}
    // ... more attributes
    
}



export default function Edit(props:EditProps) {
    const { 
        clientId,
        attributes, 
        setAttributes,
        attributes:{
            height, 
            heightUnit, 
            duration,
            durationUnit,
            top, 
            topUnit,
            absTop,
            absTopUnit,
            scrub,
        } 
    } = props;

    const defaultAttributes = useSelect((select:any) => { // Access the default values
        return select('core/blocks').getBlockType('scroll-sequence/v2-scene').attributes
    }, []); //DVPT&&console.log('index defaultAttributes',defaultAttributes)

    // ATTRIBUTES 
    const heightWithUnit =      height && heightUnit        ? `${ height }${ heightUnit }`      : String(height);
    const durationWithUnit =    duration && durationUnit    ? `${ duration }${ durationUnit }`  : String(duration);
    const topWithUnit =         top && topUnit              ? `${ top }${ topUnit }`            : String(top);
    const absTopWithUnit =      absTop && absTopUnit        ? `${ absTop }${ absTopUnit }`      : String(absTop);    

    const renderStrings = RenderFunction({attributes, heightWithUnit, durationWithUnit, topWithUnit, absTopWithUnit})


    const elRef = useRef<any>(null)
    const blockProps = useBlockProps({
        className: renderStrings?.bp.class,
        style: renderStrings?.bp.style,
        ref: elRef
    });
    const { children, ...innerBlocksProps } = useInnerBlocksProps( {
        className: renderStrings?.ibp?.class,
        style: renderStrings?.ibp?.style,                    
    } );

    useEffect(() => {
        DVPT&&console.log('scene useEffect - attributes')
        getScrollsequenceFop(elRef.current)?.createBlock(elRef.current)
        return () => {
            DVPT&&console.log('scene useEffect - CLEANUP')
            getScrollsequenceFop(elRef.current)?.destroyBlock(elRef.current)
        };
    }, [attributes]);	

    /**
     * UseEffect to handle scrub changes.
     * - because of GSAP does not allow to change scrub dynamically, we need to re-create all child instances.
     * - TODO: !!! filter out only child instances of the current scene block, not all instances.
     * 
     */
    useEffect(() => {
        DVPT&&console.log('____________________')
        DVPT&&console.log('____________________')
        DVPT&&console.log('scene useEffect - scrub is being changed - EXPENSIVE RE RENDERING _____________', scrub)
        DVPT&&console.log('____________________')
        DVPT&&console.log('____________________')
        // Loop through all child instances and re-create them to give them fresh timelines.
        const arrayOfInstancesMap = getScrollsequenceFop(elRef.current) && Array.from(getScrollsequenceFop(elRef.current).instances); // shallow copy of the Map
        DVPT&&console.log('scene useEffect - arrayOfInstancesMap!!!!!!!!!!!!!!!', arrayOfInstancesMap)
        arrayOfInstancesMap?.forEach((block:any) => {
            const blockKey = block[0];
            const blockValue = block[1];
            // canvas 1d 
            if ( blockValue.elC1d ){
                DVPT&&console.log(' scene useEffect - CHILDREN canvas 1d blockValue.elC1d', blockValue.elC1d)
                getScrollsequenceFop(blockValue.elC1d)?.createBlock(blockValue.elC1d)
                getScrollsequenceFop(blockValue.elC1d)?.preloadAll(); 
            }
            // canvas 2d 
            if ( blockValue.elC2d ){
                DVPT&&console.log(' scene useEffect - CHILDREN canvas 2d blockValue.elC2d', blockValue.elC2d)
                getScrollsequenceFop(blockValue.elC2d)?.createBlock(blockValue.elC2d)
                getScrollsequenceFop(blockValue.elC2d)?.preloadAll(); 
            }
            // canvas 3d 
            if ( blockValue.elC3d ){
                DVPT&&console.log(' scene useEffect - CHILDREN canvas 3d blockValue.elC3d', blockValue.elC3d)
                getScrollsequenceFop(blockValue.elC3d)?.createBlock(blockValue.elC3d)
                getScrollsequenceFop(blockValue.elC3d)?.preloadAll(); 
            }
            // content animation
            if ( blockValue.elCon ){
                DVPT&&console.log(' scene useEffect - CHILDREN content animation blockValue.elCon', blockValue.elCon)
                getScrollsequenceFop(blockValue.elCon)?.createBlock(blockValue.elCon)
                getScrollsequenceFop(blockValue.elCon)?.preloadAll(); 
            }
        });
    }, [scrub]);

    return (
        <>
            <BlockControls
                clientId={clientId}
                attributes={attributes} 
                setAttributes={setAttributes} 
                defaultAttributes={defaultAttributes} 
                hasInnerBlocks={true} // !! todo: this should be dynamic
            />
            <InspectorControls 
                attributes={attributes} 
                setAttributes={setAttributes} 
                defaultAttributes={defaultAttributes} 
            /> 
            
            <div {...blockProps} data-ssq-scene={JSON.stringify({...attributes, stickyType: 'js',})} >
                {renderStrings? (
                    renderStrings?.mid ? (
                        
                        <div className={renderStrings.mid.class} style={renderStrings.mid.style}>
                            <div {...innerBlocksProps} >
                                { children }
                            </div>
                        </div>
                        
                    ) : (
                        
                        <div {...innerBlocksProps} >
                            { children }
                        </div>
                        
                    )
                ) : (
                    <>Attributes Error: Fail to render Scrollsequence Scene </>
                )}
            </div>

        </>
    )
}


