import { Accordion, Box, Text, ActionIcon, Flex, Menu, Loader, HoverCard, Typography } from '@tidbcloud/uikit'
import {
  IconChevronRightFill,
  IconDataService,
  IconPlus,
  IconChevronRight,
  IconDataAppAi,
  IconInfoCircle
} from '@tidbcloud/uikit/icons'
import { isNil } from 'lodash-es'
import { ResizeCallback } from 're-resizable'
import { useEffect, useState } from 'react'

import ResizableContainer from 'dbaas/components/ResizableContainer'
import { useHelpCenterContext } from 'dbaas/screens/HelpCenter/context'
import { createEndpoint } from 'dbaas/services/dataservice'
import { eventTracking } from 'dbaas/utils/tracking'

import { useDataApiContext, LEFT_PANEL_DEFAULT_WIDTH, LEFT_PANEL_MIN_WIDTH } from '../context'
import { useCreateEndpCallbackHandler } from '../helpers'
import { useCommonStyles } from '../index.styles'
import { DataApp, EndPoint } from '../types'

import { AgeFormModal } from './AgeFormModal'
import EndpointItem from './EndpointItem'
import FileFilter from './FileFilter'
import Header from './Header'
import { useStyles } from './index.styles'
import { MgmtEndpLibModal } from './MgmtEndpLibModal'

