/* eslint-disable  @typescript-eslint/no-explicit-any */
import {
  Fragment,
  memo,
  useEffect,
  useRef,
  useState,
} from 'react'

import { readToken } from 'helpers'

import { API_ROOT } from 'config'
import { usePageParams } from 'hooks/usePageParams'

import { Container } from './styled'
import { CastPlayer } from './CastVideos'
import { useMatchPageStore } from '../MatchPage/store'

type Props = {
  src?: string,
}

const NO_DEVICES_AVAILABLE = 'NO_DEVICES_AVAILABLE'

export const ChromeCast = memo(({ src } : Props) => {
  const [isCastAvailable, setIsCastAvailable] = useState(false)

  const { profile } = useMatchPageStore()
  const { profileId: matchId, sportType } = usePageParams()

  const containerRef = useRef<HTMLDivElement | null>(null)
  const GoogleCastLauncher = (document as any).createElement('google-cast-launcher')
  GoogleCastLauncher.setAttribute('id', 'castbutton')

  const baseUrl = src ?? `${API_ROOT}/video/chromecast/stream/${sportType}/${matchId}.m3u8`
  const urlWithToken = (/\d.m3u8/.test(baseUrl)) ? `${baseUrl}?access_token=${readToken()}` : baseUrl

  const teamsInfo = `${profile?.team1.name_eng} - ${profile?.team2.name_eng}`

  useEffect(() => {
    if (
      containerRef.current
        && GoogleCastLauncher
        && containerRef.current.childNodes.length < 1
    ) {
      (containerRef.current as any).appendChild(GoogleCastLauncher)
    }
  }, [GoogleCastLauncher])

  useEffect(() => {
    const script = document.createElement('script')

    script.src = '//www.gstatic.com/cv/js/sender/v1/cast_sender.js'
    script.async = true

    document.body.appendChild(script)

    const castPlayer = new CastPlayer(urlWithToken, teamsInfo);
    (window as any).__onGCastApiAvailable = (isAvailable: boolean) => {
      if (isAvailable) {
        castPlayer.initializeCastPlayer()

        if ((window as any).cast.framework.CastContext.getInstance().getCastState()
          !== NO_DEVICES_AVAILABLE) {
          setIsCastAvailable(true)
        }
      }
    }

    return () => {
      document.body.removeChild(script)
      setIsCastAvailable(false)
    }
  }, [teamsInfo, urlWithToken])

  return (
    <Fragment>
      {isCastAvailable && <Container ref={containerRef} />}
    </Fragment>
  )
})
