import {
  Breadcrumbs,
  Box,
  BoxProps,
  Divider,
  Group,
  Button,
  Flex,
  notifier,
  Stepper,
  Stack,
  Anchor,
  Accordion,
  AccordionProps,
  Typography
} from '@tidbcloud/uikit'
import { Form, FormTextInput, FormSelect, CodeBlock } from '@tidbcloud/uikit/biz'
import {
  IconGithub,
  IconFile02,
  IconChatRobot,
  IconUser01,
  IconBookClosed,
  IconVideoRecorder
} from '@tidbcloud/uikit/icons'
import { isNil, startCase } from 'lodash-es'
import React, { useEffect, useMemo, useState } from 'react'
import { useForm } from 'react-hook-form'

import { useAccessCheck } from 'dbaas/contexts/access-control'
import { SampleDataProps } from 'dbaas/screens/DataService/CreateApp/CreateSampleData'
import CreateCluster from 'dbaas/screens/DataService/Editor/CreateCluster'
import { showErrorMsg, useFormatClusterList } from 'dbaas/screens/DataService/helpers'
import { DataApp } from 'dbaas/screens/DataService/types'
import { makeAppName } from 'dbaas/screens/DataService/utils'
import { HelpCenterCard } from 'dbaas/screens/HelpCenter/CenterCard'
import { CenterRoute, CenterSwitch, CenterRedirect, HeaderText } from 'dbaas/screens/HelpCenter/CenterRoute'
import { useHelpCenterContext } from 'dbaas/screens/HelpCenter/context'
import { useImportFortuneData } from 'dbaas/services'
import { useCreateDataApp, useGetBatchExample } from 'dbaas/services/dataservice'
import useStores from 'dbaas/stores/useStores'
import { eventTracking } from 'dbaas/utils/tracking'

import { CreateSampleDataApp } from './CreateSampleDataApp'
import { SampleDataSuccess } from './SampleDataSuccess'

export const DATA_SERVICE_BASE_PATH = '/help/DataService'

export const SAMPLE_DATA_APP_PATH = '/help/DataService/SampleDataApp'

export const CREATE_DATA_APP_PATH = '/help/DataService/CreateDataApp'

export const GUIDED_TOUR_OF_ENDPOINTS_PATH = '/help/DataService/Guided Tour of Endpoints'

export const SAMPLE_DATA_SUCCESS_PATH = '/help/DataService/SampleDataApp '

export interface DataServiceCardProps extends BoxProps {
  name: string
  icon?: React.ReactNode
  title?: string
  description?: string
  external?: boolean
  onClick?: () => void
}

const TutorialCard: React.FC<React.PropsWithChildren<DataServiceCardProps>> = ({
  name,
  icon,
  title,
  description,
  ...rest
}) => {
  return (
    <Box
      sx={(theme) => ({
        border: `1px solid ${theme.colors.carbon[5]}`,
        padding: 16,
        borderRadius: theme.defaultRadius,
        cursor: 'pointer',
        ':hover': {
          borderColor: theme.colors.carbon[6]
        }
      })}
      {...rest}
    >
      <Box
        sx={(theme) => ({
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-between',
          color: theme.colors.carbon[8]
        })}
      >
        <Box sx={() => ({ display: 'flex', flex: 1, alignItems: 'center' })}>
          {icon}
          <Typography variant="title-lg" ml={8}>
            {title}
          </Typography>
        </Box>
      </Box>
      <Typography variant="body-lg" mt={8}>
        {description}
      </Typography>
    </Box>
  )
}

