import { useRef, useLayoutEffect, useEffect, useState } from 'react'
type Props = { id:      string,
	       width:   number,
	       height:  number,
	       style?:  CSSProperties }

import type { CSSProperties, FC } from 'react'


export default ((props: Props) => {
  const { id, width, height, style = { } } = props

  const iframeRef = useRef<HTMLIFrameElement> (null)

  const [screenWidth, setScreenWidth] = useState<CSSProperties['width']> ()
  const [screenHeight, setScreenHeight] = useState<CSSProperties['height']> ()
  const [landscape, setLandscape] = useState<boolean> (false)
  const [fullScreen, setFullScreen] = useState<boolean> (false)

  const src = `https://embed.nicovideo.jp/watch/${id}?persistence=1&oldScript=1&referer=&from=0&allowProgrammaticFullScreen=1`;

  const styleFullScreen: CSSProperties = fullScreen ? {
      top:  0,
      left: landscape ? 0 : '100%',
      position: 'fixed',
      width: screenWidth,
      height: screenHeight,
      zIndex: 2147483647,
      maxWidth: 'none',
      transformOrigin: '0% 0%',
      transform: landscape ? 'none' : 'rotate(90deg)',
      WebkitTransformOrigin: '0% 0%',
      WebkitTransform: landscape ? 'none' : 'rotate(90deg)' } : {};

  const margedStyle = {
      border:   'none',
      maxWidth: '100%',
      ...style,
      ...styleFullScreen }

  useEffect (() => {
    const onMessage = (event: MessageEvent<any>) => {
      if (!(iframeRef.current)
	  || (event.source !== iframeRef.current.contentWindow))
	return

      if (event.data.eventName === 'enterProgrammaticFullScreen')
	setFullScreen (true)
      else if (event.data.eventName === 'exitProgrammaticFullScreen')
	setFullScreen (false)
    }

    addEventListener ('message', onMessage)

    return () => removeEventListener ('message', onMessage)
  }, [])

  useLayoutEffect(() => {
    if (!(fullScreen))
      return

    const initialScrollX = scrollX
    const initialScrollY = scrollY
    let timer: NodeJS.Timeout
    let ended = false

    const pollingResize = () => {
      if (ended)
	return

      const landscape = innerWidth >= innerHeight
      const windowWidth = `${landscape ? innerWidth : innerHeight}px`
      const windowHeight = `${landscape ? innerHeight : innerWidth}px`

      setLandscape (landscape)
      setScreenWidth (windowWidth)
      setScreenHeight (windowHeight)
      timer = setTimeout (startPollingResize, 200)
    }

    const startPollingResize = () => {
      if (requestAnimationFrame)
	requestAnimationFrame (pollingResize)
      else
	pollingResize ()
    }

    startPollingResize ()

    return () => {
      clearTimeout (timer)
      ended = true
      scrollTo (initialScrollX, initialScrollY)
    }
  }, [fullScreen])

  useEffect (() => {
    if (!(fullScreen))
      return
    scrollTo (0, 0)
  }, [screenWidth, screenHeight, fullScreen])

  return (
      <iframe ref={iframeRef}
	      src={src}
	      width={width}
	      height={height}
	      style={margedStyle}
	      allowFullScreen
	      allow="autoplay"/>)
}) satisfies FC<Props>
