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

import {BlockControls} from '@wordpress/block-editor'
import {Icon, 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 selectIcon = (
    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M6.34326 5.34314L13.0608 21.253L13.4143 12.4142L22.2532 12.0607L6.34326 5.34314Z" fill="#232323" stroke="#232323" stroke-width="2" stroke-linejoin="round"/>
    </svg>
)

const editIcon = (
    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M20.9402 6.06L17.9402 3.06C17.5652 2.685 16.9352 2.685 16.5602 3.06L4.56022 15.06C4.45522 15.165 4.38022 15.3 4.32022 15.435L2.82022 19.935C2.70022 20.28 2.79022 20.67 3.06022 20.94C3.24022 21.12 3.49522 21.225 3.75022 21.225C3.85522 21.225 3.96022 21.21 4.06522 21.18L8.56522 19.68C8.71522 19.635 8.83522 19.545 8.94022 19.44L20.9402 7.44C21.3152 7.065 21.3152 6.435 20.9402 6.06ZM7.72522 17.895L5.29522 18.705L6.10522 16.275L14.2502 8.13L15.8702 9.75L7.72522 17.895ZM17.2502 8.37L15.6302 6.75L17.2502 5.13L18.8702 6.75L17.2502 8.37Z" fill="#232323"/>
    </svg>
)

const EditBlockComponent = (props: any) => {
    const {attributes, setAttributes, isSelected, clientId} = props
    const hasDmChannels = useSelect(
        (sel) => sel(dmProStore).hasDmChannels(),
        []
    )
    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(dmProStore).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 openSelectBlock = () => {
        openVideoSearch()
    }

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

    const onSelected = () => {
        if (isSelected) {
            openVideoSearch()
            // @ts-ignore
            dispatch(dmProStore).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>

                <div className="dm-player__btn-actions">
                    <button
                        className="btn btn-icon btn-select-video"
                        type="button"
                        onClick={openSelectBlock}
                    >
                        {selectIcon}
                        Select
                    </button>
                    {hasDmChannels && (
                        <button
                            className="btn btn-icon btn-open-post-player"
                            type="button"
                            onClick={openPerPostPlayer}
                        >
                            {editIcon}
                            Video Settings
                        </button>
                    )}
                </div>

                {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
