import { useEffect, useRef, useState } from 'react';

import { Box, chakra, Flex, IconButton, SliderTrack, Spacer, Text, useBreakpointValue } from '@chakra-ui/react';
import {
  MdFastForward,
  MdFastRewind,
  MdFullscreen,
  MdFullscreenExit,
  MdLooksOne,
  MdNavigateBefore,
  MdNavigateNext,
  MdOutlinePictureInPictureAlt,
  MdPause,
  MdPictureInPictureAlt,
  MdPlayArrow,
  MdRepeat,
  MdRepeatOne,
  MdStop,
  MdTrendingFlat
} from 'react-icons/md';

import { useColorModeValue } from '@/components/ui/color-mode';
import { useActivePlaylistService } from '@/service/ActivePlaylist';
import { useSpecificMedia } from '@/service/Media';
import { useSpecificSeason } from '@/service/Season';
import { useSpecificSeries } from '@/service/Series';
import { useSpecificType } from '@/service/Type';
import { DataUrlAccess } from '@/utils/data-url-access';
import { isNullOrUndefined } from '@/utils/validator';

import { Slider } from './ui/slider';

export enum PlayMode {
  PLAY_ONE,
  PLAY_ALL,
  PLAY_ONE_LOOP,
  PLAY_ALL_LOOP,
}

const playModeIcon = {
  [PlayMode.PLAY_ONE]: <MdLooksOne style={{ width: '100%', height: '100%' }} />,
  [PlayMode.PLAY_ALL]: (
    <MdTrendingFlat style={{ width: '100%', height: '100%' }} />
  ),
  [PlayMode.PLAY_ONE_LOOP]: (
    <MdRepeatOne style={{ width: '100%', height: '100%' }} />
  ),
  [PlayMode.PLAY_ALL_LOOP]: (
    <MdRepeat style={{ width: '100%', height: '100%' }} />
  ),
};

export type AudioPlayerProps = {};

const formatTime = (time) => {
  if (time && !isNaN(time)) {
    const minutes = Math.floor(time / 60);
    const formatMinutes = minutes < 10 ? `0${minutes}` : `${minutes}`;
    const seconds = Math.floor(time % 60);
    const formatSeconds = seconds < 10 ? `0${seconds}` : `${seconds}`;
    return `${formatMinutes}:${formatSeconds}`;
  }
  return '00:00';
};

