import { Button, Kbd, Stack, Typography } from '@tidbcloud/uikit'
import { CodeBlock } from '@tidbcloud/uikit/biz'
import { useMemo, useState } from 'react'

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

import { useHelpCenterContext } from '../HelpCenter/context'

import { useDataApiContext } from './context'
import { Lighter, Step } from './Lighter'
import { EndPoint } from './types'

const popoverCalculator = (currentStep: number, step: Step) => {
  const firstBoundingRect = (document.querySelector(step.target[0]?.selector) as HTMLElement)?.getBoundingClientRect()
  const secondBoundingRect = (document.querySelector(step.target[1]?.selector) as HTMLElement)?.getBoundingClientRect()

  switch (currentStep) {
    case 1:
      return {
        left: firstBoundingRect?.right - 30,
        top: firstBoundingRect?.bottom + 150
      }
    case 2:
      return {
        left: secondBoundingRect?.right - 300,
        top: secondBoundingRect?.bottom - 300
      }
    case 3:
      return {
        left: secondBoundingRect?.left - 250,
        top: secondBoundingRect?.bottom + 30
      }
    case 4:
      return {
        left: firstBoundingRect?.left - 250,
        top: firstBoundingRect?.bottom + 400
      }
    case 5:
      return {
        left: firstBoundingRect?.left - 350,
        top: firstBoundingRect?.bottom + 30
      }
    case 6:
      return {
        left: firstBoundingRect?.right - 250,
        top: firstBoundingRect?.top - 300
      }
    case 7:
      return {
        left: firstBoundingRect?.left - 400,
        top: firstBoundingRect?.bottom + 30
      }
    case 8:
      return {
        left: firstBoundingRect?.right - 550,
        top: firstBoundingRect?.top + 300
      }
  }
}

const sqlExample = 'USE fortune500;\nSELECT\n*\nFROM\nfortune500_2018_2022\nWHERE\ncompany_name = ${company}'

