import { Box, BoxProps, Button, ButtonProps, Divider, Flex, FlexProps } from '@tidbcloud/uikit'
import clsx from 'clsx'
import React from 'react'

import type { SSOTypes } from 'dbaas/services/auth'
import auth from 'dbaas/services/auth'
import { setSignupProductType, setSSOSource } from 'dbaas/stores/localStorage'
import { getLakeConnectIntentFromSearch, getLakeConnectTrackingProperties } from 'dbaas/utils/lake-connect'
import { eventTracking, MixpanelEvents, reportGA } from 'dbaas/utils/tracking'
import { forwardSearch } from 'dbaas/utils/useQuery'
import MediaGoogle from 'media/google-logo.svg?react'
import MediaGithub from 'media/logo/github-logo.svg?react'
import MediaMicrosoft from 'media/logo/microsoft-logo.svg?react'
import MediaOidc from 'media/oidc-logo.svg?react'
import MediaSAML from 'media/saml-logo.svg?react'

import { useVercelParams } from '../Vercel/helpers'

export type SSOConnection = Lowercase<SSOTypes>

interface SSOButtonProps extends ButtonProps {
  className?: string
  connection?: SSOConnection
  labelClassName?: string
  labelProps?: FlexProps
  onClick?: () => void
}

export const SSOButton = ({ className, connection, children, labelClassName, labelProps, ...rest }: SSOButtonProps) => {
  const size = 18
  const iconMap: Record<SSOConnection, React.ReactNode> = {
    google: <MediaGoogle width={size} height={size} />,
    github: <MediaGithub width={size} height={size} />,
    microsoft: <MediaMicrosoft width={size} height={size} />,
    oidc: <MediaOidc width={size} height={size} />,
    saml: <MediaSAML width={size} height={size} />
  }
  return (
    <Button
      fw={600}
      fs="14px"
      lh="24px"
      variant="default"
      h={42}
      w="100%"
      c="carbon.8"
      className={clsx(className)}
      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': {
          border: `1px solid ${theme.colors.carbon[9]}`,
          transform: 'none'
        }
      })}
      {...rest}
      data-mp-event="mp--1691461016315"
    >
      <Flex
        align="center"
        w={200}
        sx={{
          svg: {
            marginRight: 16,
            flexShrink: 0
          },
          span: {
            overflow: 'hidden',
            textOverflow: 'ellipsis',
            fontWeight: 700
          }
        }}
        className={labelClassName}
        {...labelProps}
      >
        {!!connection && iconMap[connection]}
        <span>{children}</span>
      </Flex>
    </Button>
  )
}

export interface SSOSignInProps extends BoxProps {
  source?: string
  productType?: string
}

export const SSOSignIn = ({ source = 'signup', productType, ...rest }: SSOSignInProps) => {
  const params = new URLSearchParams(window.location.search)

  const forwardParams = forwardSearch(window.location.search, {
    prev_referrer: document.referrer,
    website_referrer_url: params.get('website_referrer_url') || document.referrer
  })

  const { fromVercel, redirectUri } = useVercelParams()

  const onClick = (vendor: 'GOOGLE' | 'GITHUB' | 'MICROSOFT') => () => {
    setSSOSource(source)
    setSignupProductType(productType || '')

    eventTracking(`Signup with ${vendor} Button Clicked`)
    reportGA({
      event: 'sso_signup_click',
      source,
      method: vendor
    })

    const lakeConnectIntent = getLakeConnectIntentFromSearch(params)
    if (lakeConnectIntent) {
      eventTracking(MixpanelEvents.TidbCloudLake.Validate.RequestStarted, {
        entry: 'sso_signup',
        method: vendor,
        ...getLakeConnectTrackingProperties(lakeConnectIntent)
      })
    }

    if (fromVercel && redirectUri) {
      return auth.authorizeWithVendor(vendor, redirectUri)
    }

    auth.authorizeWithVendor(vendor, forwardParams)
  }

  return (
    <Box
      mt={16}
      c="carbon.9"
      sx={{
        button: {
          marginTop: 16,
          '&:last-of-type': {
            marginBottom: 0
          }
        }
      }}
      {...rest}
    >
      <SSOButton connection="google" onClick={onClick('GOOGLE')}>
        Continue with Google
      </SSOButton>
      <SSOButton connection="github" onClick={onClick('GITHUB')}>
        Continue with GitHub
      </SSOButton>
      <SSOButton connection="microsoft" onClick={onClick('MICROSOFT')}>
        Continue with Microsoft
      </SSOButton>
      <Divider label="or" my={12} labelPosition="center"></Divider>
    </Box>
  )
}
