import { BoxProps } from '@tidbcloud/uikit'
import { observer } from 'mobx-react'
import React, { createContext, useContext, useState, Dispatch, SetStateAction } from 'react'
import { matchPath, useLocation } from 'react-router-dom'

import useStores from 'dbaas/stores/useStores'
import { eventTracking } from 'dbaas/utils/tracking'
import { useDynamicLocalStorage } from 'dbaas/utils/useSessionStorage'

import { DataApp } from '../DataService/types'
import type { SqlFile } from '../SqlEditor/types'

import { DATA_SERVICE_BASE_PATH } from './DataService'
import { DEFAULT_AGENT_PANEL_EXPANDED, getAgentPanelExpandedStorageKey, MIN_CENTER_HEIGHT } from './layout'

type SetAction<T> = Dispatch<SetStateAction<T>>

export const DEFAULT_HELP_PATH = '/help'

export interface HelpCenterData {
  dialogOpened: boolean
  dialogHeight: number
  setDialogHeight: SetAction<number>
  agentPanelExpanded: boolean
  setAgentPanelExpanded: SetAction<boolean>
  currentPath: string
  setCurrentPath: SetAction<string>
  routeMatched: boolean
  setRouteMatched: SetAction<boolean>
  openDialog: () => void
  closeDialog: () => void
  toggleDialog: () => void
  incomingSQLFile: SqlFile | null
  setIncomingSQLFile: SetAction<SqlFile | null>
  outgoingSQLFile: SqlFile | null
  setOutgoingSQLFile: SetAction<SqlFile | null>
  chat2queryReady: boolean
  setChat2queryReady: SetAction<boolean>
  needSetChat2queryCursor: boolean
  setNeedSetChat2queryCursor: SetAction<boolean>
  openChat2queryUserGuide: boolean
  setOpenChat2queryUserGuide: SetAction<boolean>
  openCreateSampleDataApp: boolean
  setOpenCreateSampleDataApp: SetAction<boolean>
  editAppInHelpCenter: DataApp | null
  setEditAppInHelpCenter: SetAction<DataApp | null>
  dataServiceGuideStep: number
  setDataServiceGuideStep: SetAction<number>
  dataServiceTooltipShow: boolean
  setDataServiceTooltipShow: SetAction<boolean>
  showDataServiceTooltip: () => void
  setNoDataAppTooltipShow: SetAction<boolean>
  noDataAppTooltipShow: boolean
  extraContext: Record<string, any> | null
  setExtraContext: SetAction<Record<string, any> | null>
  rootStyles: BoxProps['sx']
  setRootStyles: SetAction<BoxProps['sx']>
}

export const HelpCenterContext = createContext<HelpCenterData | null>(null)

export const useHelpCenterStorePrefix = () => {}

export const HelpCenterProvider: React.FC<React.PropsWithChildren<unknown>> = observer((props) => {
  const [dialogOpened, setDialogOpened] = useState(false)
  const [incomingSQLFile, setIncomingSQLFile] = useState<SqlFile | null>(null)
  const [outgoingSQLFile, setOutgoingSQLFile] = useState<SqlFile | null>(null)
  const [needSetChat2queryCursor, setNeedSetChat2queryCursor] = useState(false)
  const [extraContext, setExtraContext] = useState<Record<string, any> | null>(null)
  const [rootStyles, setRootStyles] = useState<BoxProps['sx']>({})
  const {
    store: { tenantData, userProfile }
  } = useStores()
  const storeKey = `dbaas.helpcenter-path:${userProfile.id}:${tenantData.id}`
  const [currentPath, setCurrentPath] = useDynamicLocalStorage({
    key: storeKey,
    defaultValue: '/help'
  })
  const [agentPanelExpanded, setAgentPanelExpanded] = useDynamicLocalStorage({
    key: getAgentPanelExpandedStorageKey(userProfile.id),
    defaultValue: DEFAULT_AGENT_PANEL_EXPANDED
  })
  const [chat2queryReady, setChat2queryReady] = useState(false)
  const [dialogHeight, setDialogHeight] = useState(MIN_CENTER_HEIGHT)
  const [routeMatched, setRouteMatched] = useState(false)
  const [openChat2queryUserGuide, setOpenChat2queryUserGuide] = useState(false)
  const [openCreateSampleDataApp, setOpenCreateSampleDataApp] = useState(false)
  const [editAppInHelpCenter, setEditAppInHelpCenter] = useState(null)
  const [dataServiceGuideStep, setDataServiceGuideStep] = useState(0)
  const [dataServiceTooltipShow, setDataServiceTooltipShow] = useState(false)
  const [noDataAppTooltipShow, setNoDataAppTooltipShow] = useState(false)

  const location = useLocation()

  const openDialog = () => {
    beforeOpen()
    setDialogOpened(true)
    eventTracking('Help Center Opened')
  }

  const closeDialog = () => {
    setDialogOpened(false)
    eventTracking('Help Center Closed')
  }

  const toggleDialog = () => setDialogOpened((v) => !v)

  const beforeOpen = () => {
    const isDataservice = !!matchPath(location.pathname, {
      path: '/project/data-service',
      exact: true
    })
    if (isDataservice && !currentPath.includes('/help/DataService')) {
      setCurrentPath(DATA_SERVICE_BASE_PATH)
    }
  }

  const showDataServiceTooltip = () => {
    setDataServiceTooltipShow(true)
    setTimeout(() => setDataServiceTooltipShow(false), 5000)
  }

  return (
    <HelpCenterContext.Provider
      value={{
        dialogOpened,
        openDialog,
        closeDialog,
        toggleDialog,
        currentPath,
        setCurrentPath,
        routeMatched,
        setRouteMatched,
        incomingSQLFile,
        setIncomingSQLFile,
        chat2queryReady,
        setChat2queryReady,
        outgoingSQLFile,
        setOutgoingSQLFile,
        needSetChat2queryCursor,
        setNeedSetChat2queryCursor,
        dialogHeight,
        setDialogHeight,
        agentPanelExpanded,
        setAgentPanelExpanded,
        openChat2queryUserGuide,
        setOpenChat2queryUserGuide,
        openCreateSampleDataApp,
        setOpenCreateSampleDataApp,
        editAppInHelpCenter,
        setEditAppInHelpCenter,
        dataServiceGuideStep,
        setDataServiceGuideStep,
        dataServiceTooltipShow,
        setDataServiceTooltipShow,
        showDataServiceTooltip,
        noDataAppTooltipShow,
        setNoDataAppTooltipShow,
        extraContext,
        setExtraContext,
        rootStyles,
        setRootStyles
      }}
    >
      {props.children}
    </HelpCenterContext.Provider>
  )
})

export const useHelpCenterContext = () => {
  const context = useContext(HelpCenterContext)
  if (!context) {
    throw new Error('HelpContext is empty')
  }
  return context
}
