import { YStack, Text, Button, CameraView, Comment } from '@my/ui'
import { useIsFocused } from '@react-navigation/native'
import { useCameraStream } from 'app/utils/camera/useCameraStream'
import { getServerAddress } from 'app/utils/getServerAddress'
import { useState, useEffect, useCallback } from 'react'
import { AppState } from 'react-native'
import { mediaDevices, RTCView, MediaStream } from 'react-native-webrtc'
import { useRouter } from 'solito/router'

export const CameraScreen = () => {
  const router = useRouter()
  const isFocused = useIsFocused()
  const [appState, setAppState] = useState(AppState.currentState)
  const isActive = isFocused && appState === 'active'
  const [hasPermission, setHasPermission] = useState(false)
  const [localStream, setLocalStream] = useState<MediaStream | null>(null)
  const [isFrontCamera, setIsFrontCamera] = useState(false)
  const [commentsQueue, setCommentsQueue] = useState<Comment[]>([])

  const serverAddress = getServerAddress()

  useCameraStream(localStream, setCommentsQueue, serverAddress)

  const getMediaStream = async (isFrontFacing: boolean) => {
    try {
      const stream = await mediaDevices.getUserMedia({
        audio: false,
        video: {
          frameRate: 30,
          facingMode: isFrontFacing ? 'user' : 'environment',
        },
      })
      return stream
    } catch (err) {
      console.error('Failed to get media stream:', err)
      return null
    }
  }

  const endMediaStream = useCallback(() => {
    if (!localStream) return
    localStream.getTracks().forEach((track) => {
      track.stop()
      track.enabled = false
    })
    setLocalStream(null)
  }, [])

  useEffect(() => {
    const subscription = AppState.addEventListener('change', (nextState) => {
      setAppState(nextState)
      if (nextState === 'background' || nextState === 'inactive') {
        if (localStream) {
          endMediaStream()
        }
      }
    })
    return () => subscription.remove()
  }, [endMediaStream])

  useEffect(() => {
    const startCameraStream = async () => {
      try {
        if (localStream) {
          endMediaStream()
        }

        const stream = await getMediaStream(isFrontCamera)
        if (stream) {
          setLocalStream(stream)
        }
      } catch (err) {
        console.error('Failed to start camera:', err)
      }
    }

    if (hasPermission && isActive) {
      startCameraStream()
    }

    return () => {
      if (localStream) {
        endMediaStream()
      }
    }
  }, [hasPermission, isFrontCamera, isActive, endMediaStream])

  const handleFlipCamera = useCallback(() => {
    setIsFrontCamera(!isFrontCamera)
  }, [])

  const requestPermission = async () => {
    try {
      const testStream = await getMediaStream(isFrontCamera)
      if (testStream) {
        testStream.getTracks().forEach((track) => track.stop())

        setHasPermission(true)
      }
    } catch (err) {
      console.error('No camera permission:', err)
      setHasPermission(false)
    }
  }

  useEffect(() => {
    requestPermission()
  }, [])

  if (!hasPermission) {
    return (
      <YStack
        f={1}
        ai="center"
        jc="center"
      >
        <Text>No camera permission</Text>
        <Button onPress={requestPermission}>Add Camera Permission</Button>
      </YStack>
    )
  }

  return (
    <CameraView
      onCloseCamera={() => {
        endMediaStream()
        router.back()
      }}
      onFlipCamera={handleFlipCamera}
      commentsQueue={commentsQueue}
      setCommentsQueue={setCommentsQueue}
    >
      {localStream && (
        <RTCView
          mirror={isFrontCamera}
          objectFit="cover"
          streamURL={localStream.toURL()}
          style={{ flex: 1 }}
        />
      )}
    </CameraView>
  )
}
