import React, { MouseEventHandler, useRef, useState, useEffect } from 'react'
import useRequest from '@ahooksjs/use-request/es'

import dayjs from 'dayjs'
import { PlayCircleOutlined, PauseCircleOutlined } from '@ant-design/icons'
import Fallback15 from 'assets/fallback15.svg'
import Forward15 from 'assets/forward15.svg'

import { IAudioDetail } from 'Activity/Activity.service'
import { MicroRoadshowService } from 'Material/MicroRoadshow.service'
import style from '../css/AudioControler.module.scss'

interface AudioControlerProp {
  audioDetail: IAudioDetail
  isPlay?: boolean
  showType?: 'normal' | 'fixedleft'
}

const AudioControler: React.FC<AudioControlerProp> = ({ audioDetail, isPlay = false, showType = 'normal' }) => {
  const [trackWidth, setTrackWidth] = useState<number>(0)
  const [playSate, setPlayState] = useState<boolean>(isPlay)
  const [audioDuration, setAudioDuration] = useState<number>(0)
  const [audioCurrentTime, setAudioCurrentTime] = useState<number>(0)
  const [mouseIsUp, setMouseIsUp] = useState<boolean>(true)
  const multipleArr = [0.5, 1.0, 1.25, 1.5, 1.75, 2.0] // 语音播放倍数
  const [speakSpeed, setSpeakSpeed] = useState<number>(1.0)

  const progressLineRef = useRef<HTMLDivElement>(null)
  const audioRef = useRef<HTMLAudioElement>(null)

  useEffect(() => {
    const mouseupFn = () => {
      setMouseIsUp(true)
    }
    document.addEventListener('mouseup', mouseupFn, false)
    return document.removeEventListener('mouseup', mouseupFn)
  }, [])
  useEffect(() => {
    if (isPlay && audioDetail) {
      audioDetail?.Type && applyRecord(audioDetail.SourceId || audioDetail.ActivityId, audioDetail?.Type)
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [audioDetail])

  const { run: applyRecord } = useRequest(MicroRoadshowService.postVideoHistory, {
    manual: true
  })

  const handleClickProgress: MouseEventHandler<HTMLDivElement> = e => {
    if (audioRef.current && progressLineRef.current) {
      const progressLineWidth = parseInt(getComputedStyle(progressLineRef.current).width)
      if (e.nativeEvent.offsetX <= progressLineWidth) {
        setTrackWidth(e.nativeEvent.offsetX)
        const targetTime = audioRef.current.duration * (e.nativeEvent.offsetX / progressLineWidth)
        audioRef.current.currentTime = targetTime
      }
    }
  }

  const handleMouseDown: MouseEventHandler<HTMLDivElement> = e => {
    setMouseIsUp(false)
  }

  const handleMouseUp: MouseEventHandler<HTMLDivElement> = e => {
    setMouseIsUp(true)
  }

  const handleMouseMove: MouseEventHandler<HTMLDivElement> = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
    if (!mouseIsUp && audioRef.current && progressLineRef.current) {
      setTrackWidth(e.nativeEvent.offsetX)
      audioRef.current.currentTime =
        audioRef.current.duration * (e.nativeEvent.offsetX / parseInt(getComputedStyle(progressLineRef.current).width))
    }
  }
  // 后退15s
  const handleBack = () => {
    if (audioRef.current && audioCurrentTime > 15) {
      audioRef.current.currentTime = audioCurrentTime - 15
      setAudioCurrentTime(audioCurrentTime - 15)
    }
  }
  // 进15S
  const handleForward = () => {
    if (audioRef.current && audioDuration - audioCurrentTime > 15) {
      audioRef.current.currentTime = audioCurrentTime + 15
      setAudioCurrentTime(audioCurrentTime + 15)
    }
  }
  // 变速
  const handleChangeSpeakSpeed = (speed: number) => {
    const index = multipleArr.indexOf(speed)
    const next = index === multipleArr.length - 1 ? multipleArr[0] : multipleArr[index + 1]
    if (audioRef.current) {
      audioRef.current.playbackRate = next
      setSpeakSpeed(next)
    }
  }
  // 播放，暂停
  const handlePlayOrStop = () => {
    if (playSate) {
      audioRef.current?.pause()
      setPlayState(false)
    } else {
      audioRef.current &&
        parseInt(audioRef.current.currentTime.toString()) === 0 &&
        audioDetail?.Type &&
        applyRecord(audioDetail.SourceId || audioDetail.ActivityId, audioDetail.Type)
      audioRef.current?.play().then(() => {
        setPlayState(true)
      })
    }
  }
  const handlePlayTimeUpdate = (e: React.MouseEvent<HTMLAudioElement, MouseEvent>) => {
    if (audioRef.current && progressLineRef.current) {
      setTrackWidth(
        ((e.target as HTMLAudioElement).currentTime / (e.target as HTMLAudioElement).duration) *
          parseInt(getComputedStyle(progressLineRef.current as HTMLDivElement).width)
      )
      setAudioCurrentTime((e.target as HTMLAudioElement).currentTime)
      if ((e.target as HTMLAudioElement).currentTime >= (e.target as HTMLAudioElement).duration) setPlayState(false)
    }
  }
  if (!audioDetail) return null

  return (
    <>
      <div className={`${style['custom-audio']} ${showType === 'fixedleft' ? style['fixed-left'] : ''}`}>
        {/* 音频进度条 */}
        <div className="audio-name g-ellipsis1 m-l-sm">{audioDetail.Name.replace(/<[^>]+>/g, '')}</div>
        <div
          className="audio-progress"
          onClick={handleClickProgress}
          onMouseDown={handleMouseDown}
          onMouseUp={handleMouseUp}
          onMouseMove={handleMouseMove}
          ref={progressLineRef}
        >
          <div className="slider-rail">
            <div className="slider-track" style={{ width: trackWidth || 0 }}>
              {mouseIsUp && <div className="slider-round" onClick={e => e.stopPropagation()} id="sliderRound" />}
            </div>
          </div>
        </div>
        {/* 时长 */}
        <div className="audio-duration m-l-sm">
          <span className="audio-control-left-current">
            {dayjs(audioCurrentTime * 1000 - 28800000).format(audioCurrentTime >= 3600 ? 'HH:mm:ss' : 'mm:ss')}
          </span>
          /
          <span className="audio-control-left-duration">
            {dayjs(audioDuration * 1000 - 28800000).format(audioDuration >= 3600 ? 'HH:mm:ss' : 'mm:ss')}
          </span>
        </div>
        <div className="audio-play-control">
          <div className="audio-control-other" onClick={handleBack}>
            <img src={Fallback15} alt="回退15秒" className="audio-control-icon" />
          </div>
          <div className="audio-control-center" onClick={handlePlayOrStop}>
            {playSate ? (
              <PauseCircleOutlined className="audio-control-play" color="#ffffff" />
            ) : (
              <PlayCircleOutlined className="audio-control-play" color="#ffffff" />
            )}
          </div>
          <div className="audio-control-other" onClick={handleForward}>
            <img src={Forward15} alt="快进15秒" className="audio-control-icon" />
          </div>
          <div className="audio-multiple m-l-lg" onClick={handleChangeSpeakSpeed.bind(this, speakSpeed)}>
            <span>x {speakSpeed}</span>
          </div>
        </div>
        <audio
          // controls
          preload="metadata"
          ref={audioRef}
          autoPlay={playSate}
          onLoadedMetadataCapture={() => {
            setAudioDuration((audioRef.current as HTMLAudioElement).duration)
          }}
          onTimeUpdate={handlePlayTimeUpdate}
          src={audioDetail.Url}
        ></audio>
      </div>
    </>
  )
}

export default AudioControler