export const Guide = () => {
  const {
    editAppInHelpCenter,
    dataServiceGuideStep,
    setDataServiceGuideStep,
    setEditAppInHelpCenter,
    showDataServiceTooltip
  } = useHelpCenterContext()
  const {
    editApp,
    editEndpoint,
    setEditEndpoint,
    editEndpointRef,
    setSqlText,
    sqlTextRef,
    setPathForHelpCenter,
    paramsList,
    setParamsList,
    openedEndpList,
    setOpenedEndpList
  } = useDataApiContext()

  const [step3Status, setStep3Status] = useState(false)
  const [step4Status, setStep4Status] = useState(false)
  const [step5Status, setStep5Status] = useState(false)

  const steps: Step[] = useMemo(
    () => [
      {
        target: [
          { selector: `[data-guide="data-service-${editAppInHelpCenter?.id}"]` },
          { selector: '[data-guide="menu-drop-down"]' }
        ],
        checkTargetVisible: true,
        beforeHighLight: (targets) => {
          const ele = document.querySelector(targets[0]?.selector) as HTMLElement
          if (ele) {
            ele.style.position = 'relative'
          }
        },
        popover: {
          width: 520,
          title: 'Create An Endpoint',
          content: (
            <Typography variant="body-lg">
              Hover on the Data App name and click on the "+" button. Select '
              <Typography variant="title-md" sx={{ display: 'inline' }}>
                Create Endpoint
              </Typography>
              ' to start the endpoint creation process.
            </Typography>
          )
        }
      },
      {
        target: [
          { selector: `[data-guide="endpoint-${editEndpoint?.id}"]`, preventInteraction: true },
          { selector: '[data-guide="editor"]', preventInteraction: true }
        ],
        popover: {
          width: 500,
          title: 'Create Endpoint - Write Endpoint Logic Using SQL',
          content: (
            <>
              <Typography variant="body-lg" mb={16}>
                We provide an intuitive built-in SQL editor that allows you to efficiently query and manipulate your
                data. For instance, you can use the following command to retrieve historical data for a specific
                company.
              </Typography>
              <CodeBlock>{(sqlExample || '').replaceAll('\\n', '\n').replaceAll('\t', '  ')}</CodeBlock>
              <Stack align="center" mt={16}>
                {step3Status ? (
                  <Button
                    size="xs"
                    onClick={() => {
                      setDataServiceGuideStep(dataServiceGuideStep + 1)
                      eventTracking('Guided Tour step 4')
                    }}
                  >
                    Next, configure endpoint
                  </Button>
                ) : (
                  <Button
                    size="xs"
                    onClick={() => {
                      const endp = {
                        ...editEndpointRef.current,
                        sql_template: sqlExample
                      } as EndPoint
                      setEditEndpoint(endp)
                      editEndpointRef.current = endp
                      setSqlText(sqlExample)
                      sqlTextRef.current = sqlExample
                      setStep3Status(true)
                    }}
                  >
                    Use this SQL command
                  </Button>
                )}
              </Stack>
            </>
          )
        },
        beforeHighLight: (targets) => {
          const ele = document.querySelector(targets[0]?.selector) as HTMLElement
          if (ele) {
            ele.style.position = 'relative'
          }
        }
      },
      {
        target: [
          { selector: `[data-guide="property-path"]`, preventInteraction: true },
          { selector: '[data-guide="property-method"]', preventInteraction: true },
          { selector: `[data-guide="endpoint-${editEndpoint?.id}"]`, preventInteraction: true }
        ],
        beforeHighLight: (targets) => {
          targets.forEach((v) => {
            const ele = document.querySelector(v.selector) as HTMLElement
            if (ele) {
              ele.style.position = 'relative'
              ele.style.padding = '4px'
            }
          })
        },
        afterHighLight: (targets) => {
          targets.forEach((v) => {
            const ele = document.querySelector(v.selector) as HTMLElement
            ele && (ele.style.padding = '')
          })
        },
        popover: {
          width: 500,
          title: 'Create Endpoint - Configure Endpoint',
          content: (
            <>
              <Typography variant="body-lg" mb={24}>
                Under the 'Properties' tab, enter the Path as "
                <Typography variant="title-md" sx={{ display: 'inline' }}>
                  /companyInfo
                </Typography>
                ".
              </Typography>
              <Typography variant="body-lg" mb={24}>
                Set the Request method to{' '}
                <Typography variant="title-md" sx={{ display: 'inline' }}>
                  GET
                </Typography>
                (recommended).
              </Typography>
              <Typography variant="body-lg">
                Note: The endpoint name is automatically inferred from the path value entered by default.
              </Typography>
              <Stack align="center" mt={16}>
                {step4Status ? (
                  <Button
                    size="xs"
                    onClick={() => {
                      eventTracking('Guided Tour step 5')
                      setDataServiceGuideStep(dataServiceGuideStep + 1)
                      setPathForHelpCenter('')
                      setStep3Status(false)
                      setStep4Status(false)
                      setStep5Status(false)
                    }}
                  >
                    Next, configure test value
                  </Button>
                ) : (
                  <Button
                    size="xs"
                    onClick={() => {
                      if (editEndpointRef.current) {
                        editEndpointRef.current.method = 'GET'
                        editEndpointRef.current.endpoint = '/companyInfo'
                        editEndpointRef.current.name = '/companyInfo'

                        const editEndPIdx = openedEndpList.findIndex((v) => v.id === editEndpointRef.current?.id)
                        if (editEndPIdx !== -1) {
                          openedEndpList[editEndPIdx] = editEndpointRef.current
                          setOpenedEndpList([...openedEndpList])
                          setEditEndpoint({
                            ...editEndpointRef.current
                          })
                        }
                      }
                      setPathForHelpCenter('/companyInfo')
                      setStep4Status(true)
                    }}
                  >
                    Configure properties for me
                  </Button>
                )}
              </Stack>
            </>
          )
        }
      },
      {
        target: [
          { selector: `[data-guide="tab"]`, preventInteraction: true },
          { selector: '[data-guide="definition"]', preventInteraction: true }
        ],
        popover: {
          width: 500,
          title: 'Test Endpoint - Configure Test Values',
          content: (
            <>
              <Typography variant="body-lg">
                Under the ‘Params’ tab, enter '
                <Typography variant="title-md" sx={{ display: 'inline' }}>
                  IBM
                </Typography>
                ' as the test value for the 'company' parameter in the 'Test Values' section.
              </Typography>
              <Stack align="center" mt={16}>
                {step5Status ? (
                  <Button
                    size="xs"
                    onClick={() => {
                      eventTracking('Guided Tour step 6')
                      setDataServiceGuideStep(dataServiceGuideStep + 1)
                    }}
                  >
                    Next, test endpoint
                  </Button>
                ) : (
                  <Button
                    size="xs"
                    onClick={() => {
                      const list = paramsList.slice()
                      list[0] && (list[0].value = 'IBM')
                      setParamsList(list)
                      setStep5Status(true)
                    }}
                  >
                    Next, configure test value
                  </Button>
                )}
              </Stack>
            </>
          )
        },
        beforeHighLight: (targets) => {
          targets.forEach((v) => {
            const ele = document.querySelector(v.selector) as HTMLElement
            ele && (ele.style.position = 'relative')
          })
        }
      },
      {
        target: [{ selector: '[data-guide="test"]' }],
        popover: {
          width: 500,
          title: 'Test Endpoint',
          content: (
            <>
              <Typography variant="body-lg">
                Now, click the <Kbd>Test</Kbd> button to see the endpoint in action.
              </Typography>
            </>
          )
        }
      },
      {
        target: [{ selector: '[data-guide="result"]' }],
        beforeHighLight: (targets) => {
          const jsonTree = (document.querySelector(targets[0].selector) as HTMLElement).querySelector('ul')
          if (!jsonTree) return
          jsonTree.scrollTop = jsonTree.scrollHeight
        },
        popover: {
          width: 500,
          title: 'Test Endpoint - Verify Endpoint Response',
          content: (
            <>
              <Typography variant="body-lg" mb={24}>
                If everything is set up correctly, you should receive an HTTPS response with a code 200 on the screen.
              </Typography>
              <Typography variant="body-lg">Testing is now complete!</Typography>
              <Stack align="center" mt={16}>
                <Button
                  size="xs"
                  onClick={() => {
                    eventTracking('Guided Tour step 7')
                    setDataServiceGuideStep(dataServiceGuideStep + 1)
                  }}
                >
                  Next, deploy endpoint
                </Button>
              </Stack>
            </>
          )
        }
      },
      {
        target: [{ selector: '[data-guide="deploy"]' }],
        popover: {
          width: 500,
          title: 'Deploy Endpoint',
          content: (
            <>
              <Typography variant="body-lg" mb={24}>
                Great! You're almost there, and now it's time to take the final step. Deploy the endpoint to make it
                publicly available for use.
              </Typography>
              <Typography variant="body-lg">
                Click <Kbd>Deploy</Kbd> button to start the deployment process.
              </Typography>
            </>
          )
        }
      },
      {
        target: [{ selector: '[data-guide="deploy-modal"]' }],
        popover: {
          width: 500,
          title: 'Deploy Endpoint - Review Changes',
          content: (
            <>
              <Typography variant="body-lg" mb={24}>
                Before proceeding with deployment, take a moment to review your changes and, if desired, add a brief
                change description in the field provided. This optional description can help you track your edits.
              </Typography>
              <Typography variant="body-lg">
                Click the 'Deploy' button to make the endpoint publicly available.
              </Typography>
            </>
          )
        }
      }
    ],
    [editApp, editEndpoint, step3Status, step4Status, step5Status, dataServiceGuideStep]
  )

  const handleClose = () => {
    setEditAppInHelpCenter(null)
    setDataServiceGuideStep(0)
    setPathForHelpCenter('')
    setStep3Status(false)
    setStep4Status(false)
    setStep5Status(false)
    showDataServiceTooltip()
  }

  return dataServiceGuideStep > 1 ? (
    <Lighter
      steps={steps}
      currentStep={dataServiceGuideStep - 1}
      stepFormat={(step) => step + 1 + ''}
      popoverCalculator={popoverCalculator}
      onClose={handleClose}
    />
  ) : null
}
