import { Box, Card, Divider, Text, CardProps, Flex } from '@tidbcloud/uikit'
import { Form } from '@tidbcloud/uikit/biz'
import { sha256 } from 'js-sha256'
import { capitalize } from 'lodash-es'
import { Suspense, useEffect, useState } from 'react'
import { useHistory } from 'react-router-dom'

import config from 'config'
import { Logo } from 'dbaas/components'
import Link from 'dbaas/components/Link'
import PageLoader from 'dbaas/components/Placeholder'
import { useIsMdScreen } from 'dbaas/screens/OAuth/Components/helpers'
import { registration } from 'dbaas/services/account'
import { CentralRegistrationReq, RegistrationReqConnectionType } from 'dbaas/services/account/interface'
import auth from 'dbaas/services/auth'
import {
  getSignupProductType,
  getSSOSource,
  removeSignupPlan,
  removeSSOItem,
  setChannelLanding,
  setSignupPlan
} from 'dbaas/stores/localStorage'
import { isPoC } from 'dbaas/utils/chore'
import {
  buildLakeConnectUrlFromSearch,
  getLakeConnectIntentFromSearch,
  getLakeConnectTrackingProperties
} from 'dbaas/utils/lake-connect'
import { useThirdParty } from 'dbaas/utils/marketplace'
import {
  eventTracking,
  getUTMSource,
  MixpanelEvents,
  PRODUCT_TYPES,
  REGISTER_TYPES,
  reportGA,
  reportSignup
} from 'dbaas/utils/tracking'
import { useGAPageView } from 'dbaas/utils/tracking/usePageViewTracking'
import TiDBCloudLogo from 'media/logo/tidb-cloud-logo-v2.svg'

import { AcceptServices, MSPAgreement } from '../Common/AcceptServices'
import { BackgroundMask } from '../Common/Background'
import { useChat2QueryParams } from '../Common/Chat2Query'
import { SSO_SIGNUP_PATTERN } from '../InviteeAccepting/constants'
import { useInviteeAccepting } from '../InviteeAccepting/hooks'

export interface RegisterData {
  company: string
  country: string
  phone_number: string
  accept_service: boolean
}

