import { Divider, Card, Button, Box, Flex, Image, Typography, Code } from '@tidbcloud/uikit'
import { IconLinkExternal01, IconCheckVerified02 } from '@tidbcloud/uikit/icons'
import { useHistory } from 'react-router-dom'

import { StepAction, StepProps } from '../../components/Action'
import { ClusterSelect } from '../../components/ClusterSelect'
import tidbaiBg from '../../components/Images/tidbai.jpeg'
import { LoadDataset } from '../../components/LoadDataset'
import { PasteIntoEditor } from '../../components/PasteIntoEditor'
import { useStepActions } from '../../helpers'

import { TutorialProps } from './type'

const buildCode = (database: string) => {
  return [
    `USE ${database};
SELECT
  *
FROM
  \`github_repos\`
ORDER BY
  \`stars\` DESC
LIMIT
  100;
    `,
    `USE ${database};
SELECT *
FROM github_repos
  ORDER BY VEC_COSINE_DISTANCE(embedding, (
  SELECT embedding FROM github_repos WHERE repo_name = 'pingcap/tidb')
)
LIMIT 100;
`
  ]
}

export const VectorGithub: React.FC<React.PropsWithChildren<TutorialProps>> = ({ onExit, name }) => {
  const {
    tutorial,
    onClusterSelect,
    onExit: handleExit,
    onFinish,
    onStepChange,
    onLoaded,
    loaded,
    disableStart,
    disableExit,
    onLoadStart,
    disableClusterSelect,
    onLoadTerminated
  } = useStepActions(name)
  const s3 = 's3://tidbcloud-samples/github-sample/'
  const arn = 'arn:aws:iam::385595570414:role/import-sample-access'
  const history = useHistory()
  const database = 'github_sample'
  const codes = buildCode(database)
  const tables = ['github_repos']

  const steps: StepProps[] = [
    // Prepare data include select cluster and load dataset
    {
      component: (
        <div>
          <Typography variant="headline-md" mt={16}>
            Import Github Dataset
          </Typography>
          <Typography variant="body-lg" mt={8}>
            Learn how to leverage vector search capabilities with TiDB Starter to explore and discover similar GitHub
            repositories. This tutorial uses a dataset of 5000+ well-known repositories, complete with project metadata
            and embeddings.
          </Typography>
          <Card.Section>
            <Divider my={24} />
          </Card.Section>
          <ClusterSelect
            value={tutorial.clusterId}
            clusterName={tutorial.clusterName}
            disabled={disableClusterSelect}
            onChange={onClusterSelect}
          />
          <Card.Section>
            <Divider my={24} />
          </Card.Section>
          <LoadDataset
            database={database}
            s3={s3}
            tables={tables}
            arn={arn}
            loaded={loaded}
            onLoadStart={onLoadStart}
            onLoaded={onLoaded}
            onLoadTerminated={onLoadTerminated}
            importId={tutorial.importId}
            clusterId={tutorial.clusterId || ''}
          />
        </div>
      )
    },
    // query 1
    {
      component: (
        <div>
          <Typography variant="headline-md" mt={16}>
            Get to Know the Data
          </Typography>
          <Typography variant="body-lg" mt={8}>
            Now we have data imported, let's get to know the data by running the following query. This query displays
            repositories ranked by stars. Each entry includes the repository name, description, metadata, and the
            embedding generated from the concatenation of the repository name and description using OpenAI embeddings.
          </Typography>
          <Card.Section>
            <Divider my={24} />
          </Card.Section>
          <Typography variant="action-md" c="carbon.9">
            SQL Preview
          </Typography>
          <PasteIntoEditor clusterId={tutorial.clusterId || ''} clusterName={tutorial.clusterName} value={codes[0]} />
        </div>
      )
    },
    {
      component: (
        <div>
          <Typography variant="headline-md" mt={16}>
            Search Similar Projects
          </Typography>
          <Typography variant="body-lg" mt={8}>
            Use vector search to find projects similar to a given repository. By leveraging the embeddings generated
            from the concatenation of repository names and descriptions, we can identify repositories that are
            semantically similar. The following query finds repositories similar to <Code>pingcap/tidb</Code>, ranking
            them by their cosine distance to prioritize the most similar ones.
          </Typography>
          <Card.Section>
            <Divider my={24} />
          </Card.Section>
          <Typography variant="action-md" c="carbon.9">
            SQL Preview
          </Typography>
          <PasteIntoEditor clusterId={tutorial.clusterId || ''} clusterName={tutorial.clusterName} value={codes[1]} />
        </div>
      )
    },
    {
      component: (
        <div>
          <Typography variant="headline-md" mt={16}>
            Explore TiDB.AI
          </Typography>
          <Typography variant="body-lg" mt={8}>
            Visit TiDB.AI to learn how to build real-world Gen-AI applications with TiDB Vector Search. TiDB.AI is an
            open-source conversational search tool leveraging the vector storage capabilities of TiDB and GraphRAG.
          </Typography>
          <Button
            variant="outline"
            leftSection={<IconLinkExternal01 size={16} />}
            data-mp-event="TiDB.AI Link Clicked"
            size="sm"
            styles={() => ({
              leftIcon: {
                marginRight: 4
              },
              root: {
                padding: '6px 12px',
                height: 32,
                marginTop: 16,
                ':hover': {
                  textDecoration: 'none'
                }
              },
              label: { fontSize: 14, lineHeight: '20px', fontWeight: 700 }
            })}
            onClick={() => {
              window.open('https://tidb.ai/', '_blank')
            }}
          >
            Go to TiDB.AI
          </Button>
          <Image mt={24} src={tidbaiBg} />
        </div>
      )
    },
    // Finish all steps
    {
      component: (
        <Flex direction="column" h="100%">
          <Box
            sx={() => ({
              display: 'flex',
              flexDirection: 'column',
              justifyContent: 'center',
              alignItems: 'center',
              flex: 1
            })}
          >
            <Box
              sx={(theme) => ({
                display: 'flex',
                justifyContent: 'center',
                alignItems: 'center',
                color: theme.colors.green[7],
                backgroundColor: theme.colors.green[1],
                width: 48,
                height: 48,
                borderRadius: '100%'
              })}
            >
              <IconCheckVerified02 size={20} />
            </Box>
            <Typography variant="headline-md" c="carbon.9" mt={16}>
              Congratulations!
            </Typography>
            <Typography variant="body-lg" mt={8} ta="center">
              You've successfully completed the tutorial and can continue playing with this unique dataset.
            </Typography>
            <Button
              onClick={() => {
                history.push(`/clusters/${tutorial.clusterId}/imports`)
              }}
              size="sm"
              px={12}
              mt={24}
              data-mp-event="TiDB.AI import your data clicked"
            >
              Import your data
            </Button>
            <Button
              onClick={() => {
                handleExit()
                onExit?.()
              }}
              variant="default"
              size="sm"
              px={12}
              mt={10}
              styles={(theme) => ({
                root: {
                  backgroundColor: theme.colors.carbon[2],
                  ':hover': {
                    textDecoration: 'none'
                  }
                }
              })}
              data-mp-event="Back to tutorial clicked"
            >
              Back to tutorial
            </Button>
          </Box>
        </Flex>
      )
    }
  ]
  return (
    <StepAction
      endWithFooter={false}
      steps={steps}
      value={tutorial.step}
      disabledStart={disableStart}
      disabledExit={disableExit}
      onExit={() => {
        handleExit()
        onExit?.()
      }}
      onChange={(value) => {
        onStepChange(value, steps.length)
      }}
      onFinish={() => {
        onFinish()
        onExit?.()
      }}
    />
  )
}
