import { useContext, useEffect, useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { Flex, Card, Alert, Button } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import { customAlphabet } from 'nanoid'
import AuthParticles from './AppParticles'
import FarmControlLogo from '../Logos/FarmControlLogo'
import ExclamationOctagonIcon from '../Icons/ExclamationOctagonIcon'
import CheckIcon from '../Icons/CheckIcon'
import ReloadIcon from '../Icons/ReloadIcon'
import { ApiServerContext } from '../Dashboard/context/ApiServerContext'

const createLaunchSession = customAlphabet(
  '01abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
  32
)

const AuthLaunch = () => {
  const location = useLocation()
  const hasRedirected = useRef(false)
  const startTimeoutRef = useRef(null)
  const pollTimeoutRef = useRef(null)
  const { getAppLaunchSession } = useContext(ApiServerContext)
  const [launchError, setLaunchError] = useState(false)
  const [launchErrorMessage, setLaunchErrorMessage] = useState('')
  const [launchSuccess, setLaunchSuccess] = useState(false)

  const handleRefresh = () => {
    window.location.reload()
  }

  useEffect(() => {
    let cancelled = false
    const redirect = new URLSearchParams(location.search).get('redirect')
    const redirectType = new URLSearchParams(location.search).get(
      'redirectType'
    )

    if (!redirect) {
      setLaunchError(true)
      setLaunchErrorMessage('No redirect provided!')
      return
    }

    if (!redirect || hasRedirected.current) {
      return
    }

    startTimeoutRef.current = setTimeout(() => {
      if (cancelled) {
        return
      }

      hasRedirected.current = true
      const launchSession = createLaunchSession()
      let launchCheckCount = 0

      setLaunchError(false)
      setLaunchErrorMessage('')
      setLaunchSuccess(false)

      let redirectWithLaunchSession = redirect
      try {
        const redirectUrl = new URL(redirect, window.location.origin)
        redirectUrl.searchParams.set('launchSession', launchSession)
        redirectWithLaunchSession = redirectUrl.toString()
      } catch {
        const hasQuery = redirect.includes('?')
        const separator = hasQuery ? '&' : '?'
        redirectWithLaunchSession = `${redirect}${separator}launchSession=${encodeURIComponent(
          launchSession
        )}`
      }

      const link = document.createElement('a')
      link.href = redirectWithLaunchSession
      link.style.display = 'none'

      if (redirectType === 'app-localhost') {
        link.addEventListener('click', (event) => {
          event.preventDefault()
          window.open(
            redirectWithLaunchSession,
            'farmcontrol-launch',
            'width=480,height=640,menubar=no,toolbar=no,location=yes,status=no,resizable=yes,scrollbars=yes'
          )
        })
      }

      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)

      const checkLaunchSession = async () => {
        launchCheckCount += 1

        let launchComplete = false

        try {
          const launchStatus = await getAppLaunchSession(launchSession)
          launchComplete = launchStatus?.complete === true
        } catch {
          launchComplete = false
        }

        if (cancelled) {
          return
        }

        if (launchComplete) {
          setLaunchSuccess(true)
          return
        }

        if (launchCheckCount >= 10) {
          setLaunchError(true)
          setLaunchErrorMessage('Failed to open Farm Control.')
          return
        }

        pollTimeoutRef.current = setTimeout(() => {
          checkLaunchSession()
        }, 1000)
      }

      checkLaunchSession()
    }, 0)

    return () => {
      cancelled = true
      hasRedirected.current = false
      if (startTimeoutRef.current) {
        clearTimeout(startTimeoutRef.current)
      }
      if (pollTimeoutRef.current) {
        clearTimeout(pollTimeoutRef.current)
      }
    }
  }, [getAppLaunchSession, location.search])

  return (
    <div
      style={{
        backgroundColor: 'black'
      }}
    >
      <div
        style={{
          backgroundColor: 'black',
          minHeight: '100vh',
          transition: 'opacity 0.5s ease-in-out',
          opacity: 1
        }}
      >
        <AuthParticles />
        <Flex
          align='center'
          justify='center'
          vertical
          style={{ height: '100vh' }}
          gap={'large'}
        >
          <Card style={{ borderRadius: 20 }}>
            <Flex vertical align='center'>
              <FarmControlLogo style={{ fontSize: '500px', height: '40px' }} />
            </Flex>
          </Card>
          {!launchError && !launchSuccess && (
            <Alert
              message='Launching Farm Control please wait...'
              icon={<LoadingOutlined />}
              showIcon
            />
          )}
          {launchError && (
            <>
              <Alert
                message={launchErrorMessage}
                icon={<ExclamationOctagonIcon />}
                type='error'
                showIcon
              />
              <Button
                icon={<ReloadIcon />}
                onClick={handleRefresh}
                size='large'
              />
            </>
          )}
          {launchSuccess && (
            <Alert
              message='Launch successful! You may now close this window.'
              icon={<CheckIcon />}
              type='success'
              showIcon
            />
          )}
        </Flex>
      </div>
    </div>
  )
}

export default AuthLaunch
