import 'antd/dist/antd.less'
import { AutoSaveProvider } from 'components/AutoSaveProvider'
import ModulesProvider from 'components/ModulesProvider'
import NotSupportSizeBrowser from 'components/NotSupportSizeBrowser'
import Loading from 'components/Loading'
import { ExchangeRateDefault } from 'constants/exchange-rate'
import 'fonts/SFProDisplay/stylesheet.scss'
import { useNotificationRequest, useWindowSize } from 'hooks'
import { useQuery } from 'hooks/useQuery'
import Cookies from 'js-cookie'
import LogRocket from 'logrocket'
import { getCorrelationId } from '@komi-app/correlation'
import moment from 'moment'
import { updateTalentProfileActions } from 'pages/BecomeATalent/Reducer/action'
import React, { useEffect, useState } from 'react'
import { isMobile } from 'react-device-detect'
import { useDispatch } from 'react-redux'
import { Link, useHistory, useLocation } from 'react-router-dom'
import { useTypedSelector } from 'redux/rootReducer'
import {
  detectLocalCurrencyActions,
  getExchangeRateActions,
  getExchangeRateUSDActions,
  getUserProfileActions
} from 'redux/User/actions'
import {
  selectIsAdminLogin,
  selectIsCheckLocalCurrency,
  selectUserData,
  selectUserState
} from 'redux/User/selector'
import Routes from 'routes'

import { KOMI_TALENT_CURRENCY } from 'services/UserService'
import { IframeMessage } from 'utils/iframeMessage'
import 'video.js/dist/video-js.css'
import './App.scss'
import '@komi-app/creator-ui/dist/style.css'
import './i18n'
import { webviewMessage } from './utils/webviewMessage'
import '@komi-app/components/dist/index.css'
import { UserAgentProvider } from 'context/user-agent'
import config from 'config'
import { initProfileId, linkRedirectService } from 'services'
import { useLinkRedirect } from 'context/LinkRedirectContext'
import { TALENT_PROFILE_ID } from 'constants/profile'

import {
  KOMI_SPOTIFY_ACCESS_TOKEN,
  KOMI_SPOTIFY_REFRESH_TOKEN
} from './services/SpotifyService'
import useMobileView from 'hooks/useMobileView'
import { setupLink, ToastContextProvider } from '@komi-app/creator-ui'

import {
  FLAGS,
  IfFeature,
  isReady,
  useFeatureIsOn,
  useFlags
} from '@komi-app/flags-sdk'
import When from '@komi-app/when'
import {
  CreatorTrackingProvider,
  CreatorTrackingProps
} from '@komi-app/analytics-sdk'
import { useIntercomMessengerWidget } from './hooks/useIntercomMessengerWidget'
import ErrorBoundary from 'components/ErrorBoundary/ErrorBoundary'

setupLink(Link)

LogRocket.init(config.logRocket.id, {
  rootHostname: 'komi.io',
  dom: {
    privateAttributeBlocklist: ['data-no-track']
  }
})
const KOMI_FIRST_SETUP_ONBOARDING = 'KOMI_FIRST_SETUP_ONBOARDING'

function isMobileEnabledPath(path: string | undefined) {
  if (!path) {
    return false
  }
  return (
    path === '/admin/send-login-link' || path.startsWith('/admin/onboarding')
  )
}

