import { Group, Typography, Flex, Box, Button } from '@tidbcloud/uikit'
import { Form, FormPasswordInput, FormProps, FormTextInput } from '@tidbcloud/uikit/biz'
import { IconArrowLeft, IconMail02 } from '@tidbcloud/uikit/icons'
import React, { useState } from 'react'

import { VendorLogo } from 'dbaas/components'
import auth from 'dbaas/services/auth'
import {
  buildLakeConnectLoginSearchFromSearch,
  getLakeConnectIntentFromSearch,
  getLakeConnectTrackingProperties
} from 'dbaas/utils/lake-connect'
import { emailRegEx } from 'dbaas/utils/regex'
import { eventTracking, MixpanelEvents } from 'dbaas/utils/tracking'
import { companyNameRules, firstNameRules, lastNameRules } from 'dbaas/utils/validationRules'

import { SSOSignIn, SSOSignInProps } from '../SSO'

interface FieldProps {
  labeled?: boolean
  required?: boolean
  requiredTip?: boolean
}

export const NameFields: React.FC<React.PropsWithChildren<FieldProps>> = ({ labeled = false, requiredTip }) => {
  return (
    <Group justify="space-between" grow align="flex-start" mb={16}>
      <FormTextInput
        name="first_name"
        label={labeled ? 'First Name' : ''}
        placeholder={!labeled ? 'First Name' : ''}
        aria-label="First Name"
        required={requiredTip}
        rules={{
          required: 'Please enter your first name.',
          ...firstNameRules
        }}
      />
      <FormTextInput
        name="last_name"
        label={labeled ? 'Last Name' : ''}
        placeholder={!labeled ? 'Last Name' : ''}
        required={requiredTip}
        rules={{
          required: 'Please enter your last name.',
          ...lastNameRules
        }}
      />
    </Group>
  )
}

export const EmailField: React.FC<React.PropsWithChildren<FieldProps>> = ({ labeled = false, requiredTip }) => {
  const label = 'Work Email'
  return (
    <FormTextInput
      name="email"
      label={labeled ? label : ''}
      placeholder={!labeled ? label : ''}
      required={requiredTip}
      aria-label={label}
      mb={16}
      rules={{
        required: 'Please enter a valid email address.',
        pattern: {
          value: emailRegEx,
          message: 'Please enter a valid email address.'
        }
      }}
    />
  )
}

export const PasswordField: React.FC<React.PropsWithChildren<FieldProps>> = ({ labeled = false, required = true }) => {
  return (
    <FormPasswordInput
      name="password"
      label={labeled ? 'Password' : ''}
      placeholder={!labeled ? 'Password' : ''}
      autoComplete="new-password"
      aria-label="Password"
      mb={16}
      rules={{
        required: required ? 'Please enter your password.' : undefined,
        minLength: {
          value: 8,
          message: 'At least 8 characters in length.'
        },
        maxLength: {
          value: 64,
          message: 'Maximum 64 characters in length.'
        },
        pattern: {
          value: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,64}$/,
          message:
            'The password should contain the following types of characters: upper case letters (A-Z), lower case letters (a-z), numbers (such as 0-9).'
        }
      }}
    />
  )
}

export const CompanyField: React.FC<React.PropsWithChildren<FieldProps & { required?: boolean }>> = ({
  labeled = true,
  required = true,
  requiredTip
}) => {
  const label = required ? 'Company Name' : 'Company Name  (Optional)'
  return (
    <FormTextInput
      name="company"
      label={labeled ? label : ''}
      required={requiredTip}
      aria-label={label}
      placeholder={!labeled ? label : ''}
      mb={16}
      rules={{
        required: required ? 'Please enter your company name.' : undefined,
        ...companyNameRules
      }}
    />
  )
}

export const SigninField = ({ accountProvider }: { accountProvider?: string }) => {
  return (
    <Flex align="center" gap={8}>
      <Typography variant="body-lg" fw={500} color="carbon.7">
        Have an account?
      </Typography>{' '}
      <a
        onClick={(e) => {
          e.preventDefault()
          const intent = getLakeConnectIntentFromSearch(window.location.search)
          const lakeLoginSearch = buildLakeConnectLoginSearchFromSearch(window.location.search)

          if (intent && lakeLoginSearch) {
            eventTracking(MixpanelEvents.TidbCloudLake.Validate.RequestStarted, {
              entry: 'signup_signin_switch',
              ...getLakeConnectTrackingProperties(intent)
            })
            auth.login(lakeLoginSearch)
            return
          }

          auth.login(accountProvider ? window.location.search : '')
        }}
      >
        Sign In
      </a>
    </Flex>
  )
}

export const SignupForm: React.FC<
  React.PropsWithChildren<
    FormProps & {
      ssoProps?: SSOSignInProps
      withVendor?: boolean
    }
  >
> = ({ children, ssoProps, withVendor = true, ...rest }) => {
  const [type, setType] = useState<'sso' | 'email'>('sso')
  return (
    <Box mih={318} sx={{ borderTop: '1px solid transparent' }}>
      {type === 'sso' ? (
        <>
          <SSOSignIn mt={0} {...ssoProps} />
          <Button
            fw={600}
            fs="14px"
            lh="24px"
            variant="default"
            h={42}
            w="100%"
            c="carbon.8"
            sx={(theme) => ({
              border: `1px solid ${theme.colors.carbon[4]}`,
              backgroundColor: theme.white,
              '&:hover': {
                border: `1px solid ${theme.colors.carbon[6]}`,
                backgroundColor: theme.white
              },
              '&:focus': {
                border: `1px solid ${theme.colors.carbon[6]}`
              },
              '&:active': {
                transform: 'none',
                border: `1px solid ${theme.colors.carbon[9]}`
              }
            })}
            onClick={() => setType('email')}
          >
            <Flex align="center" w={202} fw={700}>
              <IconMail02 size={20} mr={16} />
              Sign up with Email
            </Flex>
          </Button>
          {withVendor && (
            <Flex align="center" gap={8} mt={16}>
              <Typography variant="body-lg" fw={500} c="carbon.7">
                Start free with
              </Typography>
              <VendorLogo name="aws" size={36} />
              <Box
                component="a"
                href="https://aws.amazon.com/marketplace/procurement?productId=4152cefc-92d1-4edc-95d0-fafb6a649f5e&sellerId=arn:aws:aws-marketplace:us-east-1:470438934515:AWSMarketplace/Seller/e3afb426-7e40-4492-ac9b-e4e0007ff813&isBuyWithAWS=true"
                target="_blank"
                rel="noreferrer"
                fw={500}
                fz={14}
              >
                AWS Marketplace
              </Box>
            </Flex>
          )}
        </>
      ) : (
        <>
          <Flex
            align="center"
            sx={(theme) => ({ cursor: 'pointer', color: theme.colors.carbon[8], height: 40 })}
            onClick={() => setType('sso')}
            my={16}
          >
            <IconArrowLeft size={22} />
            <Typography variant="label-lg">Change Other Methods</Typography>
          </Flex>
          <Form {...rest}>
            <NameFields labeled={false} />
            <EmailField labeled={false} />
            <PasswordField labeled={false} />
            {children}
          </Form>
        </>
      )}
    </Box>
  )
}
