import { ActionIcon, Button, Flex, Modal, MultiSelect, Typography } from '@tidbcloud/uikit'
import { usePrevious } from '@tidbcloud/uikit/hooks'
import { IconPlus } from '@tidbcloud/uikit/icons'
import { useEffect, useRef, useState } from 'react'

import { useListAppCluster, useCreateAppCluster } from 'dbaas/services/dataservice'
import { eventTracking } from 'dbaas/utils/tracking'

import { useDataApiContext } from '../context'
import { useFormatClusterList, showErrorMsg } from '../helpers'
import { EndPoint, DataSourceType } from '../types'

import CreateCluster from './CreateCluster'
import SelectWrap from './SelectWrap'

const ClusterList = () => {
  const {
    editApp,
    orgId,
    projectId,
    editEndpoint,
    setEditEndpoint,
    editEndpointRef,
    setClusterDataSource,
    clusterDataSource,
    createSession,
    isClusterError,
    setIsClusterError
  } = useDataApiContext()
  const ref = useRef<HTMLInputElement>(null)
  const [opened, setOpened] = useState(false)
  const preEndpointId = usePrevious(editEndpoint?.id)

  const { refetch: refetchAppClusters, isSuccess: isFetchAppsSucc } = useListAppCluster(
    orgId,
    projectId,
    `${editApp?.id || editEndpoint?.dataappp_id}`,
    {
      query: {
        enabled: !!orgId || !!projectId || !!editApp?.id || !!editEndpoint?.dataappp_id,
        refetchOnWindowFocus: false,
        onSuccess: (data) => {
          setClusterDataSource((data?.data || []) as DataSourceType[])
        }
      }
    }
  )

  useEffect(() => {
    if (
      !editEndpoint ||
      editEndpoint.cluster_id === '0' ||
      editEndpoint.id !== preEndpointId ||
      ['chat2data', 'chat2eda'].includes(editEndpoint?.type ?? '')
    ) {
      return
    }

    if (editEndpointRef.current && editEndpoint.session_id) {
      setEditEndpoint({
        ...editEndpointRef.current,
        session_id: ''
      })
      editEndpointRef.current?.session_id && (editEndpointRef.current.session_id = '')
    }

    createSession(editEndpoint.id)
  }, [editEndpoint?.cluster_id])

  useEffect(() => {
    const list = (clusterDataSource || []).map((cluster: DataSourceType) => {
      return {
        label: cluster.cluster_name,
        value: `${cluster.cluster_id}`
      }
    })

    if (!isFetchAppsSucc || !editEndpoint) {
      return
    }

    const endp = {
      ...editEndpointRef.current
    } as EndPoint

    if (!list.length) {
      endp.cluster_id = '0'
    } else {
      if (endp.cluster_id === '0' || !list.some((item) => item.value === editEndpoint.cluster_id)) {
        endp.cluster_id = list[0].value
      }
    }
    setEditEndpoint(endp)
    editEndpointRef.current = endp
  }, [clusterDataSource, editEndpoint?.id])

  useEffect(() => {
    setIsClusterError(false)
  }, [editEndpoint?.id, editEndpoint?.cluster_id])

  return (
    <>
      <SelectWrap
        placeholder="Select a cluster"
        styles={() => ({
          root: {
            marginRight: 8,
            minWidth: editEndpoint?.type === 'system-data' ? 280 : undefined
          }
        })}
        data={(clusterDataSource || []).map((cluster: DataSourceType) => {
          return {
            label:
              editEndpoint?.type === 'system-data'
                ? `${cluster.cluster_name} (${cluster.cluster_id})`
                : cluster.cluster_name,
            value: `${cluster.cluster_id}`
          }
        })}
        ref={ref}
        error={isClusterError}
        onDropdownClose={() => {}}
        onChange={(id) => {
          eventTracking('DataService cluster changed')
          const val = {
            ...editEndpointRef.current,
            cluster_id: `${id}`
          } as EndPoint
          setEditEndpoint(val)
          editEndpointRef.current = val
        }}
        nothingFoundMessage={
          <Flex
            onClick={() => setOpened(true)}
            align="center"
            sx={(theme) => ({
              '&:hover': {
                backgroundColor: theme.colors.carbon[3],
                cursor: 'pointer'
              },
              borderRadius: theme.defaultRadius,
              cursor: 'pointer',
              lineHeight: '40px',
              color: theme.colors.carbon[8]
            })}
          >
            <ActionIcon size={20} variant="transparent" c="carbon.8" component="span">
              <IconPlus />
            </ActionIcon>
            <span style={{ marginLeft: 4 }}>Link New Cluster</span>
          </Flex>
        }
        value={editEndpoint?.cluster_id}
      />
      <LinkClusterModal opened={opened} onClose={() => setOpened(false)} onRefetch={() => refetchAppClusters()} />
    </>
  )
}

export const LinkClusterModal: React.FC<
  React.PropsWithChildren<{ opened: boolean; onClose: () => void; onRefetch: () => void }>
> = ({ opened, onClose, onRefetch }) => {
  const { list: clusterLists } = useFormatClusterList()
  const [selectCluster, setSelectCluster] = useState<string[]>([])

  const { editApp, orgId, projectId, editEndpoint } = useDataApiContext()

  const mutation = useCreateAppCluster({
    mutation: {
      onSuccess: () => {
        onClose()
        onRefetch()
      },
      onError: (e) => {
        showErrorMsg(e)
      }
    }
  })

  return (
    <Modal title="Link Cluster" centered={true} opened={opened} onClose={() => onClose()}>
      <Typography variant="body-lg" mb={8}>
        Select clusters that allow data service access
      </Typography>

      <MultiSelect
        data={clusterLists}
        placeholder="Select one or more clusters"
        styles={{
          pillsList: {
            flexWrap: 'nowrap',
            overflow: 'hidden'
          },
          pill: {
            maxWidth: '30%'
          }
        }}
        nothingFoundMessage={<CreateCluster />}
        onChange={(values) => setSelectCluster(values)}
      />

      <Flex justify="flex-end" gap={16} sx={{ marginTop: 24 }}>
        <Button variant="default" onClick={() => onClose()} data-mp-event="mp-cancel-1691461014870">
          Cancel
        </Button>
        <Button
          loading={mutation.isLoading}
          disabled={!selectCluster?.length}
          onClick={() => {
            mutation.mutateAsync({
              orgId,
              projectId,
              appId: `${editApp?.id || editEndpoint?.dataappp_id}`,
              data: {
                cluster_ids: selectCluster
              }
            })
          }}
          data-mp-event="mp-confirm-1691461014871"
        >
          Link Cluster
        </Button>
      </Flex>
    </Modal>
  )
}

export default ClusterList
