import {useState, useEffect, useRef} from 'react'
import PropTypes from 'prop-types'
import {styled, useTheme} from '@mui/material/styles'
import Box from '@mui/material/Box'
import Typography from '@mui/material/Typography'
import Slider from '@mui/material/Slider'
import IconButton from '@mui/material/IconButton'
import Stack from '@mui/material/Stack'
import PauseRounded from '@mui/icons-material/PauseRounded'
import PlayArrowRounded from '@mui/icons-material/PlayArrowRounded'
import VolumeUpRounded from '@mui/icons-material/VolumeUpRounded'
import VolumeDownRounded from '@mui/icons-material/VolumeDownRounded'
import Image from 'next/image'
import {grey} from '@mui/material/colors'
import {Link} from '@mui/material'

const apiUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:1337'

const Widget = styled('div')(({theme}) => ({
  padding: 16,
  borderRadius: 16,
  width: 343,
  maxWidth: '100%',
  margin: 'auto',
  position: 'relative',
  zIndex: 1,
  backgroundColor:
    theme.palette.mode === 'dark' ? 'rgba(0,0,0,0.6)' : grey[200],
  backdropFilter: 'blur(40px)',
}))

const CoverImage = styled('div')({
  width: 100,
  height: 100,
  objectFit: 'cover',
  overflow: 'hidden',
  flexShrink: 0,
  borderRadius: 8,
  backgroundColor: 'rgba(0,0,0,0.08)',
  '& > img': {
    width: '100%',
  },
})

const TinyText = styled(Typography)({
  fontSize: '0.75rem',
  opacity: 0.38,
  fontWeight: 500,
  letterSpacing: 0.2,
})

