import {
  Button,
  Group,
  GroupProps,
  Accordion,
  Card,
  Divider,
  AccordionProps,
  Typography,
  ActionIcon,
  openConfirmModal
} from '@tidbcloud/uikit'
import { CodeBlock } from '@tidbcloud/uikit/biz'
import { IconCopy01 } from '@tidbcloud/uikit/icons'
import { useEffect, useState } from 'react'
import { matchPath, useHistory } from 'react-router-dom'

import { useHelpCenterContext } from 'dbaas/screens/HelpCenter/context'
import { eventTracking } from 'dbaas/utils/tracking'

export interface PasteIntoEditorProps extends GroupProps {
  value: string
  clusterId: string
  clusterName?: string
  withCopy?: boolean
  disabled?: boolean
  hasPasteButton?: boolean
  pasteButtonText?: string
  pasteValue?: string
  enableCopyButtonPaste?: boolean
}

export const PasteIntoEditor: React.FC<React.PropsWithChildren<PasteIntoEditorProps>> = ({
  value,
  clusterId,
  clusterName,
  disabled,
  hasPasteButton = true,
  pasteButtonText,
  pasteValue,
  enableCopyButtonPaste,
  ...rest
}) => {
  const { incomingSQLFile, setOutgoingSQLFile, chat2queryReady, setChat2queryReady, setNeedSetChat2queryCursor } =
    useHelpCenterContext()
  const history = useHistory()
  const [pasteState, setPasteState] = useState<'initial' | 'pasting' | 'pasted'>('initial')

  useEffect(() => {
    // check SQL Editor is ready to interactive
    if (pasteState === 'pasting' && incomingSQLFile && chat2queryReady) {
      const { content } = incomingSQLFile
      const isNullAtTail = content?.slice(-1) === '\n' || content === ''
      let pasteContent = pasteValue === undefined ? value : pasteValue
      const needAddNewLine = content?.slice(-2) !== '\n\n'
      content && pasteValue === undefined && (pasteContent = !needAddNewLine ? pasteContent : `\n${pasteContent}`)
      const newContent = content ? `${content}${isNullAtTail ? '' : '\n'}${pasteContent}` : pasteContent
      setOutgoingSQLFile({
        ...incomingSQLFile,
        content: newContent
      })
      setPasteState('pasted')
      eventTracking('Tutorial Pasted Code', { clusterName, clusterId })
    }
  }, [incomingSQLFile, chat2queryReady, pasteState])

  const handleClick = async () => {
    const target = `/tidbs/${clusterId}/sqleditor`
    eventTracking('Tutorial Start Pasting Code', { clusterName, clusterId })

    if (
      !matchPath(window.location.pathname, {
        path: target
      })
    ) {
      setChat2queryReady(false)
      openConfirmModal({
        title: (
          <Typography variant="title-lg" lh="22px">
            Go to the SQL Editor?
          </Typography>
        ),
        centered: true,
        zIndex: 10000,
        size: 460,
        children: (
          <Typography variant="body-lg" color="gary.7">
            This query will be pasted into the {clusterName || 'SQL Editor'} if you click okay.
          </Typography>
        ),
        labels: {
          cancel: 'Cancel',
          confirm: 'Okay'
        },
        onCancel: () => {},
        onConfirm: () => {
          history.push(target)
          setPasteState('pasting')
        }
      })
    } else {
      setPasteState('pasting')
    }
  }

  return (
    <Group align="center" mt={16} mb={48} gap={8} {...rest}>
      <CodeBlock
        w="100%"
        language="sql"
        onCopyClick={() => {
          if (!enableCopyButtonPaste) {
            return
          }

          setNeedSetChat2queryCursor(true)
          setPasteState('pasting')

          setTimeout(() => {
            setNeedSetChat2queryCursor(false)
          }, 500)
        }}
      >
        {value}
      </CodeBlock>

      {hasPasteButton && (
        <Button
          variant="default"
          leftSection={
            <ActionIcon size="xs" variant="transparent" disabled={disabled}>
              <IconCopy01 size={16} />
            </ActionIcon>
          }
          onClick={handleClick}
          disabled={disabled}
          styles={() => ({
            section: {
              marginRight: 4
            },
            label: { fontSize: 14, lineHeight: '20px', fontWeight: 700 }
          })}
          data-mp-event="mp-pasteintochat2query-1691461016580"
        >
          {pasteButtonText || 'Paste into SQL Editor'}
        </Button>
      )}
    </Group>
  )
}

export interface CodeSnippetProps extends Omit<AccordionProps, 'children'> {
  data: {
    title: React.ReactNode
    description?: React.ReactNode
    code: string
    clusterId: string
    clusterName?: string
  }[]
  withDivider?: boolean
  disabled?: boolean
  hasPasteButton?: boolean
  othersInfo?: React.ReactNode
  pasteButtonText?: string
  pasteValue?: string
  enableCopyButtonPaste?: boolean
}

export const CodeSnippet: React.FC<React.PropsWithChildren<CodeSnippetProps>> = ({
  data,
  withDivider = true,
  disabled = false,
  hasPasteButton = true,
  enableCopyButtonPaste,
  ...rest
}) => {
  return (
    <Accordion
      defaultValue={Array.from({ length: data.length }, (_, i) => i.toString())}
      px={0}
      multiple
      styles={() => ({
        item: {
          borderBottom: 'none'
        },
        control: {
          padding: 0,
          ':hover': {
            backgroundColor: 'transparent'
          }
        },
        content: {
          padding: 0
        }
      })}
      {...rest}
    >
      {data.map((item, index) => {
        const key = item.title + index.toString()
        return (
          <div key={key}>
            <Accordion.Item value={index.toString()}>
              <Accordion.Control>
                <Typography variant="title-lg" c="carbon.9">
                  {item.title}
                </Typography>
                {!!item.description && (
                  <Typography variant="body-lg" c="carbon.8" mt={4}>
                    {item.description}
                  </Typography>
                )}
              </Accordion.Control>
              <Accordion.Panel>
                <PasteIntoEditor
                  clusterId={item.clusterId}
                  clusterName={item.clusterName}
                  disabled={disabled}
                  value={item.code}
                  mb={0}
                  hasPasteButton={hasPasteButton}
                  pasteButtonText={rest.pasteButtonText}
                  pasteValue={rest.pasteValue}
                  enableCopyButtonPaste={enableCopyButtonPaste}
                >
                  {rest.children}
                </PasteIntoEditor>
                {rest.othersInfo}
              </Accordion.Panel>
              {withDivider && (
                <Card.Section>
                  <Divider my={24} />
                </Card.Section>
              )}
            </Accordion.Item>
          </div>
        )
      })}
    </Accordion>
  )
}