const SideMenu = () => {
  const [resizing, setResizing] = useState(false)
  const {
    layout: { leftPanel },
    setLeftPanelLayout,
    orgId,
    projectId,
    editEndpoint,
    setEditEndpoint,
    setEditApp,
    editApp,
    setRenamedEndpoint,
    editEndpointRef,
    clusterDataSource,
    setIsAutoSaveClose,
    resetLeftPanelLayout,
    newAppListExpandKey,
    setDataappOpenedTab
  } = useDataApiContext()
  const [expandVal, setExpandVal] = useState<string[]>([])
  const [filterAppList, setFilterAppList] = useState<DataApp[]>([])
  const [ageModalShow, setAgeModalShow] = useState<boolean>(false)
  const [mgmtEndpModalShow, setMgmtEndpModalShow] = useState<boolean>(false)
  const [appIdForMenu, setAppIdForMenu] = useState<string>()
  const { updateSelectData } = useCreateEndpCallbackHandler()

  const endpointDefaultParams = {
    name: '/untitled_endpoint',
    sql_template: '',
    method: 'GET',
    settings: {
      row_limit: 1000,
      timeout: 30000
    },
    cluster_id: (clusterDataSource?.length && clusterDataSource[0]?.cluster_id) || '0'
  }
  const [_isCreatingEndp, setIsCreatingEndp] = useState(false)
  const { classes } = useStyles()
  const { classes: commonClasses } = useCommonStyles()
  const { editAppInHelpCenter, dataServiceGuideStep, setDataServiceGuideStep } = useHelpCenterContext()

  useEffect(() => {
    if (!editEndpoint) {
      return
    }
    addExpandKey(editEndpoint?.dataappp_id)
  }, [editEndpoint?.id])

  useEffect(() => {
    newAppListExpandKey && addExpandKey(newAppListExpandKey)
  }, [newAppListExpandKey])

  const addExpandKey = (newKey: string | number) => {
    const keys = new Set(expandVal)
    keys.add(`${newKey}`)
    setExpandVal(Array.from(keys))
  }

  const onResize: ResizeCallback = (_event, _direction, _elementRef, delta) => {
    if ((leftPanel.width || 0) + delta.width <= LEFT_PANEL_MIN_WIDTH + 10) {
      setLeftPanelLayout({
        hidden: true
      })
    } else {
      setLeftPanelLayout({
        hidden: false
      })
    }
    setResizing(true)
  }

  const onResizeStop: ResizeCallback = (_event, _direction, _elementRef, delta) => {
    setResizing(false)
    if ((leftPanel.width || 0) + delta.width <= LEFT_PANEL_MIN_WIDTH / 2) {
      setLeftPanelLayout({
        hidden: true
      })
      return
    }
    setLeftPanelLayout({
      hidden: false,
      width: Math.max(LEFT_PANEL_MIN_WIDTH, (leftPanel.width || 0) + delta.width)
    })
  }

  useEffect(() => {
    if (!editApp || !leftPanel.hidden) {
      return
    }

    setLeftPanelLayout({
      hidden: false,
      width: LEFT_PANEL_MIN_WIDTH
    })
  }, [editApp])

  useEffect(() => {
    setIsAutoSaveClose(mgmtEndpModalShow)
  }, [mgmtEndpModalShow])

  const createEp = async (appId: string) => {
    setIsCreatingEndp(true)

    try {
      const res = await createEndpoint(orgId, projectId, appId, endpointDefaultParams)
      setIsCreatingEndp(false)

      if (res.code === 200) {
        const ep = res.endpoint as EndPoint
        setEditEndpoint(ep)
        editEndpointRef.current = ep
        setEditApp(null)

        if (dataServiceGuideStep <= 1) {
          setRenamedEndpoint(ep)
        }

        await updateSelectData(ep, true)
        setExpandVal([`${ep.dataappp_id}`])

        if (!isNil(editAppInHelpCenter) && dataServiceGuideStep > 1) {
          setDataServiceGuideStep(dataServiceGuideStep + 1)
          eventTracking('Guided Tour step 3')
        }
      }
    } catch (_e) {
      setIsCreatingEndp(false)
    }
  }

  return (
    <ResizableContainer
      className={resizing ? '' : commonClasses.resizerContainer}
      enable={{
        top: false,
        right: editApp ? false : true,
        bottom: false,
        left: editApp ? false : true,
        topRight: false,
        bottomRight: false,
        bottomLeft: false,
        topLeft: false
      }}
      size={{ width: leftPanel.hidden ? 0 : (leftPanel.width ?? LEFT_PANEL_DEFAULT_WIDTH), height: '100%' }}
      handleClasses={{ right: commonClasses.resizer }}
      onResize={onResize}
      onResizeStop={onResizeStop}
      minWidth={leftPanel.hidden ? 1 : LEFT_PANEL_MIN_WIDTH}
      maxWidth="50%"
    >
      <Flex
        direction="column"
        h="100%"
        sx={(theme) => ({
          overflow: 'hidden',
          backgroundColor: theme.white,
          borderRight: `1px solid ${theme.colors.carbon[3]}}`,
          position: 'relative'
        })}
      >
        <Header />

        <Flex direction="column" sx={{ overflow: 'hidden', height: '100%' }}>
          <FileFilter onChange={(list: DataApp[]) => setFilterAppList(list)} />
          <Box
            component="div"
            p={16}
            sx={{
              flex: 1,
              overflow: 'auto'
            }}
          >
            <Accordion
              chevronPosition="left"
              chevron={
                <ActionIcon
                  variant="transparent"
                  component="span"
                  color="carbon.8"
                  sx={{
                    ':hover': {
                      color: 'initial'
                    }
                  }}
                >
                  <IconChevronRightFill size={14} />
                </ActionIcon>
              }
              styles={(theme) => ({
                chevron: {
                  '&[data-rotate]': {
                    transform: 'rotate(90deg)'
                  },
                  marginTop: -4,
                  marginRight: 0,
                  marginLeft: 0,
                  minWidth: 28,
                  width: 28
                },
                label: {
                  color: theme.colors.carbon[8],
                  whiteSpace: 'nowrap',
                  overflow: 'hidden',
                  textOverflow: 'ellipsis',
                  padding: 0
                },
                content: {
                  padding: '4px 0 4px 18px',
                  borderRadius: 4,
                  backgroundColor: 'transparent'
                },
                item: {
                  marginBottom: 2,
                  border: 'none',
                  color: theme.colors.carbon[8],
                  fontSize: 13,
                  backgroundColor: 'transparent'
                },
                control: {
                  padding: 0,
                  backgroundColor: 'transparent',
                  '&:hover': {
                    backgroundColor: 'transparent'
                  }
                }
              })}
              multiple
              value={expandVal}
              onChange={(val) => {
                setExpandVal(val)
                eventTracking('DataApp fold icon clicked')
              }}
            >
              {filterAppList.map((app) => (
                <Accordion.Item value={`${app.id}`} key={app.id} data-test-name="app-item">
                  <Flex
                    data-guide={`data-service-${app.id}`}
                    align="center"
                    gap={8}
                    justify="space-between"
                    sx={(theme) => ({
                      position: 'relative',
                      cursor: 'pointer',
                      borderRadius: 4,
                      paddingLeft: 4,
                      border: '0',
                      lineHeight: '28px',
                      backgroundColor: editApp?.id === app.id ? theme.colors.carbon[3] : 'transparent',
                      '&:hover': { backgroundColor: theme.colors.carbon[3] }
                    })}
                    className={classes.accordionItem}
                  >
                    <Box
                      sx={{
                        maxWidth: '100%',
                        width: '100%',
                        overflow: 'hidden'
                      }}
                    >
                      <Accordion.Control>
                        <Flex
                          align="center"
                          onClick={(e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
                            e.preventDefault()
                            e.stopPropagation()
                            if (app.status === 'initializing') {
                              return
                            }
                            setEditEndpoint(null)
                            editEndpointRef.current = null
                            setEditApp(app)
                            localStorage.setItem('data-service-edit-endpoint', '')

                            if (app.app_type !== 'chat2query') {
                              setDataappOpenedTab('Overview')
                            }
                          }}
                        >
                          {app.status === 'initializing' && (
                            <Box
                              sx={(theme) => ({
                                height: 18,
                                position: 'absolute',
                                left: 4,
                                borderRadius: 16,
                                backgroundColor: editApp?.id === app.id ? theme.colors.carbon[3] : theme.white,
                                '&:hover': {
                                  backgroundColor: theme.colors.carbon[3]
                                }
                              })}
                            >
                              <Loader size={18} />
                            </Box>
                          )}
                          <Box mr={4} lh={1} h={14}>
                            {app.app_type === 'chat2query' ? (
                              <IconDataAppAi size={14} />
                            ) : (
                              <IconDataService size={14} />
                            )}
                          </Box>
                          <Text
                            component="span"
                            sx={() => ({
                              overflow: 'hidden',
                              textOverflow: 'ellipsis',
                              fontSize: 13
                            })}
                          >
                            {app.app_name}
                          </Text>
                        </Flex>
                      </Accordion.Control>
                    </Box>
                    {app.app_type !== 'chat2query' && app.status === 'normal' && (
                      <Menu
                        position="bottom-start"
                        styles={() => ({
                          item: {
                            fontSize: 13
                          }
                        })}
                        opened={app.id === editAppInHelpCenter?.id && dataServiceGuideStep === 2 ? true : undefined}
                      >
                        <Menu.Target data-test-name="menu-target">
                          <ActionIcon
                            aria-label="Menu"
                            variant="transparent"
                            color="carbon.8"
                            sx={(theme) => ({
                              '&:hover': {
                                backgroundColor: theme.colors.carbon[4]
                              }
                            })}
                          >
                            <IconPlus size={16} />
                          </ActionIcon>
                        </Menu.Target>
                        <Menu.Dropdown sx={{ position: 'fixed' }} data-guide="menu-drop-down">
                          <Menu.Item
                            disabled={dataServiceGuideStep === 2}
                            data-mp-event="DataService auto generate clicked"
                            onClick={() => {
                              setAppIdForMenu(app.id)
                              setAgeModalShow(true)
                            }}
                          >
                            <Flex align="center" gap={8}>
                              Autogenerate Endpoint
                              <HoverCard position="right" width={360} withArrow>
                                <HoverCard.Target>
                                  <IconInfoCircle />
                                </HoverCard.Target>
                                <HoverCard.Dropdown>
                                  <Typography variant="body-md">
                                    Quickly generate - Create, Retrieve, Update, and Delete (CRUD) endpoints and Vector
                                    endpoints for a table with automated configurations. Ideal for quick data
                                    exploration.
                                  </Typography>
                                </HoverCard.Dropdown>
                              </HoverCard>
                            </Flex>
                          </Menu.Item>
                          <Menu.Item
                            sx={(theme) =>
                              dataServiceGuideStep === 2 ? { border: `1px solid ${theme.colors.peacock[7]}` } : {}
                            }
                            data-guide="create-endpoint"
                            data-mp-event="DataService create endpoint clicked"
                            data-mp-source="side menu top"
                            onClick={() => {
                              createEp(app.id)
                            }}
                          >
                            <Flex align="center" gap={8}>
                              Create Endpoint
                              <HoverCard position="right" width={360} withArrow>
                                <HoverCard.Target>
                                  <IconInfoCircle />
                                </HoverCard.Target>
                                <HoverCard.Dropdown>
                                  <Typography variant="body-md">
                                    Build custom endpoint from the ground up, tailoring configurations to meet unique
                                    application requirements.
                                  </Typography>
                                </HoverCard.Dropdown>
                              </HoverCard>
                            </Flex>
                          </Menu.Item>
                          <Menu.Item
                            disabled={dataServiceGuideStep === 2}
                            data-mp-event="DataService manage endpoint library clicked"
                            onClick={() => {
                              setAppIdForMenu(app.id)
                              setMgmtEndpModalShow(true)
                            }}
                          >
                            <Flex align="center" gap={8}>
                              Manage Endpoint Library
                              <HoverCard position="right" width={360} withArrow>
                                <HoverCard.Target>
                                  <IconInfoCircle />
                                </HoverCard.Target>
                                <HoverCard.Dropdown>
                                  <Typography variant="body-md">
                                    Effortlessly manage the Endpoint Library, comprising a catalog of predefined
                                    system-provided endpoints. Add or remove endpoints without the need to create them
                                    from the ground up.
                                  </Typography>
                                </HoverCard.Dropdown>
                              </HoverCard>
                            </Flex>
                          </Menu.Item>
                        </Menu.Dropdown>
                      </Menu>
                    )}
                  </Flex>
                  <EndpointItem app={app} expandVal={expandVal} />
                </Accordion.Item>
              ))}
            </Accordion>
          </Box>
        </Flex>

        {leftPanel.hidden && !resizing && (
          <Flex
            align="center"
            sx={(theme) => ({
              position: 'absolute',
              top: 'calc(50% - 15px)',
              right: -18,
              width: 18,
              height: 30,
              backgroundColor: theme.colors.carbon[3],
              borderRadius: '0 18px 18px 0',
              zIndex: 1
            })}
            onClick={() => {
              resetLeftPanelLayout()
            }}
          >
            <ActionIcon
              variant="transparent"
              sx={{
                width: 18,
                minWidth: 18,
                padding: 0
              }}
              color="carbon.6"
            >
              <IconChevronRight size={16} />
            </ActionIcon>
          </Flex>
        )}
      </Flex>
      <AgeFormModal
        opened={ageModalShow}
        editEndpoint={editEndpoint}
        appId={appIdForMenu || ''}
        onClose={() => setAgeModalShow(false)}
      />
      {mgmtEndpModalShow && <MgmtEndpLibModal appId={appIdForMenu || ''} onClose={() => setMgmtEndpModalShow(false)} />}
    </ResizableContainer>
  )
}

export default SideMenu
