import { Box, Divider, Group, Button, Flex, ScrollArea, Stepper, notifier, Stack, Typography } from '@tidbcloud/uikit'
import { Form, FormTextInput, FormSelect } from '@tidbcloud/uikit/biz'
import { isNil } from 'lodash-es'
import { useEffect, useRef, useState } from 'react'
import { useForm } from 'react-hook-form'

import { PRIVATE_LINK_STATUS } from 'dbaas/features/ClusterManagement/feats'
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 { getClusterPrivateLinkStatus, useCreateDataApp, useGetSampleDataAppStatus } from 'dbaas/services/dataservice'
import { getErrorMessage } from 'dbaas/services/errorCodes'
import useStores from 'dbaas/stores/useStores'

import { useHelpCenterContext } from '../context'

import { DATA_SERVICE_BASE_PATH, SAMPLE_DATA_SUCCESS_PATH } from '.'

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

  const appRef = useRef<DataApp>()

  const { watch, reset, getValues, setValue } = form

  const formValues = watch()

  const [nextLoading, setNextLoading] = useState(false)
  const { setCurrentPath, setEditAppInHelpCenter } = useHelpCenterContext()
  const {
    store: { tenantData, activeProject }
  } = useStores()

  const { mutateAsync } = useCreateDataApp()

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

  const { list: clusterList } = useFormatClusterList(false)

  useEffect(() => {
    getClusterList()
  }, [JSON.stringify(clusterList)])

  const setDefaultCluster = (list: { disabled: boolean; value: string }[]) => {
    const availableClusterId = list.find((item) => !item.disabled)
    if (availableClusterId && !getValues('cluster_ids')) {
      setValue('cluster_ids', availableClusterId.value)
    }

    if (!availableClusterId && getValues('cluster_ids')) {
      setValue('cluster_ids', '')
    }
  }

  const getClusterList = async () => {
    try {
      const dedicatedList = clusterList.filter((item) => !item.isDev && !item.disabled).map((item) => item.value)
      if (!dedicatedList.length) {
        setTimeout(() => {
          setDefaultCluster(clusterList)
        }, 4)
        return
      }

      const res = await getClusterPrivateLinkStatus(tenantData.id, activeProject.id, {
        cluster_ids: dedicatedList.join(',')
      })

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

      const list = clusterList.map((item) => {
        if (item.isDev) {
          return item
        }

        const data = (res.data || []).find((i) => i.cluster_id === item.value)
        return {
          ...item,
          disabled: !data || data.link_status !== PRIVATE_LINK_STATUS.NORMAL
        }
      })

      setDefaultCluster(list)
    } catch (e) {
      notifier.error(getErrorMessage(e, true))
    }
  }

  const handleSubmit = async (values: SampleDataProps) => {
    try {
      setNextLoading(true)
      const res = await mutateAsync({
        orgId: tenantData.id,
        projectId: activeProject.id,
        data: {
          app_type: 'dataapi',
          app_name: values.app_name,
          cluster_ids: [values.cluster_ids],
          description: values.description,
          is_sample: true
        }
      })

      if (res.code !== 200) {
        showErrorMsg(res, true)
        setNextLoading(false)
        return
      }

      const app = res.data?.app_info
      if (!app) {
        notifier.error('Failed to create Data App')
        return
      }

      localStorage.setItem('Dataservice-data', `${app.id}`)
      // setEditAppInHelpCenter(app as any as DataApp)
      appRef.current = app as any as DataApp
    } catch (e) {
      setNextLoading(false)
      showErrorMsg(e, true)
    }
  }

  const { data } = useGetSampleDataAppStatus(tenantData.id, activeProject.id, `${appRef.current?.id}`, {
    query: {
      enabled: !!tenantData.id && !!activeProject.id && !!appRef.current?.id && appRef.current.status !== 'normal',
      refetchInterval: 1000,
      refetchIntervalInBackground: false,
      refetchOnWindowFocus: false,
      useErrorBoundary: true
    }
  })

  const statusList = data?.data?.task_records

  const stepers = [
    { label: 'Create Data App', value: '' },
    { label: 'Import Sample Dataset', value: 'import_data' },
    { label: 'Create Endpoints', value: 'create_endpoint' },
    { label: 'Deploy Endpoints', value: 'deploy_endpoint' }
  ]

  const [_errIndex, setErrIndex] = useState(-1)

  useEffect(() => {
    if (!statusList?.length) {
      return
    }

    const state = statusList[statusList?.length - 1].state

    if (state === 'success') {
      setActive(stepers.length)
      return
    }

    if (state === 'fail') {
      setErrIndex(statusList.length === 1 ? 0 : statusList.length - 2)
      setActive(statusList.length === 1 ? 0 : statusList.length - 2)
      return
    }

    setActive(stepers.findIndex((step) => step.value === state) + 1)
  }, [statusList])

  const resetActive = () => {
    setActive(-1)
  }

  const isNormal = data?.data?.app_status === 'normal'

  useEffect(() => {
    if (isNormal) {
      // appRef.current = app as any as DataApp
      appRef.current && (appRef.current.status = 'normal')
      appRef.current && setEditAppInHelpCenter(appRef.current)
      reset()
      setNextLoading(false)
      setTimeout(() => {
        setCurrentPath(SAMPLE_DATA_SUCCESS_PATH)
      }, 0)
    }
  }, [isNormal])

  return (
    <ScrollArea mx={-24} mb={-24}>
      <Form<SampleDataProps> form={form} onSubmit={handleSubmit} withActions={false}>
        <Stack gap={8}>
          <Typography variant="headline-lg" mt={16} mx={24}>
            Create Sample Data App
          </Typography>
          <Typography variant="body-lg" mx={24} mb={8}>
            Welcome to the Fortune 500 Data App creation process!
          </Typography>
          <Typography variant="body-lg" mx={24}>
            Here, we'll create a Fortune 500 Data App by importing the 'fortune-500' dataset and deploying four secure
            endpoints. This app will simplify your exploration of the top 500 companies worldwide. After the Data App
            creation process is completed, you can access endpoint interfaces for rankings, financial data, trends, and
            more.
          </Typography>
          <Typography variant="body-lg" mx={24}>
            Get ready to dive into this dataset for research, analysis, and planning.
          </Typography>
          <Typography variant="body-lg" mx={24}>
            To begin, click the 'Create' button, and watch as the following steps are auto-executed to set up your data
            app and endpoints!
          </Typography>
          <Box
            py={8}
            px={24}
            mx={24}
            sx={(theme) => ({
              background: theme.colors.carbon[2]
            })}
          >
            <Stepper orientation="vertical" active={active} size="xs">
              {stepers.map((v, i) => (
                <Stepper.Step
                  mih={0}
                  key={i}
                  sx={{ display: 'flex', alignItems: 'center' }}
                  label={
                    <Typography variant="label-lg" c="carbon.8">
                      {v.label}
                    </Typography>
                  }
                  loading={false}
                ></Stepper.Step>
              ))}
            </Stepper>
          </Box>
          <Divider mt={12} />
          <FormTextInput
            mx={24}
            rules={{ required: 'Required' }}
            name="app_name"
            label={<Typography variant="title-md">Data App Name</Typography>}
          />
          <Divider mt={12} />
          <FormSelect
            rules={{ required: 'Required' }}
            nothingFoundMessage={<CreateCluster />}
            mx={24}
            data={clusterList}
            name="cluster_ids"
            placeholder="Select one cluster as your data source"
            label={<Typography variant="title-md">Link Data Source</Typography>}
          />
          <Divider mt={12} />
          <FormTextInput
            mx={24}
            mb={80}
            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}
          px={24}
          sx={(theme) => ({
            position: 'absolute',
            bottom: 0,
            borderTop: `1px solid ${theme.colors.carbon[4]}`,
            background: theme.colors.carbon[1]
          })}
        >
          <Button
            variant="default"
            size="sm"
            px={12}
            onClick={() => {
              resetActive()
              setEditAppInHelpCenter(null)
              setCurrentPath(DATA_SERVICE_BASE_PATH)
              setNextLoading(false)
            }}
          >
            Exit Tutorial
          </Button>
          <Button
            size="sm"
            px={12}
            type="submit"
            loading={nextLoading}
            disabled={
              formValues.app_name === '' || isNil(formValues.cluster_ids) || formValues.cluster_ids.length === 0
            }
          >
            Next
          </Button>
        </Flex>
      </Form>
    </ScrollArea>
  )
}