const App = () => {
  const detectCurrency = useTypedSelector(selectIsCheckLocalCurrency)
  const isAdminLogin = useTypedSelector(selectIsAdminLogin)
  const user = useTypedSelector(selectUserData)
  const userState = useTypedSelector(selectUserState)
  const location = useLocation()
  const query = useQuery()
  //TODO: replace the below accessTokens
  const accessToken = query?.get('access_token') // redirect from admin
  const token = query?.get('token') // redirect from consumer
  const talentProfileId = query?.get('talentProfileId') // redirect from consumer
  const router = useHistory()
  const [isNotSetup, setIsNotSetup] = useState(false)
  const [firstRoute, setFirstRoute] = useState<any>()
  const { width } = useWindowSize()
  const { setLinkRedirect } = useLinkRedirect()

  useFlags(
    gb => {
      if (user)
        gb.setAttributes({
          ...gb.getAttributes(),
          tier: user.tier
        })
    },
    [user]
  )

  const isLinkRedirectOn = useFeatureIsOn(FLAGS.LINK_REDIRECT)
  const isSpotifyFixOn = useFeatureIsOn(FLAGS.FIX_GS46_SPOTIFY_AUTH_FIX)
  const mobileView = useMobileView()
  const [shouldDisableScreenSizeError, setShouldDisableScreenSizeError] =
    useState(false)
  const isNotSupport = mobileView ? false : width && width < 1040

  const useAnalyticsSDK = useFeatureIsOn(FLAGS.USE_ANALYTICS_SDK_TALENT)
  const isAnonIdFixOn = useFeatureIsOn(FLAGS.FIX_SB_1274_ANON_ID_RESET_TALENT)
  const shouldRemoveOldAnonIdCookie = useFeatureIsOn(
    FLAGS.FIX_SB_1274_ANON_ID_REMOVE_OLD_COOKIE
  )

  const [tracking, setTracking] = useState<CreatorTrackingProps>()
  const ready = isReady()

  useIntercomMessengerWidget()

  useEffect(() => {
    setShouldDisableScreenSizeError(
      isMobileEnabledPath(router?.location?.pathname)
    )
  }, [router.location.pathname])

  useEffect(() => {
    setFirstRoute(router?.location?.pathname)
    if (
      firstRoute !== '/collaborator-login' || !isNotSupport
        ? !user
        : !talentProfileId
    ) {
      return
    }
    const checkSetupStatus = () => {
      if (!isNotSupport && user) {
        const { talentProfile } = user

        const isOnboarding =
          talentProfile?.onboardSteps &&
          Object.keys(talentProfile?.onboardSteps).every(
            (key: string) => !(talentProfile?.onboardSteps as any)[key]
          )
        if (isOnboarding && talentProfile) {
          const result = localStorage.getItem(KOMI_FIRST_SETUP_ONBOARDING)
          const data = result ? JSON.parse(result) : {}
          if (!data.items?.includes(talentProfile?.id)) {
            localStorage.setItem(
              KOMI_FIRST_SETUP_ONBOARDING,
              JSON.stringify({
                items: [...(data.items || []), talentProfile?.id]
              })
            )
            setIsNotSetup(true)
            return
          }
        }
        return
      }
      if (talentProfileId) {
        const result = localStorage.getItem(KOMI_FIRST_SETUP_ONBOARDING)
        const data = result ? JSON.parse(result) : {}
        if (!data.items?.includes(talentProfileId)) {
          localStorage.setItem(
            KOMI_FIRST_SETUP_ONBOARDING,
            JSON.stringify({
              items: [...(data.items || []), talentProfileId]
            })
          )
          setIsNotSetup(true)
          return
        }
      }
    }
    checkSetupStatus()
  }, [user, firstRoute, isNotSupport])

  useNotificationRequest()
  const dispatch = useDispatch()
  moment.updateLocale('en-gb', {
    weekdaysMin: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
  })

  useEffect(() => {
    if (!ready || isSpotifyFixOn) {
      return
    }

    if (Cookies.get(KOMI_SPOTIFY_ACCESS_TOKEN)) {
      Cookies.remove(KOMI_SPOTIFY_ACCESS_TOKEN)
    }
    if (Cookies.get(KOMI_SPOTIFY_REFRESH_TOKEN)) {
      Cookies.remove(KOMI_SPOTIFY_REFRESH_TOKEN)
    }
  }, [isSpotifyFixOn, ready])

  useEffect(() => {
    // prevents using talent.*
    //  or local.komi.ci
    const { location } = window
    if (
      location.hostname.startsWith('talent.') ||
      (location.origin === config.service.url && location.pathname === '/')
    ) {
      window.location.href = config.client.url
    }
  }, [])

  useEffect(() => {
    if (user) {
      const profileId = user.talentProfile?.id

      if (profileId) {
        initProfileId(profileId)
        Cookies.set(TALENT_PROFILE_ID, profileId as string)
      }

      if (!isAnonIdFixOn) {
        ;(window as any)?.analytics?.reset()
      }

      if (shouldRemoveOldAnonIdCookie) {
        Cookies.remove('ajs_anonymous_id')
        localStorage.removeItem('ajs_anonymous_id')
      }

      ;(window as any)?.analytics?.identify(user.id, {
        Id: user.id,
        Name: `${user.talentProfile?.firstName} ${user.talentProfile?.lastName}`,
        Email: user.email,
        Platform: webviewMessage.isWebView()
          ? 'Webview'
          : isMobile
            ? 'Responsive'
            : 'Web'
      })
    }
  }, [user])

  useEffect(() => {
    const correlationId =
      sessionStorage.getItem('correlationId') || getCorrelationId()
    sessionStorage.setItem('correlationId', correlationId!)

    LogRocket.identify(
      correlationId!,
      user
        ? {
            name: `${user.talentProfile?.firstName} ${user.talentProfile?.lastName}`,
            email: user?.email || ''
          }
        : undefined
    )
  }, [user])

  useEffect(() => {
    if (ready) dispatch(getUserProfileActions.REQUEST())
  }, [router, dispatch, accessToken, token, ready])

  useEffect(() => {
    if (ready && user && useAnalyticsSDK && !tracking) {
      const userId = user.id!
      const profileId = user.talentProfile?.id!
      const profileName =
        `${user.talentProfile?.firstName} ${user.talentProfile?.lastName}`.trim()
      const userFullname = `${user.firstName} ${user.lastName}`.trim()

      const handle = user.talentProfile?.user?.username!
      const talentId = user.talentProfile?.user?.id!

      setTracking({
        handle,
        profileId,
        profileName,
        userFullname,
        userId,
        talentId
      })
    }
  }, [user, tracking, ready])

  // obsolete?
  useEffect(() => {
    if (detectCurrency) return

    if (user && user.localCurrency) {
      Cookies.set(KOMI_TALENT_CURRENCY, user.localCurrency, {
        expires: 999999
      })
      dispatch(getExchangeRateActions.REQUEST(user.localCurrency))
      dispatch(getExchangeRateUSDActions.REQUEST())
      dispatch(detectLocalCurrencyActions.SUCCESS(true))
    } else if (user && !user.localCurrency && !isAdminLogin) {
      // we will not detect local with expert
      if (IframeMessage.inIframe()) return
      ;(async () => {
        const currency = ExchangeRateDefault.localCurrency
        Cookies.set(KOMI_TALENT_CURRENCY, currency, { expires: 999999 })
        dispatch(
          updateTalentProfileActions.REQUEST({
            localCurrency: currency,
            userState: userState
          })
        )
        dispatch(getExchangeRateActions.REQUEST(currency))
        dispatch(getExchangeRateUSDActions.REQUEST())
      })()
    }

    return () => {}
  }, [dispatch, user, detectCurrency])

  // for Admin (obsolete?)
  useEffect(() => {
    const query = new URLSearchParams(location.search)
    const localCurrency: any = query?.get('localCurrency')
    if (!user || !localCurrency || !IframeMessage.inIframe()) return
    Cookies.set(KOMI_TALENT_CURRENCY, localCurrency, { expires: 999999 })
    dispatch(getExchangeRateActions.REQUEST(localCurrency))
    dispatch(getExchangeRateUSDActions.REQUEST())
  }, [user])

  useEffect(() => {
    if (!isLinkRedirectOn) return
    const loadExistingRedirect = async () => {
      if (user && user.talentProfile) {
        const result = await linkRedirectService().getLinkRedirect()

        let isExistingRedirectExpired = true

        if (
          result?.linkRedirect?.scheduled_end_timestamp != undefined &&
          result?.linkRedirect?.scheduled_timezone != undefined
        ) {
          const linkRedirectDateTimeNow = moment().tz(
            result?.linkRedirect?.scheduled_timezone
          )
          if (
            linkRedirectDateTimeNow.isBefore(
              result?.linkRedirect?.scheduled_end_timestamp
            )
          ) {
            isExistingRedirectExpired = false
          }
        }

        setLinkRedirect({
          link: isExistingRedirectExpired ? '' : result?.linkRedirect?.link,
          scheduledTimezone: isExistingRedirectExpired
            ? ''
            : result?.linkRedirect?.scheduled_timezone,
          scheduledStartTimestamp: isExistingRedirectExpired
            ? moment().valueOf()
            : moment(result?.linkRedirect?.scheduled_start_timestamp).valueOf(),
          scheduledEndTimestamp: isExistingRedirectExpired
            ? moment().add(1, 'days').valueOf()
            : moment(result?.linkRedirect?.scheduled_end_timestamp).valueOf(),
          isEnabled: isExistingRedirectExpired
            ? false
            : result?.linkRedirect?.is_enabled
        })
      }
    }

    loadExistingRedirect()
  }, [setLinkRedirect, user?.talentProfile, isLinkRedirectOn])

  return (
    <ErrorBoundary>
      <CreatorTrackingProvider context={tracking}>
        <IfFeature
          feature={FLAGS.FEAT_SB_331_COPY_URL_PROMPT}
          enabled={
            <When
              value={ready}
              then={
                isNotSupport && !shouldDisableScreenSizeError ? (
                  <NotSupportSizeBrowser isNotSetup={isNotSetup} />
                ) : (
                  <UserAgentProvider>
                    <ToastContextProvider>
                      <AutoSaveProvider>
                        <ModulesProvider>
                          <Routes />
                        </ModulesProvider>
                      </AutoSaveProvider>
                    </ToastContextProvider>
                  </UserAgentProvider>
                )
              }
              otherwise={<Loading />}
            />
          }
          disabled={
            <When
              value={ready}
              then={
                isNotSupport && !shouldDisableScreenSizeError ? (
                  <NotSupportSizeBrowser isNotSetup={isNotSetup} />
                ) : (
                  <UserAgentProvider>
                    <AutoSaveProvider>
                      <ModulesProvider>
                        <ToastContextProvider>
                          <Routes />
                        </ToastContextProvider>
                      </ModulesProvider>
                    </AutoSaveProvider>
                  </UserAgentProvider>
                )
              }
              otherwise={<Loading />}
            />
          }
        />
      </CreatorTrackingProvider>
    </ErrorBoundary>
  )
}

export default App