const CreateDataAppForm = () => {
  const { list: clusterList } = useFormatClusterList(false)
  const { setCurrentPath, setEditAppInHelpCenter, closeDialog, setDataServiceGuideStep } = useHelpCenterContext()
  const {
    store: { tenantData, activeProject }
  } = useStores()

  const defaultCluster = useMemo(() => {
    const validClusters = clusterList.filter((v) => !v.disabled)
    return validClusters.length === 1 ? validClusters[0].value : ''
  }, [clusterList])

  const form = useForm<SampleDataProps>({
    defaultValues: {
      app_name: `fortune500-sample-dataapp-${makeAppName(4)}`,
      cluster_ids: defaultCluster,
      description: 'Access and analyze valuable insights from Fortune 500 companies.'
    }
  })

  const { watch, getValues, setValue } = form

  const formValues = watch()

  useEffect(() => {
    if (clusterList) {
      const validClusters = clusterList.filter((v) => !v.disabled)
      if (!getValues('cluster_ids') && validClusters[0]) {
        setValue('cluster_ids', validClusters[0].value)
      }
    }
  }, [clusterList])

  const [active, setActive] = useState(-1)

  const [created, setCreated] = useState(false)

  const { isLoading: step1IsLoading, mutateAsync: step1MutateAsync } = useCreateDataApp()

  const { isLoading: step2IsLoading, mutateAsync: step2MutateAsync } = useImportFortuneData()

  useEffect(() => {
    if (created && !step1IsLoading && !step2IsLoading) {
      closeDialog()
      setCreated(false)
      setCurrentPath(DATA_SERVICE_BASE_PATH)
      setTimeout(() => {
        setDataServiceGuideStep(2)
        eventTracking('Guided Tour step 2')
      }, 1000)
    }
  }, [created, step1IsLoading, step2IsLoading])

  const createSampleDataHandler = async (values: SampleDataProps) => {
    try {
      setDataServiceGuideStep(1)
      const res = await step1MutateAsync({
        orgId: tenantData.id,
        projectId: activeProject.id,
        data: {
          app_type: 'dataapi',
          app_name: values.app_name,
          cluster_ids: [values.cluster_ids],
          description: values.description
        }
      })

      if (res.code !== 200) {
        notifier.error(res.message)
        return
      }

      const app = res.data?.app_info
      if (!app) {
        notifier.error('Failed to create sample Data App')
        return
      }
      setActive(1)
      setEditAppInHelpCenter(app as any as DataApp)
      await step2MutateAsync({
        orgId: tenantData.id,
        projectId: activeProject.id,
        clusterId: values.cluster_ids
      })
      setActive(2)
      setCreated(true)
    } catch (e) {
      showErrorMsg(e, true)
    }
  }

  return (
    <Form<SampleDataProps>
      form={form}
      onSubmit={createSampleDataHandler}
      withActions={false}
      h="100%"
      layout="none"
      mb={-24}
      mx={-24}
      sx={{ display: 'flex', flexDirection: 'column' }}
    >
      <Stack
        gap={4}
        h={0}
        sx={{
          flex: 1,
          overflowY: 'auto',
          '::-webkit-scrollbar': {
            width: 0
          }
        }}
        pb={12}
      >
        <Typography variant="headline-lg" mt={16} mx={24}>
          Welcome to Endpoint Guidance Tour
        </Typography>
        <Typography variant="body-lg" mx={24}>
          In this 9-step journey, we will walk you through the process of creating, testing, and deploying an HTTPS
          endpoint. By the end of the tour, you will have equipped yourself with the knowledge and skills to create,
          test, and deploy HTTPS endpoints.
        </Typography>
        <Typography variant="headline-lg" mt={16} mx={24}>
          Create a Data App
        </Typography>
        <Typography variant="body-lg" mx={24}>
          Endpoints are contained within a Data App. Let's create a Fortune 500 Data App and import the 'fortune-500'
          dataset into the linked cluster.
        </Typography>
        <Typography variant="body-lg" mb={8} mx={24}>
          To begin, click the 'Next' button, and watch as the following steps are auto-executed to set up your Data App!
        </Typography>
        <Box
          mx={24}
          py={8}
          px={24}
          sx={(theme) => ({
            background: theme.colors.carbon[2]
          })}
        >
          <Stepper orientation="vertical" active={active} size="xs">
            <Stepper.Step
              mih={0}
              sx={{ display: 'flex', alignItems: 'center' }}
              label={
                <Typography variant="label-lg" c="carbon.8">
                  Create Data App
                </Typography>
              }
              loading={step1IsLoading}
            ></Stepper.Step>
            <Stepper.Step
              mih={0}
              sx={{ display: 'flex', alignItems: 'center' }}
              label={
                <Typography variant="label-lg" c="carbon.8">
                  Import Sample Dataset
                </Typography>
              }
              loading={step2IsLoading}
            ></Stepper.Step>
          </Stepper>
        </Box>
        <Divider my={12} />
        <FormTextInput mx={24} name="app_name" label={<Typography variant="title-md">Data App Name</Typography>} />
        <Divider my={12} mx={24} />
        <FormSelect
          mx={24}
          nothingFoundMessage={<CreateCluster />}
          data={clusterList}
          name="cluster_ids"
          placeholder="Select one cluster as your data source"
          label={<Typography variant="title-md">Link Data Source</Typography>}
        />
        <Divider my={12} />
        <FormTextInput
          mx={24}
          name="description"
          label={
            <Group gap={8}>
              <Typography variant="title-md" inline>
                Description
              </Typography>
              <Typography variant="label-lg" color="carbon.7">
                (Optional)
              </Typography>
            </Group>
          }
        />
      </Stack>

      <Flex
        justify="space-between"
        align="center"
        w="100%"
        py={16}
        h={64}
        sx={(theme) => ({
          borderTop: `1px solid ${theme.colors.carbon[4]}`
        })}
      >
        <Button
          variant="default"
          size="sm"
          px={12}
          mx={24}
          onClick={() => {
            eventTracking('Data App Guided Tour complete')
            setCurrentPath(DATA_SERVICE_BASE_PATH)
          }}
        >
          Exit Tutorial
        </Button>
        <Box>1/9</Box>
        <Button
          size="sm"
          px={12}
          mr={24}
          type="submit"
          loading={step1IsLoading || step2IsLoading}
          disabled={formValues.app_name === '' || isNil(formValues.cluster_ids) || formValues.cluster_ids.length === 0}
        >
          Next
        </Button>
      </Flex>
    </Form>
  )
}

