import * as Sentry from '@sentry/react'
import { Grid, BackgroundImage, Center, Box, Card, Stack, Typography, Flex, Divider } from '@tidbcloud/uikit'
import { Form, FormErrorMessage, FormProps } from '@tidbcloud/uikit/biz'
import { useDebouncedValue } from '@tidbcloud/uikit/hooks'
import { ThemeProvider } from '@tidbcloud/uikit/theme'
import DOMPurify from 'dompurify'
import { trim } from 'lodash-es'
import { observer } from 'mobx-react'
import { useEffect, useState } from 'react'
import { useHistory } from 'react-router-dom'

import { GridWrapper } from 'dbaas/screens/ClustersV2/new/components'
import { CentralAuth0AuditLogReqOperation, updateAuth0AuditLog } from 'dbaas/services'
import { useCreatePlgOnBoardingSurvey } from 'dbaas/services/account'
import { CentralCreatePlgOnBoardingSurveyReq } from 'dbaas/services/account/interface'
import { getErrorMessage } from 'dbaas/services/errorCodes'
import { ExpFeatHashmap, getAuthInfo } from 'dbaas/stores/localStorage'
import { ram } from 'dbaas/stores/ram'
import useStores from 'dbaas/stores/useStores'
import { eventTracking, identifyUser } from 'dbaas/utils/tracking'
import useQuery from 'dbaas/utils/useQuery'
import surveyOrg from 'media/survey-org.jpg'
import rightBgImgLight from 'media/survey-right-bg.svg'

import { markSurveyDone, useSearchCompany } from './helpers'
import { CompanyItem, FormCheckItemGroup, FormAutocomplete, Sector } from './Item'
import { QUESTIONS } from './questions'

