import {select, dispatch, subscribe} from "@wordpress/data"
import {useEffect, useRef, useLayoutEffect, useState} from "@wordpress/element"
import {STORE_KEY} from "../../Stores/VideoStore"

import {BlockControls} from '@wordpress/block-editor'
import {ToolbarGroup, ToolbarButton} from '@wordpress/components'
import {search, cog, edit} from '@wordpress/icons'
import React from 'react'
import {fetchApi} from "../../Libs/ApiCall"
import PlayerIdsResponse from "Interfaces/PlayerIdsResponse"
import PlayerIdInterface from "Interfaces/PlayerIdInterface"

const EditBlockComponent = (props: any) => {
    const {attributes, setAttributes, isSelected, clientId} = props
    const getUniquePlayerId = () => `dm-player-${clientId}`
    const isInitialMount = useRef(true)
    const prevVideoRef = useRef(attributes.videoData.id)
    const [playerId, setPlayerId] = useState<PlayerIdInterface[]>([])
    const [videoData, setVideoData] = useState(attributes.videoData)
    const [manualSettings, setManualSettings] = useState(null)
    const [videoSettings, setVideoSettings] = useState({
        player_id: "",
        video_heading: false,
        video_heading_text: "",
        video_title: false
    })

    useLayoutEffect(() => {
        if (isInitialMount.current) {
            onSelected()
            isInitialMount.current = false
        }
    }, []);

    useEffect(() => {
        const fetchManualSettings = async () => {
            try {
                const response = await fetchApi('/dm-pro/v2/get-wp-option?option_name=dm_pro_manual', 'GET')
                if (response) {
                    setManualSettings(response)
                }
            } catch (error) {
                if (!error || error.code !== 'option_not_found') {
                    console.error('Error fetching manual settings:', error)
                }
            }
        }

        fetchManualSettings()
    }, [])

    useEffect(() => {
        const meta = select('core/editor').getEditedPostAttribute('meta')
        if (meta && meta.dmpro_video_settings) {
            // @ts-ignore
            setVideoSettings(meta.dmpro_video_settings)
        }
    }, [])

    useEffect(() => {
        let timeoutId;
        const unsubscribe = subscribe(() => {
            const newMeta = select('core/editor').getEditedPostAttribute('meta')
            if (newMeta && newMeta.dmpro_video_settings) {
                // Clear any pending timeout
                clearTimeout(timeoutId);

                // Set a new timeout
                timeoutId = setTimeout(() => {
                    // @ts-ignore
                    setVideoSettings(newMeta.dmpro_video_settings)
                }, 300); // 300ms debounce
            }
        })

        return () => {
            clearTimeout(timeoutId);
            unsubscribe();
        }
    }, [])


    useEffect(() => {
        const handleVideoUpdate = (e) => {
            if (isSelected) {
                setAttr(e.detail.sender)
            }
        }

        document.addEventListener('dm-video-updated', handleVideoUpdate)

        if (isSelected) {
            onSelected();

            // Use an IIFE
            (async () => {
                await fetchPlayerId()
            })()
        }

        return () => {
            document.removeEventListener('dm-video-updated', handleVideoUpdate)
        }
    }, [isSelected])

    /**
     * This function is called when the video data changes,
     */
    useEffect(() => {
        setVideoData(attributes.videoData)
        const uniquePlayerId = getUniquePlayerId()

        if (attributes.videoData.videos_total) {
            // @ts-ignore
            dailymotion.createPlayer(uniquePlayerId, {
                playlist: (attributes.videoData.private === true) ? attributes.videoData.id : attributes.videoData.id,
            }).then(() => {
                prevVideoRef.current = attributes.videoData.id
            }).catch(error => {
                console.error('Error creating player:', error)
            })
        } else if (attributes.videoData.id) {
            // @ts-ignore
            dailymotion.createPlayer(uniquePlayerId, {
                video: (attributes.videoData.private === true) ? attributes.videoData.private_id : attributes.videoData.id,
            }).then(() => {
                prevVideoRef.current = attributes.videoData.id
            }).catch(error => {
                console.error('Error creating player:', error)
            })
        }

    }, [attributes.videoData])

    const setAttr = async (sender) => {
        const videoData = select(STORE_KEY).getVideoData()
        if (videoData !== undefined) {
            setAttributes({ videoData: videoData });
        }
    }

    const openVideoSearch = () => {
        const videoSearch: HTMLDivElement = document.querySelector('.dm-pro-video-search')

        if (!videoSearch) {
            const dmButton: HTMLButtonElement = document.querySelector('button[aria-label="Video Search"]')
            dmButton.click()
        }
    }

    const openPerPostPlayer = () => {
        setTimeout(() => {
            const perPostPlayer: HTMLElement = document.querySelector('.video-settings-overlay')
            perPostPlayer.classList.toggle('show');
        }, 100);
    }

    const onSelected = () => {
        if (isSelected) {
            openVideoSearch()
            // @ts-ignore
            dispatch(STORE_KEY).setVideo(attributes.videoData)

            // Send custom event to catch on VideoBlockComponent to render a new video
            const videoActive = new CustomEvent("dm-video-active")
            document.dispatchEvent(videoActive)
        }
    }

    const fetchPlayerId = async () => {
        try {
            const response = await fetchApi('/dm-pro/v2/get-player-ids', 'GET') as PlayerIdsResponse

            if (response && Array.isArray(response.ids)) {
                setPlayerId(response.ids);
            } else {
                setPlayerId([])
            }
        } catch (error) {
            setPlayerId([])
            console.error('Error fetching player IDs:', error)
        }
    }


    const setPlayerAttributes = () => {
        let attrs = {}
        return attrs
    }

    const generateVideoContainer = () => {
        const uniquePlayerId = getUniquePlayerId();

        return <div id={uniquePlayerId}></div>
    }

    const renderHeading = () => {
        let headingText = ""

        if (videoSettings.player_id === '' && manualSettings && manualSettings.manual_video_heading && manualSettings.manual_video_heading_text) {
            headingText = manualSettings.manual_video_heading_text
        }

        if (videoSettings.player_id && videoSettings.video_heading && videoSettings.video_heading_text) {
            headingText = videoSettings.video_heading_text
        }

        if (headingText === "") {
            return null
        }

        return <h3 className="video-heading">{headingText}</h3>
    }

    return (

        <figure className="dm-player__holder  dm-pro-tokens">

            { renderHeading() }
            <div className="video-player-wrapper">
                <div className="text-holder">
                    <h3 className="hero-text">Click here <br/> to start embedding content</h3>
                    <p className="outstanding-text">Press anywhere</p>
                </div>
                <BlockControls>
                    <ToolbarGroup>
                        <ToolbarButton
                            icon={search}
                            label="Search Dailymotion videos"
                            onClick={openVideoSearch}
                        />
                        {playerId.length > 0 && (
                            <ToolbarButton
                            icon={cog}
                            label="Set up player id"
                            onClick={openPerPostPlayer}></ToolbarButton>
                        )}
                    </ToolbarGroup>
                </BlockControls>

                <button className="btn btn-open-post-player" type="button" onClick={openPerPostPlayer}>{edit} Video Settings</button>

                {generateVideoContainer()}
            </div>

            {((videoSettings.player_id && videoSettings.video_title) || (videoSettings.player_id === '' && manualSettings && manualSettings.manual_video_title)) && (
                <figcaption className="dm__video-title wp-element-caption">{attributes.videoData.title}</figcaption>
            )}
        </figure>

    )
}

export default EditBlockComponent