const GuidedTourOfEndpoints = () => {
  const { closeDialog, setCurrentPath, editAppInHelpCenter, setEditAppInHelpCenter } = useHelpCenterContext()
  const {
    store: { tenantData, activeProject }
  } = useStores()

  const [codeExample, setCodeExample] = useState('')

  useGetBatchExample(tenantData.id, activeProject.id, editAppInHelpCenter?.id || '', {
    query: {
      refetchInterval: 2000,
      enabled: !!tenantData.id && !!activeProject.id && !!editAppInHelpCenter?.id && !codeExample,
      refetchOnWindowFocus: false,
      onSuccess: (res) => {
        const list = res.data?.endpoint_examples || []
        const examples = (list.length && list[0].examples) || []
        if (list.length) {
          setCodeExample(examples.length ? examples[0].code || '' : '')
        }
      }
    }
  })

  return (
    <Flex direction="column" sx={{ flex: 1 }} h={0} mb={-24}>
      <Box sx={{ flex: 1, overflowY: 'auto' }} h={0}>
        <Typography variant="headline-lg" mt={16}>
          Congratulations!
        </Typography>
        <Typography variant="body-lg" mt={8}>
          You have successfully created, tested and deployed your first HTTPS endpoint.
        </Typography>
        <Typography variant="body-lg" my={12}>
          Your endpoint is now ready to be consumed by your application or any other client.
        </Typography>
        <Divider my={24} />
        <Typography variant="title-md">Access Endpoint</Typography>
        <Typography variant="body-lg" my={12}>
          Accessing an endpoint typically requires you to
          <Typography
            c="peacock.7"
            ml={4}
            component="a"
            onClick={() => {
              const newApp = { ...editAppInHelpCenter, endpoints: [] } as DataApp
              setEditAppInHelpCenter(newApp)
            }}
          >
            create an API Key
          </Typography>
          . However, for the purpose of this guide, we've already generated an API key for you.
        </Typography>
        <Typography variant="body-lg" my={12}>
          Copy the command below and execute it in a terminal window. (
          <a href="https://curl.se/download.html" target="_blank" rel="noreferrer">
            CURL
          </a>{' '}
          may be required to complete this step.)
        </Typography>
        <CodeBlock>{codeExample.replaceAll('\\n', '\n').replaceAll('\t', '  ')}</CodeBlock>
        <Typography variant="body-lg" my={24}>
          Explore more advanced functionalities:
        </Typography>
        <Box>
          <Group gap={8}>
            <IconGithub />
            <Anchor
              href="https://docs.pingcap.com/tidbcloud/data-service-manage-github-connection"
              fz={14}
              c="gray"
              target="_blank"
            >
              GitHub integrations
            </Anchor>
          </Group>
          <Group gap={8}>
            <IconUser01 />
            <Anchor
              href="https://docs.pingcap.com/tidbcloud/data-service-postman-integration"
              fz={14}
              c="gray"
              target="_blank"
            >
              Run in Postman
            </Anchor>
          </Group>
          <Group gap={8}>
            <IconFile02 />
            <Anchor
              href="https://docs.pingcap.com/tidbcloud/data-service-oas-with-nextjs"
              fz={14}
              c="gray"
              target="_blank"
            >
              Use OpenAPI specification with Next.js
            </Anchor>
          </Group>
          <Group gap={8}>
            <IconChatRobot />
            <Anchor href="https://docs.pingcap.com/tidbcloud/use-chat2query-api" fz={14} c="gray" target="_blank">
              Import a Chat2Query API
            </Anchor>
          </Group>
        </Box>
        <Typography variant="body-lg" my={24}>
          Still not found what you're looking for?
          <a href="https://docs.pingcap.com/tidbcloud/data-service-get-started" target="_blank" rel="noreferrer">
            {' '}
            Explore our Data Service offerings
          </a>{' '}
          for more information.
        </Typography>
      </Box>
      <Flex
        justify="center"
        align="center"
        h={64}
        sx={(theme) => ({ borderTop: `1px solid ${theme.colors.carbon[4]}` })}
      >
        <Button
          size="sm"
          px={12}
          onClick={() => {
            closeDialog()
            setCurrentPath(DATA_SERVICE_BASE_PATH)
          }}
        >
          Complete Tour
        </Button>
      </Flex>
    </Flex>
  )
}