export const VideoPlayer = ({}: AudioPlayerProps) => {
  const { playMediaList, MediaOffset, previous, next, first, clear } =
    useActivePlaylistService();
  const [time, setTime] = useState(10);
  const [isRunning, setIsRunning] = useState(true);
  useEffect(() => {
    if (!isRunning || time <= 0) {
        console.log(`exit timer`);
        setIsRunning(false);
      return;
    }
    const timer = setInterval(() => {
      setTime((prevTime) => {
        console.log(`current time : ${prevTime}`);
        return prevTime - 1;
    });
    }, 1000);

    return () => clearInterval(timer);
  }, [time, isRunning]);

  const resetTimer = () => {
    if (playMediaList.length !== 0 && !!document.fullscreenElement) {
      setTime(10);
      setIsRunning(true);
    }
  };
  useEffect(() => {
    const resetTimerLocal = () => {
      if (playMediaList.length !== 0 && !!document.fullscreenElement) {
        setTime(10);
        setIsRunning(true);
      }
    };
    window.addEventListener("mousemove", resetTimerLocal);
    return () => {
      window.removeEventListener("mousemove", resetTimerLocal);
    };
  }, [playMediaList, setTime, setIsRunning]);

  const containerRef = useRef<HTMLDivElement>(null);
  const videoRef = useRef<HTMLVideoElement>(null);
  const [isPlaying, setIsPlaying] = useState<boolean>(false);
  const [timeProgress, setTimeProgress] = useState<number>(0);
  const [playingMode, setPlayingMode] = useState<PlayMode>(PlayMode.PLAY_ALL);
  const [duration, setDuration] = useState<number>(0);
  const { dataMedia } = useSpecificMedia(
    MediaOffset !== undefined ? playMediaList[MediaOffset] : undefined
  );
  const { dataSeason } = useSpecificSeason(dataMedia?.seasonId);
  const { dataType } = useSpecificType(dataMedia?.typeId);
  const { dataSeries } = useSpecificSeries(dataMedia?.seriesId);

  const isMobile = useBreakpointValue({ base: true, md: false });
  const [mediaSource, setMediaSource] = useState<string>('');
  useEffect(() => {
    setMediaSource(
      dataMedia && dataMedia?.dataId
        ? DataUrlAccess.getUrl(dataMedia?.dataId)
        : ''
    );
  }, [dataMedia, setMediaSource]);
  const backColor = useColorModeValue('back.100', 'back.800');
  const configButton = isMobile ? {
    borderRadius: 'full',
    backgroundColor: 'transparent',
    _hover: {
      bgColor: 'brand.500',
    },
    width: '35px',
    height: '35px',
    padding: '2px',
  } : {
    borderRadius: 'full',
    backgroundColor: 'transparent',
    _hover: {
      bgColor: 'brand.500',
    },
    width: '50px',
    height: '50px',
    padding: '5px',
  };

  useEffect(() => {
    if (!videoRef || !videoRef.current) {
      return;
    }
    if (isPlaying) {
      videoRef.current.play();
    } else {
      videoRef.current.pause();
    }
  }, [isPlaying, videoRef]);

  const onAudioEnded = () => {
    if (playMediaList.length === 0 || isNullOrUndefined(MediaOffset)) {
      return;
    }
    if (playingMode === PlayMode.PLAY_ALL_LOOP) {
      if (playMediaList.length == MediaOffset + 1) {
        first();
      } else {
        next();
      }
    } else if (playingMode === PlayMode.PLAY_ALL) {
      next();
    } else if (playingMode === PlayMode.PLAY_ONE_LOOP) {
      onSeek(0);
      onPlay();
    }
  };
  const onSeek = (newValue) => {
    console.log(`onSeek: ${newValue}`);
    if (!videoRef || !videoRef.current) {
      return;
    }
    videoRef.current.currentTime = newValue;
  };
  const onPlay = () => {
    if (!videoRef || !videoRef.current) {
      return;
    }
    if (isPlaying) {
      videoRef.current.pause();
    } else {
      videoRef.current.play();
    }
  };
  const onStop = () => {
    if (!videoRef || !videoRef.current) {
      return;
    }
    if (videoRef.current.currentTime <= 0.5 && videoRef.current.paused) {
      clear();
    } else {
      videoRef.current.pause();
      videoRef.current.currentTime = 0;
    }
  };
  const onNavigatePrevious = () => {
    previous();
  };
  const onFastRewind = () => {
    if (!videoRef || !videoRef.current) {
      return;
    }
    videoRef.current.currentTime -= 10;
  };
  const onFastForward = () => {
    if (!videoRef || !videoRef.current) {
      return;
    }
    videoRef.current.currentTime += 10;
  };
  const onNavigateNext = () => {
    next();
  };
  const onTypePlay = () => {
    setPlayingMode((value: PlayMode) => {
      if (value === PlayMode.PLAY_ONE) {
        return PlayMode.PLAY_ALL;
      } else if (value === PlayMode.PLAY_ALL) {
        return PlayMode.PLAY_ONE_LOOP;
      } else if (value === PlayMode.PLAY_ONE_LOOP) {
        return PlayMode.PLAY_ALL_LOOP;
      } else {
        return PlayMode.PLAY_ONE;
      }
    });
  };
  /**
   * Call when meta-data is updated
   */
  function onChangeMetadata(): void {
    const seconds = videoRef.current?.duration;
    if (seconds !== undefined) {
      setDuration(seconds);
    }
  }
  const onTimeUpdate = () => {
    if (!videoRef || !videoRef.current) {
      return;
    }
    //console.log(`onTimeUpdate ${videoRef.current.currentTime}`);
    setTimeProgress(videoRef.current.currentTime);
  };
  const onDurationChange = (event) => {};
  const onChangeStateToPlay = () => {
    setIsPlaying(true);
  };
  const onChangeStateToPause = () => {
    setIsPlaying(false);
  };
  const marks = () => {
    const minutes = Math.floor(duration / 60);
    const result: number[] = [];
    for (let i = 1; i <= minutes; i++) {
      result.push(60 * i);
    }
    return result;
  };
  const onFullScreen = () => {
    if (containerRef.current) {
      if (!document.fullscreenElement) {
        if (containerRef.current.requestFullscreen) {
          resetTimer();
          containerRef.current.requestFullscreen();
        }
      } else {
        document.exitFullscreen();
      }
    }
  };
  const [isPiPSupported, setIsPiPSupported] = useState(false);
  useEffect(() => {
    setIsPiPSupported(!!document.pictureInPictureEnabled);
  }, []);
  const [isPiP, setIsPiP] = useState(false);
  const onPictureInPicture = async () => {
    if (videoRef.current) {
      try {
        if (!isPiP) {
          await videoRef.current.requestPictureInPicture();
          setIsPiP(true);
        } else {
          document.exitPictureInPicture();
          setIsPiP(false);
        }
      } catch (error) {
        console.error("Erreur avec Picture-in-Picture:", error);
      }
    }
  };
  const [isFullScreen, setIsFullScreen] = useState(false);
  useEffect(() => {
    const handleFullScreenChange = () => {
      console.log(`changeFullScreen: ${!!document.fullscreenElement}`)
      setIsFullScreen(!!document.fullscreenElement);
    };

    document.addEventListener("fullscreenchange", handleFullScreenChange);
    return () => {
      document.removeEventListener("fullscreenchange", handleFullScreenChange);
    };
  }, []);
  return (
    <>
      {!isNullOrUndefined(MediaOffset) && (
        <>
        <Flex
          position="absolute"
          //height="500px"
          minHeight="150px"
          paddingY="5px"
          paddingX="10px"
          marginX="15px"
          bottom={0}
          left={0}
          right={0}
          zIndex={1000}
          borderWidth="1px"
          borderColor="brand.900"
          bgColor={isFullScreen ? "0x000000" : backColor}
          borderTopRadius="10px"
          direction="column"
          ref={containerRef}
          >
            <chakra.video
              position={isFullScreen ? "absolute" : "relative"}
              maxHeight={isFullScreen ? undefined : "30vh"}
              maxWidth={isFullScreen ? undefined : "100%"}
              height={isFullScreen ? "100%" : undefined}
              width={isFullScreen ? "100%": undefined}
              marginX="auto"
              src={mediaSource}
              ref={videoRef}
              //preload={true}
              onPlay={onChangeStateToPlay}
              onPause={onChangeStateToPause}
              onTimeUpdate={onTimeUpdate}
              onDurationChange={onDurationChange}
              onLoadedMetadata={onChangeMetadata}
              autoPlay={true}
              onEnded={onAudioEnded}
              />
          {(!isFullScreen || (!isMobile || isRunning)) && <><Text
            alignContent="left"
            fontSize="20px"
            fontWeight="bold"
            userSelect="none"
            marginRight="auto"
            overflow="hidden"
            // noOfLines={1}
            >
            {dataMedia?.name ?? '???'}
          </Text>
          <Text
            alignContent="left"
            fontSize="16px"
            userSelect="none"
            marginRight="auto"
            overflow="hidden"
            // noOfLines={1}
            >
            {dataSeries && dataSeries.name}
            {dataSeason && dataSeason?.name}
            {dataType && ` / ${dataType.name}`}
          </Text>
          {isFullScreen && <Spacer/>}
          <Box width="full" paddingX="15px">
            <Slider
              defaultValue={[0]}
              value={[timeProgress]}
              min={0}
              max={duration}
              step={0.1}
              onValueChange={(e) => onSeek(e.value)}
              variant="outline"
              colorPalette="brand"
              marks={marks()}
              //focusCapture={false}
              >
              <SliderTrack
                bg="brand.200"
                height="10px"
                borderRadius="full"
              ></SliderTrack>
            </Slider>
          </Box>
          <Flex>
            <Text
              alignContent="left"
              fontSize="16px"
              userSelect="none"
              marginRight="auto"
              overflow="hidden"
              // noOfLines={1}
              >
              {formatTime(timeProgress)}
            </Text>
            <Text alignContent="left" fontSize="16px" userSelect="none">
              {formatTime(duration)}
            </Text>
          </Flex>
          <Flex gap="5px">
            <IconButton
              {...configButton}
              aria-label={'Play'}
              onClick={onPlay}
              variant="ghost"
            >
              {isPlaying ? (
                <MdPause style={{ width: '100%', height: '100%' }} />
              ) : (
                <MdPlayArrow style={{ width: '100%', height: '100%' }} />
              )}
            </IconButton>
            <IconButton
              {...configButton}
              aria-label={'Stop'}
              onClick={onStop}
              variant="ghost"
              >
              <MdStop style={{ width: '100%', height: '100%' }} />
            </IconButton>
            <IconButton
              {...configButton}
              aria-label={'Previous Media'}
              onClick={onNavigatePrevious}
              marginLeft="auto"
              variant="ghost"
              >
              <MdNavigateBefore style={{ width: '100%', height: '100%' }} />{' '}
            </IconButton>
            <IconButton
              {...configButton}
              aria-label={'jump 15sec in past'}
              onClick={onFastRewind}
              variant="ghost"
              >
              <MdFastRewind style={{ width: '100%', height: '100%' }} />
            </IconButton>
            <IconButton
              {...configButton}
              aria-label={'jump 15sec in future'}
              onClick={onFastForward}
              variant="ghost"
              >
              <MdFastForward style={{ width: '100%', height: '100%' }} />
            </IconButton>
            <IconButton
              {...configButton}
              aria-label={'Next Media'}
              marginRight="auto"
              onClick={onNavigateNext}
              variant="ghost"
              >
              <MdNavigateNext style={{ width: '100%', height: '100%' }} />
            </IconButton>
            <IconButton
              {...configButton}
              aria-label={'continue to the end'}
              onClick={onTypePlay}
              variant="ghost"
              >
              {playModeIcon[playingMode]}
            </IconButton>
            <IconButton
              {...configButton}
              aria-label={'Fullscreen'}
              onClick={onFullScreen}
              variant="ghost"
              >
                {!!document.fullscreenElement ?
                <MdFullscreenExit style={{ width: '100%', height: '100%' }} />:
                <MdFullscreen style={{ width: '100%', height: '100%' }} />}
            </IconButton>
            {isPiPSupported && !isMobile &&
            <IconButton
              {...configButton}
              aria-label={'Fullscreen'}
              onClick={onPictureInPicture}
              variant="ghost"
              >
                {isPiP ? <MdOutlinePictureInPictureAlt style={{ width: '100%', height: '100%' }} /> : <MdPictureInPictureAlt style={{ width: '100%', height: '100%' }} /> }
            </IconButton>
            }
          </Flex>
          </>}
        </Flex>
      </>
      )}
    </>
  );
};
