import { useEffect, useState } from 'react';
import { useRoute, useNavigation } from '@react-navigation/native';

import { View } from '@/components/shared/Themed';
import styled from '@emotion/native';
import TimerContent from '@/components/useCases/timer/view/TimerContent';
import FinishContent from '@/components/useCases/timer/view/FinishContent';
import { TimerBgColor } from '@/components/useCases/timer/business/type';
import { Audio } from 'expo-av';
import { Sound } from 'expo-av/build/Audio';
import { activateKeepAwakeAsync, deactivateKeepAwake } from 'expo-keep-awake';
import { loadUserSettings } from '@/components/shared/business/AsyncStorage';
import BackgroundTimer from 'react-native-background-timer';
import { useAudio } from '@/components/useCases/timer/business/useAudio';

interface TimerProps {
  reps: number;
  restTime: number;
  workTime: number;
}

export default function Timer() {
  const navigation = useNavigation();
  const route = useRoute();

  const { reps, restTime, workTime } = route.params as TimerProps;
  const [currentRep, setCurrentRep] = useState<number>(0);
  const [timeLeft, setTimeLeft] = useState<number>(0);
  const [isWorkPhase, setIsWorkPhase] = useState<boolean>(true);
  const [isRunning, setIsRunning] = useState<boolean>(false);
  const [isFinish, setIsFinish] = useState<boolean>(false);
  const [soundEnabled, setSoundEnabled] = useState<boolean>(true);
  const { playSound } = useAudio(require('../assets/audios/boxingBell.mp3'), soundEnabled);

  useEffect(() => {
    const init = async () => {
      try {
        const soundEnabledLocal = await loadUserSettings('soundEnabled');
        setSoundEnabled(Boolean(Number(soundEnabledLocal)));

        handleStart();
        await activateKeepAwakeAsync();
      } catch (error) {
        throw new Error('Erreur lors du chargement des paramètres utilisateur');
      }
    };

    init();
  }, []);

  // when the user exits the screen, desactivate the keepAwake
  useEffect(() => {
    const unsubscribe = navigation.addListener('beforeRemove', (_) => {
      deactivateKeepAwake();
    });

    return unsubscribe;
  }, [navigation]);

  useEffect(() => {
    let timerId: number | null = null;

    if (isRunning && timeLeft > 0) {
      timerId = BackgroundTimer.setInterval(() => {
        setTimeLeft((prevTime) => prevTime - 1);
      }, 1000);
    } else if (isRunning && timeLeft === 0) {
      nextRep();
    }

    return () => {
      if (timerId !== null) {
        BackgroundTimer.clearInterval(timerId);
      }
    };
  }, [isRunning, timeLeft]);

  const handleStart = () => {
    setCurrentRep(1);
    setIsWorkPhase(true);
    setTimeLeft(workTime);
    setIsRunning(true);
    setIsFinish(false);
  };

  const nextRep = () => {
    if (currentRep < reps) {
      if (isWorkPhase) {
        playSound();
        setIsWorkPhase(false);
        setTimeLeft(restTime);
      } else {
        playSound();
        setIsWorkPhase(true);
        setTimeLeft(workTime);
        setCurrentRep((prevRep) => prevRep + 1);
      }
    } else {
      playSound();
      setIsFinish(true);
      setIsRunning(false);
    }
  };

  const previousRep = () => {
    if (isWorkPhase) {
      if (currentRep > 1) {
        setIsWorkPhase(false);
        setTimeLeft(restTime);
        setCurrentRep((prevRep) => prevRep - 1);
      }
    } else {
      setIsWorkPhase(true);
      setTimeLeft(workTime);
    }
  };

  const handleContine = () => {
    setIsRunning(true);
  };

  const handleStop = () => {
    setIsRunning(false);
  };

  const renderBgColor: () => TimerBgColor = () => {
    if (isFinish) return 'black';
    if (isWorkPhase) return 'red';

    return 'green';
  }

  return (
    <Container bgColor={renderBgColor()}>
      {isFinish && (
        <FinishContent handleStart={handleStart} />
      )}

      {!isFinish && (
        <TimerContent
          isWorkPhase={isWorkPhase}
          timeLeft={timeLeft}
          reps={reps}
          bgColor={renderBgColor()}
          currentRep={currentRep}
          isRunning={isRunning}
          nextRep={nextRep}
          previousRep={previousRep}
          handleStop={handleStop}
          handleContine={handleContine}
        />
      )}
    </Container>
  );
}

const Container = styled(View)<{ bgColor: TimerBgColor }>(({ theme, bgColor }) => ({
  flex: 1,
  alignItems: 'center',
  justifyContent: 'center',
  backgroundColor: theme.colors[bgColor]
}));