export const AccordionWrap: React.FC<React.PropsWithChildren<AccordionProps>> = ({ children, ...props }) => {
  return (
    <Accordion
      radius={0}
      styles={(t) => ({
        item: {
          borderBottom: 'none'
        },
        control: {
          backgroundColor: t.colors.carbon[2],
          paddingTop: 8,
          paddingBottom: 8,
          marginTop: 16,
          '&:hover': {
            backgroundColor: t.colors.carbon[2]
          }
        },
        content: {
          padding: '16px 16px 0'
        }
      })}
      {...props}
    >
      {children}
    </Accordion>
  )
}

export const DataServiceGuideEntry = () => {
  const { currentPath, setCurrentPath, setEditAppInHelpCenter, setDataServiceGuideStep } = useHelpCenterContext()
  const accessible = useAccessCheck('ProjectDataServiceGate')

  const appGuide = [
    {
      name: 'guide',
      icon: <IconBookClosed size={16} />,
      title: 'Guided Tour of Endpoints',
      description: 'Learn how to create, test, and deploy an HTTPS endpoint to access data from an external client.',
      path: CREATE_DATA_APP_PATH
    },
    {
      name: 'sample',
      icon: <IconBookClosed size={16} />,
      title: 'Sample Data App',
      description: 'Create a Fortune 500 data app and explore four secure endpoints. ',
      path: SAMPLE_DATA_APP_PATH
    }
  ]

  const tutorials: (DataServiceCardProps & { path: string })[] = [
    ...(accessible ? appGuide : []),
    {
      name: 'docs',
      icon: <IconBookClosed size={16} />,
      title: 'TCDS Doc Site',
      description: '',
      external: true,
      path: 'https://docs.pingcap.com/tidbcloud/data-service-overview#tidb-cloud-data-service-beta-overview'
    }
  ]

  const steps = currentPath
    .split('/')
    .filter((item) => !!item)
    .map((item, index, array) => ({
      path: '/' + array.slice(0, index).concat(item).join('/'),
      title: startCase(item)
    }))

  return (
    <>
      <HelpCenterCard.Header>
        <Breadcrumbs
          styles={(theme) => ({
            separator: {
              marginLeft: 4,
              marginRight: 4,
              color: theme.colors.gray[7]
            }
          })}
        >
          {steps.map((t, index) => (
            <HeaderText
              key={t + index.toString()}
              active={index === steps.length - 1}
              onClick={() => {
                eventTracking(`${t.title} clicked`)
                setEditAppInHelpCenter(null)
                setCurrentPath(t.path)
              }}
            >
              {t.title}
            </HeaderText>
          ))}
        </Breadcrumbs>
      </HelpCenterCard.Header>
      <CenterSwitch>
        <CenterRoute path={DATA_SERVICE_BASE_PATH} exact>
          <Box sx={{ overflow: 'auto', marginLeft: -24, marginRight: -24, paddingLeft: 24, paddingRight: 24 }}>
            <Typography variant="headline-lg" mt={16}>
              Getting Started for Data Service
            </Typography>
            <Typography variant="body-lg" mt={8}>
              Use sample data to quickly get started testing the features and functionality of Data Service.
            </Typography>
            {tutorials.map((item, index) => {
              const { path, ...rest } = item
              return (
                <TutorialCard
                  {...rest}
                  mt={index !== 0 ? 8 : 24}
                  key={item.title + '' + index.toString()}
                  onClick={() => {
                    if (item.external) {
                      window.open(item.path, '_blank')
                      return
                    }

                    setCurrentPath(item.path)
                    if (item.name === 'guide') {
                      setDataServiceGuideStep(0)
                    }
                  }}
                />
              )
            })}
            <AccordionWrap>
              <Accordion.Item value="Blogs">
                <Accordion.Control>
                  <Typography variant="title-md">Blogs</Typography>
                </Accordion.Control>
                <Accordion.Panel>
                  {[
                    {
                      title: 'Embracing Low-Code Development for Backend Apps with TiDB Cloud Data Services',
                      url: 'https://www.pingcap.com/blog/low-code-development-backend-apps-tidb-cloud-data-services/'
                    },
                    {
                      title: 'Effortlessly Transform CSV into a REST API with TiDB Cloud Data Services',
                      url: 'https://www.pingcap.com/blog/backend-management-csv-rest-api-tidb-cloud-data-service/'
                    },
                    {
                      title: 'Mastering TiDB Cloud Data Service–Your Ultimate Guide to Building a Data-Driven Backend',
                      url: 'https://www.pingcap.com/blog/building-a-data-driven-backend-with-data-service/'
                    },
                    {
                      title: 'Building an AI-Powered Crypto ETF Insights App with GPTs and TiDB Cloud Data Service',
                      url: 'https://www.pingcap.com/blog/building-ai-powered-crypto-etf-insights-app-gpts-tidb-cloud-data-service/'
                    }
                  ].map((item, index) => (
                    <Flex align="flex-start" gap={8} mb={16} key={index}>
                      <Box component={IconBookClosed} size={16} mt={4} sx={{ flexShrink: 0 }} />
                      <Anchor href={item.url} target="_blank" c="carbon.8" underline="never">
                        {item.title}
                      </Anchor>
                    </Flex>
                  ))}
                </Accordion.Panel>
              </Accordion.Item>
            </AccordionWrap>

            <AccordionWrap>
              <Accordion.Item value="Vlogs">
                <Accordion.Control>
                  <Typography variant="title-md">Vlogs</Typography>
                </Accordion.Control>
                <Accordion.Panel>
                  {[
                    {
                      title: 'TiDB Cloud Data Services Building a Data Driven Backend',
                      url: 'https://www.youtube.com/watch?v=Hghv2jHYsMI'
                    }
                  ].map((item, index) => (
                    <Flex align="flex-start" gap={8} mb={16} key={index}>
                      <Box component={IconVideoRecorder} size={16} mt={4} sx={{ flexShrink: 0 }} />
                      <Anchor href={item.url} target="_blank" c="carbon.8" underline="never">
                        {item.title}
                      </Anchor>
                    </Flex>
                  ))}
                </Accordion.Panel>
              </Accordion.Item>
            </AccordionWrap>
          </Box>
        </CenterRoute>
        <CenterRoute path={CREATE_DATA_APP_PATH} exact>
          <CreateDataAppForm />
        </CenterRoute>
        <CenterRoute path={GUIDED_TOUR_OF_ENDPOINTS_PATH} exact>
          <GuidedTourOfEndpoints />
        </CenterRoute>
        <CenterRoute path={SAMPLE_DATA_APP_PATH} exact>
          <CreateSampleDataApp />
        </CenterRoute>
        <CenterRoute path={SAMPLE_DATA_SUCCESS_PATH} exact>
          <SampleDataSuccess />
        </CenterRoute>
        <CenterRedirect path={`${DATA_SERVICE_BASE_PATH}/*`} to={DATA_SERVICE_BASE_PATH} />
      </CenterSwitch>
    </>
  )
}