export default function Lekte({audio, url, teks}) {
  const audioRef = useRef(new Audio(audio))
  const intervalRef = useRef()
  const isReady = useRef(false)
  const {duration} = audioRef.current
  const theme = useTheme()
  const [position, setPosition] = useState(0)
  const [volume, setVolume] = useState(100)
  const [isPlaying, setIsPlaying] = useState(false)
  const awtis = teks.awtis.map(({alias}) => alias)

  function formatDuration(value) {
    const minute = Math.floor(value / 60)
    const secondLeft = value - (minute * 60)
    if (Number.isNaN(minute) || Number.isNaN(secondLeft)) {
      return 'Information indisponible'
    }

    return `${minute}:${secondLeft <= 9 ? `0${secondLeft}` : secondLeft}`
  }

  const mainIconColor = theme.palette.mode === 'dark' ? '#fff' : '#000'
  const lightIconColor = theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.4)' : grey[900]

  const startTimer = () => {
    clearInterval(intervalRef.current)
    intervalRef.current = setInterval(() => {
      setPosition(Math.round(audioRef.current.currentTime))
    }, [1000])
  }

  useEffect(() => {
    if (isReady.current) {
      audioRef.current.play()
      setIsPlaying(true)
      startTimer()
    } else {
      isReady.current = true
    }
  }, [])

  useEffect(() => {
    if (isPlaying) {
      audioRef.current.play()
    } else {
      audioRef.current.pause()
    }
  }, [isPlaying])

  useEffect(() =>
    () => {
      audioRef.current.pause()
      clearInterval(intervalRef.current)
    }
  , [])

  useEffect(() => {
    if (isPlaying) {
      audioRef.current.play()
      startTimer()
    } else {
      clearInterval(intervalRef.current)
      audioRef.current.pause()
    }
  }, [isPlaying])

  useEffect(() => {
    audioRef.current.pause()
    audioRef.current = new Audio(audio)
    setIsPlaying(false)
    setVolume(100)
    setPosition(0)
  }, [audio])

  const handleChangePosition = value => {
    setPosition(value)
    audioRef.current.currentTime = value
  }

  const handleChangeVolume = value => {
    setVolume(value)
    audioRef.current.volume = value / 100
  }

  return (
    <Box sx={{width: '80%', position: 'relative', zIndex: 0}}>
      <Widget>
        <Box sx={{display: 'flex', alignItems: 'center'}}>
          <CoverImage>
            <Image
              alt={teks.tit}
              src={teks?.kouveti?.formats?.thumbnail ? `${apiUrl}${teks.kouveti.formats.thumbnail.url}` : '/oki-logo-192x192.png'}
              width={teks?.kouveti?.formats?.thumbnail ? teks.kouveti.formats.thumbnail.width : 192}
              height={teks?.kouveti?.formats?.thumbnail ? teks.kouveti.formats.thumbnail.height : 192}
            />
          </CoverImage>
          <Box sx={{ml: 1.5, minWidth: 0}}>
            <Typography fontWeight={500}>
              {new Intl.ListFormat('fr').format(awtis)}
            </Typography>
            <Typography>
              <Link underline='hover' sx={{cursor: 'pointer'}} target='_blank' rel='noreferrer' href={url}>
                <strong>{teks.tit}</strong>
              </Link>
            </Typography>
            <Typography variant='caption'>
              <i>{teks.lanne}</i>
            </Typography>
          </Box>
        </Box>
        <Slider
          aria-label='time-indicator'
          size='small'
          defaultValue={position}
          value={position || 0}
          min={0}
          step={1}
          max={duration || 100}
          sx={{
            color: theme.palette.mode === 'dark' ? '#fff' : 'rgba(0,0,0,0.87)',
            height: 4,
            '& .MuiSlider-thumb': {
              width: 8,
              height: 8,
              transition: '0.3s cubic-bezier(.47,1.64,.41,.8)',
              '&:before': {
                boxShadow: '0 2px 12px 0 rgba(0,0,0,0.4)',
              },
              '&:hover, &.Mui-focusVisible': {
                boxShadow: `0px 0px 0px 8px ${
                  theme.palette.mode === 'dark'
                    ? 'rgb(255 255 255 / 16%)'
                    : 'rgb(0 0 0 / 16%)'
                }`,
              },
              '&.Mui-active': {
                width: 20,
                height: 20,
              },
            },
            '& .MuiSlider-rail': {
              opacity: 0.28,
            },
          }}
          onChange={(_, value) => handleChangePosition(value)}
        />
        <Box
          sx={{
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'space-between',
            mt: -2,
          }}
        >
          <TinyText>{formatDuration(position)}</TinyText>
          <TinyText>-{formatDuration(Math.round(duration) - position)}</TinyText>
        </Box>
        <Box
          sx={{
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            mt: -1,
          }}
        >
          <IconButton
            aria-label={isPlaying ? 'pause' : 'play'}
            onClick={() => setIsPlaying(!isPlaying)}
          >
            {isPlaying ? (
              <PauseRounded sx={{fontSize: '3rem'}} htmlColor={mainIconColor} />
            ) : (
              <PlayArrowRounded
                sx={{fontSize: '3rem'}}
                htmlColor={mainIconColor}
              />
            )}
          </IconButton>
        </Box>
        <Stack spacing={2} direction='row' sx={{mb: 1, px: 1}} alignItems='center'>
          <VolumeDownRounded htmlColor={lightIconColor} />
          <Slider
            aria-label='Volume'
            defaultValue={volume}
            value={volume}
            sx={{
              color: theme.palette.mode === 'dark' ? '#fff' : 'rgba(0,0,0,0.87)',
              '& .MuiSlider-track': {
                border: 'none',
              },
              '& .MuiSlider-thumb': {
                width: 24,
                height: 24,
                backgroundColor: '#fff',
                '&:before': {
                  boxShadow: '0 4px 8px rgba(0,0,0,0.4)',
                },
                '&:hover, &.Mui-focusVisible, &.Mui-active': {
                  boxShadow: 'none',
                },
              },
            }}
            onChange={(_, value) => handleChangeVolume(value)}
          />
          <VolumeUpRounded htmlColor={lightIconColor} />
        </Stack>
      </Widget>
    </Box>
  )
}

Lekte.propTypes = {
  audio: PropTypes.string.isRequired,
  url: PropTypes.string.isRequired,
  teks: PropTypes.object.isRequired
}
