import { Box, Button, Divider, Flex, Group, Popover, Typography, useMantineTheme } from '@tidbcloud/uikit'
import { IconXClose } from '@tidbcloud/uikit/icons'
import { rgba } from '@tidbcloud/uikit/utils'
import { isNil } from 'lodash-es'
import { ReactElement, useState } from 'react'

import { eventTracking } from 'dbaas/utils/tracking'

const enum ZIndex {
  Base = 9000,
  First = 9001,
  Second = 9002
}

type Target = {
  selector: string
  preventInteraction?: boolean
}

type Popover = {
  title: string | ReactElement
  content: string | ReactElement
  width?: number
}

export type Step = {
  target: Target[]
  popover: Popover
  checkTargetVisible?: boolean
  originalColor?: string
  beforeHighLight?: (targets: Target[]) => void
  afterHighLight?: (targets: Target[]) => void
}

type Props = {
  currentStep: number
  steps: Step[]
  withWrapper?: boolean
  stepFormat?: (currentStep: number) => string
  popoverCalculator?: (
    currentStep: number,
    step: Step
  ) => { left?: number; top?: number; right?: number; bottom?: number } | undefined
  onClose?: () => void
}

export const Lighter = ({ currentStep, steps, stepFormat, popoverCalculator, onClose }: Props) => {
  const theme = useMantineTheme()

  const [closeConfirmShow, setCloseConfirmShow] = useState(false)

  const removeHighLight = (step: Step) => {
    step.target.map((v) => {
      const ele = document.querySelector(v.selector) as HTMLElement | null
      if (!isNil(ele)) {
        ele.style.zIndex = ''
        ele.style.background = ''
        ele.style.position = ''
        if (v.preventInteraction) {
          ele.style.pointerEvents = ''
        }
      }
    })
    step.afterHighLight?.(step.target)
  }

  const step = steps[currentStep - 1]
  const prevStep = steps[currentStep - 2]

  if (isNil(step)) {
    console.error('Cannot find this step')
    prevStep && removeHighLight(prevStep)
    return null
  }

  prevStep && removeHighLight(prevStep)

  step.beforeHighLight?.(step.target)

  step.target.map((v) => {
    const ele = document.querySelector(v.selector) as HTMLElement
    if (!isNil(ele)) {
      ele.style.zIndex = ZIndex.First + ''
      ele.style.background = theme.white
      if (v.preventInteraction) {
        ele.style.pointerEvents = 'none'
      }
    }
  })

  const popoverInfo = popoverCalculator?.(currentStep, step)

  const stepShow = stepFormat?.(currentStep) || currentStep

  const handleClose = () => {
    eventTracking('Data App Guided Tour exit')
    removeHighLight(step)
    onClose?.()
  }

  return (
    <>
      <Box
        w="100%"
        h="100%"
        sx={(theme) => ({
          position: 'fixed',
          zIndex: ZIndex.Base,
          background: theme.colors.carbon[6],
          top: 0,
          left: 0,
          opacity: 0.8
        })}
      ></Box>
      <Box
        sx={(theme) => ({
          position: 'fixed',
          zIndex: ZIndex.Second,
          width: step.popover.width,
          background: theme.colors.carbon[2],
          borderRadius: 8,
          border: `1px solid ${theme.colors.carbon[5]}`,
          boxShadow: `0px 16px 64px 0px ${rgba(theme.white, 0.05)}`,
          ...popoverInfo
        })}
      >
        <Flex justify="space-between" p={16}>
          <Typography variant="title-lg">{step.popover.title}</Typography>
          <Popover opened={closeConfirmShow} width={480} withArrow position="top" zIndex={ZIndex.Second}>
            <Popover.Target>
              <Box component={IconXClose} sx={{ cursor: 'pointer' }} onClick={() => setCloseConfirmShow(true)} />
            </Popover.Target>
            <Popover.Dropdown>
              <Typography variant="body-lg">
                By completing this guide, you will learn how to create, test, and deploy a HTTPS endpoint to access data
                from an external client.
              </Typography>
              <Typography variant="body-lg" my={24}>
                You can revisit the guided tour anytime by clicking the "?" in the bottom right corner of the screen.
              </Typography>
              <Typography variant="body-lg">Are you sure you want exit ?</Typography>
              <Group justify="flex-end">
                <Button variant="default" size="xs" onClick={() => setCloseConfirmShow(false)}>
                  Cancel
                </Button>
                <Button variant="default" size="xs" onClick={handleClose}>
                  Yes
                </Button>
              </Group>
            </Popover.Dropdown>
          </Popover>
        </Flex>
        <Divider />
        <Box m={16}>{step.popover.content}</Box>
        <Group mb={16} ml={16}>
          <Typography variant="body-md">{stepShow}/9</Typography>
        </Group>
      </Box>
    </>
  )
}