const FormWrapper: React.FC<React.PropsWithChildren<FormProps>> = ({ children, actionsProps, ...rest }) => {
  return (
    <Form
      h="100%"
      sx={{ display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}
      actionsProps={{
        mt: 0,
        direction: 'row-reverse',
        gap: 'xs',
        cancelText: 'Skip',
        confirmText: 'Continue',
        ...actionsProps
      }}
      {...rest}
    >
      {children}
    </Form>
  )
}

export const Survey = observer(() => {
  const {
    store: {
      userProfile,
      tenantData: { name: orgName },
      expWhiteList
    },
    actions
  } = useStores()
  const [error, setError] = useState('')
  const [current, setCurrent] = useState(0)
  const [data, setData] = useState<CentralCreatePlgOnBoardingSurveyReq>({
    whyYouWantToUseTiDB: QUESTIONS.whyYouWantToUseTiDB.options[0].value,
    role: [],
    companyName: '',
    companyURL: '',
    usingDatabase: [],
    language: []
  })
  const query = useQuery()
  const trigger = query.get('trigger') || ''
  const history = useHistory()

  const userName = userProfile.first_name
    ? userProfile.first_name + ' ' + userProfile.last_name
    : getAuthInfo().email || ''

  const [company, setCompany] = useState('')
  const [debouncedCompany] = useDebouncedValue(company, 300)
  const { data: companies } = useSearchCompany({ query: debouncedCompany })

  const companyMap =
    companies?.data?.reduce(
      (prev, next) => {
        prev[next.name] = next
        return prev
      },
      {} as Record<string, { name: string; domain: string; logo: string }>
    ) || {}

  const { mutateAsync: sync, isLoading } = useCreatePlgOnBoardingSurvey()

  const onSubmit = async (value: CentralCreatePlgOnBoardingSurveyReq) => {
    if (isLoading) {
      return
    }

    const done = current === Steps.length - 1
    setData({ ...data, ...value })
    if (done) {
      setError('')
      try {
        await sync({ data: { ...data, ...value, status: 'done', trigger } })
        eventTracking('Submitted Survey')
        goNext()
      } catch (e) {
        setError(getErrorMessage(e))
      }
      return
    }
    setCurrent((prev) => prev + 1)
  }

  const goNext = () => {
    markSurveyDone()

    const next = query.get('next')
    // alicloud direct to create cluster page
    if (expWhiteList[ExpFeatHashmap.EnableAlibabaCloudOrgs]) {
      history.replace('/clusters/create-cluster', {
        from: window.location.pathname
      })
      return
    }

    if (next) {
      let nextUrl = decodeURIComponent(next)
      history.replace(nextUrl, {
        from: window.location.pathname
      })
    } else {
      history.replace('/', {
        from: window.location.pathname
      })
    }
  }

  const onCancel = () => {
    eventTracking('Skip Survey')
    setCurrent(stepOne)
  }

  const stepsMap = {
    whyYouWantToUseTiDB: (
      <Flex direction="column" sx={{ position: 'relative' }}>
        <Typography variant="body-lg" sx={{ position: 'absolute', top: -36 }}>
          Hi {trim(userName)}, welcome to TiDB Cloud!
        </Typography>
        <Typography variant="title-lg" fz={20} mb={18}>
          Why are you signing up for TiDB Cloud?
        </Typography>
        <FormCheckItemGroup
          name="whyYouWantToUseTiDB"
          options={QUESTIONS.whyYouWantToUseTiDB.options}
          cols={2}
          w={660}
          itemProps={{
            iconProps: { sx: { '> svg': { width: 40, height: 40 } } },
            descrptionProps: { fw: 700 },
            withCheckbox: false
          }}
        />
      </Flex>
    ),
    role: (
      <Flex direction="column">
        <Typography variant="title-lg" fz={20} mb={18}>
          Which role can best describe you?
        </Typography>
        <FormCheckItemGroup
          name="role"
          options={QUESTIONS.role.options}
          cols={3}
          multiple
          w={740}
          itemProps={{
            p: 16,
            h: 100,
            iconProps: { sx: { '> svg': { width: 24, height: 24 } } }
          }}
        />
      </Flex>
    ),
    usingDatabase: (
      <Flex direction="column">
        <Typography variant="title-lg" fz={20} mb={18}>
          What database management systems are you using now?
        </Typography>
        <FormCheckItemGroup
          name="usingDatabase"
          multiple
          options={QUESTIONS.usingDatabase.options}
          cols={4}
          w={740}
          itemProps={{ p: 16, h: 100 }}
        />
      </Flex>
    ),
    language: (
      <Flex direction="column">
        <Typography variant="title-lg" fz={20} mb={18}>
          Which programming language(s) you prefer to work in?
        </Typography>
        <FormCheckItemGroup
          name="language"
          multiple
          options={QUESTIONS.language.options}
          cols={3}
          w={740}
          itemProps={{ p: 16, h: 100 }}
        />
      </Flex>
    ),
    company: (
      <Flex direction="column" w={700}>
        <Typography variant="title-lg" fz={20} mb="lg">
          What should we call your company?
        </Typography>
        <FormAutocomplete
          name="companyName"
          placeholder="Enter your company name here"
          data={Object.keys(companyMap).map((t) => {
            const company = companyMap[t]
            return {
              value: DOMPurify.sanitize(company.name)
            }
          })}
          onChange={(val) => {
            setCompany(val)
          }}
          onOptionSubmit={(value) => {
            const company = companyMap[value || '']
            setData({ ...data, companyURL: company.domain })
          }}
          renderOption={({ option }) => {
            const data = companyMap[option.value || '']
            return <CompanyItem value={option.value} logo={DOMPurify.sanitize(data.logo)} />
          }}
        />
        <BackgroundImage
          src={surveyOrg}
          w={698}
          h={244}
          sx={() => ({ position: 'relative', overflow: 'hidden' })}
          mt={48}
          mb="lg"
        >
          <Typography
            variant="body-lg"
            fw={500}
            c="carbon.7"
            sx={{ position: 'absolute', top: 42, left: 180, display: 'inline-block' }}
            maw={100}
            truncate
          >
            Default Project
          </Typography>
          <Typography
            variant="body-lg"
            fw={500}
            c="carbon.7"
            sx={{ position: 'absolute', top: 86, left: 180, display: 'inline-block' }}
            maw={100}
            truncate
          >
            {orgName}
          </Typography>
          <Typography
            c="carbon.7"
            variant="body-lg"
            sx={{ position: 'absolute', top: 127, left: 180, display: 'inline-block' }}
            maw={100}
            truncate
          >
            {userName}
          </Typography>
          <Typography
            variant="body-lg"
            c="peacock.7"
            sx={{ position: 'absolute', top: 86, left: 376, display: 'inline-block' }}
            maw={180}
            truncate
          >
            {company || data.companyName || 'Your company'}
          </Typography>
          <Typography
            variant="body-lg"
            c="carbon.7"
            sx={{ position: 'absolute', top: 142, left: 400, display: 'inline-block' }}
            maw={180}
            truncate
          >
            Org Settings
          </Typography>
          <Typography
            variant="body-lg"
            c="carbon.7"
            sx={{ position: 'absolute', top: 187, left: 400, display: 'inline-block' }}
            maw={180}
            truncate
          >
            Billing
          </Typography>
          <Typography
            variant="body-lg"
            c="carbon.7"
            sx={{ position: 'absolute', top: 231, left: 400, display: 'inline-block' }}
            maw={180}
          >
            Console Audit Log
          </Typography>
        </BackgroundImage>
      </Flex>
    )
  }

  const Steps = [
    <FormWrapper
      // make sure put key here to separate form instance
      key="whyYouWantToUseTiDB"
      defaultValues={{
        whyYouWantToUseTiDB: data.whyYouWantToUseTiDB
      }}
      onCancel={onCancel}
      onSubmit={onSubmit}
    >
      {stepsMap.whyYouWantToUseTiDB}
    </FormWrapper>,
    <FormWrapper
      key="role"
      defaultValues={{
        role: data.role
      }}
      onCancel={onCancel}
      onSubmit={onSubmit}
    >
      {stepsMap.role}
    </FormWrapper>,
    <FormWrapper
      key="usingDatabase"
      defaultValues={{
        usingDatabase: data.usingDatabase
      }}
      onCancel={onCancel}
      onSubmit={onSubmit}
    >
      {stepsMap.usingDatabase}
    </FormWrapper>,
    <FormWrapper
      key="language"
      defaultValues={{
        language: data.language
      }}
      onCancel={onCancel}
      onSubmit={onSubmit}
    >
      {stepsMap.language}
    </FormWrapper>,
    <FormWrapper
      key="company"
      defaultValues={{
        companyName: data.companyName
      }}
      onCancel={onCancel}
      onSubmit={onSubmit}
      actionsProps={{
        confirmText: 'Get Started',
        loading: isLoading,
        disabled: !company,
        cancelProps: { display: 'none' }
      }}
    >
      {stepsMap.company}
      {!!error && <FormErrorMessage mt={8} mb={16} message={error} onDismiss={() => setError('')} />}
    </FormWrapper>
  ]

  const stepOne = Steps.length - 1

  useEffect(() => {
    async function fetch() {
      const lastVisit = await actions.fetchLastVisit()

      actions.fetchFeatureList(lastVisit?.org_id)

      actions.fetchUserProfileV2().then((data) => {
        const [user, tenant] = data
        Sentry.setUser({
          id: user.user_id,
          email: user.email
        })

        // logging to mixpanel
        identifyUser(
          { ...user, id: user.user_id },
          { third_party_account_provider: tenant.third_party_account_provider || '' }
        )
        // retrieve billing info
        actions.fetchTenantPlanInfo()
      })
      actions.fetchWhiteList()

      if (ram.get('reportLogin')) {
        eventTracking('Login')
        updateAuth0AuditLog(
          {
            operation: CentralAuth0AuditLogReqOperation.SIGNIN,
            is_success: true,
            failure_info: '',
            org_id: lastVisit.org_id || ''
          },
          { isHandleErr: true }
        )
        ram.clear('reportLogin')
      }
    }
    fetch()
  }, [actions])

  return (
    <ThemeProvider colorScheme="light">
      <Box h="100vh">
        <GridWrapper>
          <Grid columns={5} gutter={0} styles={{ inner: { height: '100%' }, root: { height: '100%' } }}>
            <Grid.Col
              span={3}
              bg="gray.0"
              sx={{
                display: 'flex',
                alignItems: 'center',
                flexDirection: 'column',
                justifyContent: 'center',
                maxHeight: '100%'
              }}
            >
              <Flex direction="column" mih={464} w={740}>
                {Steps[current]}
              </Flex>
            </Grid.Col>
            <Grid.Col span={2} bg="gray.1" sx={{ position: 'relative' }}>
              <BackgroundImage
                src={rightBgImgLight}
                radius={0}
                h="100%"
                sx={{
                  position: 'absolute'
                }}
              />
              <Center p="xl" pb={80} h="100%">
                <Card w={402} px="lg" py={40}>
                  <Stack gap={8}>
                    <Flex gap={8}>
                      <Stack gap={8}>
                        <Sector value={((current + 1) / stepOne) * 100} completed={current + 1 > stepOne} label="1" />
                        <Divider orientation="vertical" h={40} sx={{ alignSelf: 'center' }} />
                      </Stack>
                      <Box>
                        <Typography variant="body-lg" fw={700} c="carbon.9">
                          Tell us about your use case
                        </Typography>
                        <Typography variant="body-sm" c="carbon.7">
                          Tell us a bit more to let us serve you better
                        </Typography>
                      </Box>
                    </Flex>
                    <Flex gap={8}>
                      <Sector
                        value={0}
                        label="2"
                        {...(current + 1 <= stepOne ? {} : { completed: true, onlyText: true })}
                      ></Sector>
                      <Box>
                        <Typography variant="body-lg" fw={700} c="carbon.9">
                          Personalize your project
                        </Typography>
                        <Typography variant="body-sm" c="carbon.7">
                          Get immediate productivity in minutes
                        </Typography>
                      </Box>
                    </Flex>
                  </Stack>
                </Card>
              </Center>
            </Grid.Col>
          </Grid>
        </GridWrapper>
      </Box>
    </ThemeProvider>
  )
})

export default Survey
