import { Box, Button, Flex, Modal, Typography, notifier } from '@tidbcloud/uikit'
import { Form, FormTextInput, FormSelect } from '@tidbcloud/uikit/biz'
import { useEffect, useState } from 'react'
import { useForm } from 'react-hook-form'

import { ReasonHoverHint } from 'dbaas/components/HoverHint/ReasonHoverHint'
import { useAccessDeniedHintReason } from 'dbaas/contexts/access-control'
import { PRIVATE_LINK_STATUS } from 'dbaas/features/ClusterManagement/feats/chat2query/common'
import { useCreateDataApp, getClusterPrivateLinkStatus } from 'dbaas/services/dataservice'
import { getErrorMessage } from 'dbaas/services/errorCodes'

import { useDataApiContext } from '../context'
import CreateCluster from '../Editor/CreateCluster'
import { DATA_APP_NAME_RULES, useFormatClusterList } from '../helpers'
import { DataApp } from '../types'
import { makeAppName } from '../utils'

export interface SampleDataProps {
  app_name: string
  cluster_ids: string
  description?: string
}

const CreateSampleData = () => {
  const { orgId, projectId, setEditApp, getAppList } = useDataApiContext()
  const formProps = useForm<SampleDataProps>({})
  const { watch, reset, getValues, setValue } = formProps
  const name = watch('app_name')
  const clusterIds = watch('cluster_ids')
  const createMutation = useCreateDataApp()
  const [opened, setOpened] = useState(false)
  const { list: clusterList } = useFormatClusterList(false)
  const accessible = useAccessDeniedHintReason({
    id: 'ProjectDataServiceGate'
  })

  useEffect(() => {
    if (!opened) {
      return
    }

    getClusterList()
  }, [JSON.stringify(clusterList), opened])

  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(orgId, projectId, {
        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 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 Item = ({ content, hasLine }: { content: string; hasLine?: boolean }) => {
    return (
      <>
        <Typography variant="label-lg" c="carbon.8" sx={{ whiteSpace: 'nowrap' }}>
          {content}
        </Typography>
        {hasLine !== false && (
          <Box
            sx={(theme) => ({
              height: 2,
              backgroundColor: theme.colors.carbon[5],
              flex: 1
            })}
          ></Box>
        )}
      </>
    )
  }

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

      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
      }

      localStorage.setItem('Dataservice-SampleData', `${app.id}`)

      closeModal()
      setEditApp(app as any as DataApp)
      getAppList()
    } catch (e) {
      notifier.error(getErrorMessage(e, true))
    }
  }

  const closeModal = () => {
    setOpened(false)
    reset()
  }

  useEffect(() => {
    if (!opened) {
      return
    }

    setTimeout(() => {
      setValue('app_name', `fortune-500-${makeAppName(4)}`)
      setValue('description', 'Access and analyze valuable insights from Fortune 500 companies.')
    }, 10)
  }, [setValue, opened])

  return (
    <Box>
      <ReasonHoverHint reasons={[accessible.reason]}>
        {({ matched }) => (
          <Button
            data-mp-event="DataService create sample data app button clicked"
            disabled={matched}
            onClick={() => setOpened(true)}
          >
            Create Sample Data App
          </Button>
        )}
      </ReasonHoverHint>

      <Modal
        opened={opened}
        title="Create Sample Data App"
        centered
        closeOnClickOutside={false}
        trapFocus={false}
        size={800}
        onClose={closeModal}
      >
        <Typography variant="body-lg" c="carbon.8">
          <Box>Welcome to the Fortune 500 Data App creation process! </Box>
          <Box my={16}>
            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.
          </Box>
          <Box>Get ready to dive into this dataset for research, analysis, and planning.</Box>
          <Box my={16}>
            To begin, click the 'Create' button, and watch as the following steps are auto-executed to set up your data
            app and endpoints!
          </Box>
        </Typography>
        <Flex
          align="center"
          justify="space-between"
          gap={4}
          p="8px 16px"
          mb={32}
          sx={(theme) => ({
            backgroundColor: theme.colors.carbon[2]
          })}
        >
          <Item content="1. Create Data App" />
          <Item content="2. Import Sample Dataset" />
          <Item content="3. Create Endpoints" />
          <Item content="4. Deploy Endpoints" hasLine={false} />
        </Flex>

        <Form
          form={formProps}
          layout="none"
          formMode="onChange"
          actionsProps={{
            confirmText: 'Create',
            confirmProps: {
              disabled: !name || !clusterIds,
              'data-mp-event': 'DataService create sample data app button clicked'
            }
          }}
          onCancel={() => {
            setOpened(false)
            reset()
          }}
          onSubmit={createSampleDataHandler}
        >
          <Box>
            <Flex align="top" gap={24} mb={24}>
              <FormTextInput
                sx={{
                  flex: 2
                }}
                name="app_name"
                label={<Typography variant="title-md">Data App Name</Typography>}
                maxLength={31}
                placeholder="Data App name"
                rules={DATA_APP_NAME_RULES}
              />

              <FormSelect
                styles={() => ({
                  root: {
                    flex: 3
                  },
                  label: {
                    marginBottom: 8
                  },
                  values: {
                    height: 'auto'
                  }
                })}
                label={<Typography variant="title-md">Link Data Source</Typography>}
                name="cluster_ids"
                data={clusterList}
                placeholder="Select one cluster as your data source"
                nothingFoundMessage={<CreateCluster />}
              />
            </Flex>
            <FormTextInput
              name="description"
              label={
                <Flex>
                  <Typography variant="title-md">Description</Typography>
                  <Typography variant="body-lg" c="carbon.7" ml={4}>
                    (Optional)
                  </Typography>
                </Flex>
              }
              placeholder="Provide a Data App description (up to 1000 characters)"
              maxLength={1000}
            />
          </Box>
        </Form>
      </Modal>
    </Box>
  )
}

export default CreateSampleData