export const SignUpVendorCallback = () => {
  const history = useHistory()
  const [loading, setLoading] = useState(false)
  const params = new URLSearchParams(window.location.search)
  const { accountProvider, accountToken, freeTrial, msp } = useThirdParty(params)
  const plan = params.get('plan') || ''
  const isMd = useIsMdScreen()

  const { forChat2Query } = useChat2QueryParams()

  const { enabled: inviteeAcceptingEnabled, handler: handleInviteeAccepting } = useInviteeAccepting(
    params.get(SSO_SIGNUP_PATTERN) || ''
  )

  const handleAcceptInvitationSubmit = async () => {
    if (loading) {
      return
    }

    setLoading(true)

    const { accepted, isError, errorMsg } = await handleInviteeAccepting()

    setLoading(false)

    if (isError) {
      throw new Error(errorMsg)
    } else if (accepted) {
      history.push('/')
    }
  }

  const utm = getUTMSource()

  const handleRegistrationSubmit = async (data: RegisterData) => {
    if (loading) {
      return
    }
    setLoading(true)
    const query = new URLSearchParams(window.location.search)
    const connectionType = auth.getConnectionType()
    const fromOAuth = query.has('returnTo') && query.get('returnTo')?.includes('oauth')
    const submitData: CentralRegistrationReq = {
      ...data,
      first_name: '',
      last_name: '',
      email: '',
      connection_type: (
        [
          RegistrationReqConnectionType.EMAIL,
          RegistrationReqConnectionType.MICROSOFT,
          RegistrationReqConnectionType.GITHUB,
          RegistrationReqConnectionType.GOOGLE
        ] as RegistrationReqConnectionType[]
      ).includes(connectionType as RegistrationReqConnectionType)
        ? connectionType
        : undefined,
      auth0_token: auth.getToken() || '',
      third_party_account_provider: accountProvider,
      third_party_account_token: accountToken,
      third_party_free_trial: freeTrial,
      recaptcha_response: '',
      job: '',
      password: '',
      country: '',
      source: fromOAuth ? { ...utm, signup_source: 'oauth' } : utm,
      channel: forChat2Query
    }
    try {
      await registration(submitData, {
        timeout: config.SIGNUP_TIMEOUT,
        isHandleErr: true,
        _warningStatus: [400]
      })
      const ssoSource = getSSOSource()
      eventTracking(`${capitalize(connectionType)} SSO Signup`, {
        'Signup Entry': ssoSource,
        channel: utm.utm_source || utm.utm_campaign,
        utm
      })

      const email = localStorage.getItem('sign_in_email') || ''
      const productType = getSignupProductType() || PRODUCT_TYPES.GENERAL_CLOUD

      // report data to hubspot
      reportSignup({
        ...submitData,
        connection_type: connectionType,
        email,
        signupSource: ssoSource || '',
        productType
      })

      // report marketplace user
      if (accountProvider && accountToken) {
        eventTracking('Became A Billed Customer', {
          source: accountProvider
        })
      }
      removeSSOItem()
      setLoading(false)

      // GA SSO Signup Event
      reportGA({
        event: 'ssoRegistrationComplete',
        entry: getSSOSource(),
        channel: utm.utm_source || utm.utm_campaign
      })

      reportGA({
        event: 'sign_up_complete',
        sign_up_form: 'sso',
        user_id: email ? sha256(email) : undefined,
        register_type: REGISTER_TYPES.SSO_REGISTER,
        most_recent_referral_url: utm.most_recent_referral_url,
        website_referrer_url: utm.website_referrer_url,
        product_type: productType
      })

      const configurationId = query.get('configurationId')
      const next = decodeURIComponent(query.get('next') || '')
      const lakeConnectIntent = getLakeConnectIntentFromSearch(query)
      const lakeConnectUrl = buildLakeConnectUrlFromSearch(query)

      if (lakeConnectIntent && lakeConnectUrl) {
        eventTracking(MixpanelEvents.TidbCloudLake.Create.RequestSucceeded, {
          entry: 'sso_signup',
          ...getLakeConnectTrackingProperties(lakeConnectIntent)
        })
        eventTracking(MixpanelEvents.TidbCloudLake.View.EnterClicked, {
          entry: 'sso_signup',
          ...getLakeConnectTrackingProperties(lakeConnectIntent)
        })
        window.location.replace(lakeConnectUrl)
        return
      }

      if (query.has('returnTo')) {
        return history.push(decodeURIComponent(query.get('returnTo') || ''))
      } else if (configurationId && next?.includes('vercel.com')) {
        history.push(`/console/ecosystem/vercel/redirect${window.location.search}`)
      } else {
        if (forChat2Query) {
          setChannelLanding(auth.getAuthInfo().email || '')
          history.push('/landing')
        } else {
          /**
           * Redirect to home page without search params
           * for signed-up users by SSO
           */
          history.push('/')
        }
      }
    } catch (e) {
      setLoading(false)
      eventTracking(`${capitalize(connectionType)} SSO Signup Error`, {
        'Signup Entry': getSSOSource(),
        'Error Message': e,
        channel: utm.utm_source || utm.utm_campaign,
        utm
      })
      throw e
    }
  }

  const onSubmit = async (data: RegisterData) => {
    if (inviteeAcceptingEnabled) {
      return handleAcceptInvitationSubmit()
    } else {
      return handleRegistrationSubmit(data)
    }
  }

  useEffect(() => {
    // only login user can access signup sso
    if (!auth.isAuthenticated()) {
      return history.push('/signup')
    }
    if (isPoC(plan)) {
      setSignupPlan(plan)
    } else {
      removeSignupPlan()
    }
  }, [])

  useGAPageView()

  const cardProps: Omit<CardProps, 'children'> = isMd
    ? {
        shadow: 'none',
        w: 468,
        p: 0
      }
    : {
        shadow: 'none',
        w: 650,
        p: 0
      }

  return (
    <Suspense fallback={<PageLoader />}>
      {auth.isAuthenticated() ? (
        <Box
          bg="carbon.1"
          sx={(theme) => ({
            display: 'flex',
            flexDirection: 'column',
            height: '100vh',
            alignItems: 'center',
            justifyContent: isMd ? 'flex-start' : 'center',
            position: 'relative',
            backgroundColor: theme.white
          })}
        >
          {isMd ? (
            <>
              <Flex justify="center" align="center" pt={24} pb={40}>
                <Logo withText={false} width={40} height={40} viewBox="0 0 50 50" />
              </Flex>
            </>
          ) : (
            <>
              <BackgroundMask></BackgroundMask>
              <Box
                sx={{
                  position: 'absolute',
                  top: 24,
                  left: 24,
                  width: 135,
                  height: 30,
                  background: `url(${TiDBCloudLogo}) center/contain no-repeat`
                }}
              ></Box>
            </>
          )}

          <Card {...cardProps}>
            <Box p={24} pb={0}>
              <Text fw={700} fz={20} lh={'30px'} color="carbon.9">
                {forChat2Query ? 'Welcome to TiDB Cloud' : 'Accept TiDB Cloud Terms'}
              </Text>
              <Text fw={400} fz={14} lh="20px" mt={24} color="carbon.8">
                {forChat2Query
                  ? 'Now TiDB Cloud is powered by AI, which will revolutionize the way to gain instant insight from your data. With AI empowered, you can get 10X productivity and make your imagination real.'
                  : 'Please acknowledge the following terms to finish creating your account.'}
              </Text>
            </Box>
            <Form<RegisterData>
              onSubmit={onSubmit}
              formMode={'onSubmit'}
              defaultValues={{
                company: '',
                country: '',
                phone_number: '',
                accept_service: false
              }}
              errorMessageProps={{
                mx: 24
              }}
              actionsProps={{
                px: 24,
                pb: 24,
                cancelProps: {
                  onClick: () => {
                    eventTracking('Sign Up SSO Cancel Button Clicked')
                    auth.logout('/signup')
                  }
                },
                confirmProps: {
                  onClick: () => {
                    eventTracking('Sign Up SSO Submit Button Clicked', {
                      channel: utm.utm_source || utm.utm_campaign,
                      utm
                    })
                  }
                },
                confirmText: 'Get Started'
              }}
            >
              {!!msp ? (
                <Box p={24}>
                  <MSPAgreement
                    agreement={
                      'I agree that my TiDB Cloud account is now through a managed service provider and is solely subject to the terms and conditions between my organization and the managed service provider. '
                    }
                  />
                </Box>
              ) : (
                <AcceptServices
                  mb={0}
                  p={24}
                  onChange={(value) => {
                    eventTracking(`${value ? 'Checked' : 'Uncheck'} Policy Services`)
                  }}
                  label={
                    forChat2Query ? (
                      <>
                        <Text fw={400} fz={14} lh="20px" color="carbon.8">
                          I agree to the{' '}
                          <Link
                            className="link"
                            href="https://www.pingcap.com/legal/privacy-policy-include-ai-powered-functions"
                            target="_blank"
                            rel="noopener noreferrer"
                            eventName="Privacy Policy Link Clicked"
                            eventParams={{ source: 'Sign Up' }}
                          >
                            Privacy Policy
                          </Link>{' '}
                          and{' '}
                          <Link
                            className="link"
                            href="https://www.pingcap.com/legal/tidb-cloud-services-agreement"
                            target="_blank"
                            rel="noopener noreferrer"
                            eventName="Services Agreement Link Clicked"
                            eventParams={{ source: 'Sign Up' }}
                          >
                            Services Agreement
                          </Link>{' '}
                          and create a TiDB Cloud account.
                        </Text>
                      </>
                    ) : null
                  }
                />
              )}
              <Divider></Divider>
            </Form>
          </Card>
        </Box>
      ) : null}
    </Suspense>
  )
}

export default SignUpVendorCallback
