import { Select, Modal, Loader, Center, Anchor, Flex, Typography, Box, ActionIcon } from '@tidbcloud/uikit'
import { CodeBlock } from '@tidbcloud/uikit/biz'
import { IconPlus } from '@tidbcloud/uikit/icons'
import { useEffect, useMemo, useState } from 'react'

import { useGetAllDbData } from 'dbaas/services'
import { useListAppCluster } from 'dbaas/services/dataservice'
import { useGetEndpointCodeExample } from 'dbaas/services/dataservice'

import { useDataApiContext } from '../context'
import { LinkClusterModal } from '../Editor/ClusterList'
import { EndPoint } from '../types'

interface CodeExampleResult {
  prod: { code: string; type: string }[]
}

const CodeExample: React.FC<React.PropsWithChildren<{ default: boolean; endpoint?: EndPoint; onClose: () => void }>> = (
  props
) => {
  const { orgId, projectId, appList, editEndpoint, editEndpointRef, setEditEndpoint, setEditApp, setDataappOpenedTab } =
    useDataApiContext()

  const [opened, setOpened] = useState(props.default)
  const [clusterId, setClusterId] = useState('')
  const [database, setDatabase] = useState('')
  const [exampleType, setExampleType] = useState('')
  const [authType, setAuthType] = useState('digest')
  const [linkModalOpend, setLinkModalOpend] = useState(false)
  const [endp, setEndp] = useState<EndPoint | null>(null)

  useEffect(() => {
    setOpened(props.default)
  }, [props.default])

  useEffect(() => {
    setEndp(props.endpoint || editEndpoint)
  }, [props.endpoint?.id, editEndpoint?.id])

  const isSummaryEndpoint = useMemo(() => {
    const whiteList = [
      '/v2/dataSummaries',
      '/v3/dataSummaries',
      '/v3/knowledgeBases',
      '/v3/sessions',
      '/v3/suggestQuestions',
      '/v2/chat2data',
      '/v3/chat2data',
      '/v3/refineSql',
      '/v2/executeQuery',
      '/v1/chat2data',
      '/v2/sqlRefine'
    ]
    return whiteList.includes(endp?.endpoint ?? '') || endp?.type === 'system-data'
  }, [endp?.id])

  const { data: clusters, refetch: refetchAppClusters } = useListAppCluster(orgId, projectId, `${endp?.dataappp_id}`, {
    query: {
      enabled: !!orgId && !!projectId && !!opened && !!endp?.dataappp_id && !!isSummaryEndpoint,
      refetchOnWindowFocus: false
    }
  })

  const { data: dbData, isLoading: isDbLoading } = useGetAllDbData(
    orgId,
    projectId,
    clusterId,
    {
      isbrief: 'true'
    },
    {
      query: {
        enabled: !!clusterId && isSummaryEndpoint,
        refetchOnWindowFocus: false
      }
    }
  )

  const {
    data: example,
    isLoading: isCodeExampleLoading,
    refetch: refetchCodeExample
  } = useGetEndpointCodeExample(
    orgId,
    projectId,
    `${endp?.dataappp_id}`,
    `${endp?.id}`,
    {
      cluster_id: clusterId,
      database,
      auth_type: authType
    },
    {
      query: {
        cacheTime: 0,
        enabled:
          !!orgId && !!projectId && !!endp?.id && opened && (isSummaryEndpoint ? !!clusterId && !!database : true),
        refetchOnWindowFocus: false
      }
    }
  )

  useEffect(() => {
    if (example?.data) {
      setExampleType((example?.data as CodeExampleResult).prod[0].code)
    } else {
      setExampleType('')
    }
  }, [example?.data])

  useEffect(() => {
    if (dbData?.data?.length) {
      setDatabase(dbData.data[0].name || '')
    }
  }, [dbData?.data])

  useEffect(() => {
    if (clusters?.data?.length) {
      setClusterId(clusters.data[0].cluster_id ?? '')
    }
  }, [clusters?.data])

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

    if (endp?.cluster_id && endp?.cluster_id !== '0') {
      setClusterId(endp.cluster_id)
    }

    refetchCodeExample()
  }, [opened])

  return (
    <>
      <Modal
        title="Code Example"
        size={700}
        opened={opened}
        centered={true}
        trapFocus={false}
        onClose={() => {
          setOpened(false)
          props.onClose()
        }}
      >
        <Flex gap={16} mb={16}>
          {isSummaryEndpoint && (
            <>
              <Select
                data={(clusters?.data || []).map((item) => {
                  return {
                    label: item.cluster_name ?? '',
                    value: item.cluster_id ?? ''
                  }
                })}
                sx={{ flex: 1 }}
                value={clusterId}
                onChange={(val) => {
                  if (val === clusterId) {
                    return
                  }
                  setClusterId(val || '')
                  setDatabase('')
                }}
                nothingFoundMessage={
                  <Flex
                    onClick={() => setLinkModalOpend(true)}
                    align="center"
                    sx={(theme) => ({
                      '&:hover': {
                        backgroundColor: theme.colors.carbon[3],
                        cursor: 'pointer'
                      },
                      borderRadius: theme.defaultRadius,
                      cursor: 'pointer',
                      lineHeight: '40px',
                      paddingLeft: 12,
                      color: theme.colors.carbon[8]
                    })}
                  >
                    <ActionIcon
                      aria-label="Link New Cluster"
                      size={20}
                      variant="transparent"
                      c="carbon.8"
                      component="span"
                    >
                      <IconPlus />
                    </ActionIcon>
                    <span style={{ marginLeft: 4 }}>Link New Cluster</span>
                  </Flex>
                }
              />

              <Select
                data={
                  isDbLoading
                    ? []
                    : (dbData?.data || []).map((db: { name: string }) => {
                        return {
                          label: db.name,
                          value: db.name
                        }
                      })
                }
                // placeholder={isDbLoading ? 'Loading...' : ''}
                sx={{ flex: 1 }}
                value={database}
                onChange={(val) => setDatabase(val || '')}
              />
            </>
          )}

          <Select
            defaultValue="digest"
            data={[
              { label: 'Basic Authentication', value: 'basic' },
              { label: 'Digest Authentication', value: 'digest' }
            ]}
            onChange={(auth) => setAuthType(auth || 'digest')}
          />
        </Flex>

        {isCodeExampleLoading ? (
          <Center>
            <Loader size="sm" />
          </Center>
        ) : (
          <Box>
            {exampleType && <CodeBlock>{(exampleType || '').replaceAll('\\n', '\n').replaceAll('\t', '  ')}</CodeBlock>}
          </Box>
        )}

        <Typography variant="body-md" mt={16}>
          Accessing the endpoint requires an API Key.
          <Anchor
            mx={4}
            fw={600}
            onClick={() => {
              const app = appList.find((app) => `${app.id}` === `${endp?.dataappp_id}`)
              if (app) {
                setEditEndpoint(null)
                editEndpointRef.current = null
                setEditApp(app)

                setOpened(false)
                setDataappOpenedTab('Settings')
              }
            }}
          >
            Create an API Key
          </Anchor>
          if you don't have it yet.
        </Typography>
      </Modal>

      <LinkClusterModal
        opened={linkModalOpend}
        onClose={() => setLinkModalOpend(false)}
        onRefetch={() => refetchAppClusters()}
      />
    </>
  )
}

export default CodeExample
