import { Box, Center, Loader } from '@tidbcloud/uikit'
import { IconRefreshCcw01, IconXClose } from '@tidbcloud/uikit/icons'
import axios from 'axios'
import { observer } from 'mobx-react'
import React, { useEffect, useState, useRef } from 'react'

import { log } from 'common/log'
import ResizableContainer from 'dbaas/components/ResizableContainer'
import { Store, Actions } from 'dbaas/stores'
import useStores from 'dbaas/stores/useStores'

interface IPushableWrapProps {
  children?: any
  actions?: Actions
  store?: Store
  [key: string]: any
}

const errMsgStyle: React.CSSProperties = {
  position: 'absolute',
  top: '50%',
  left: '50%',
  transform: 'translate(-50%, -50%)',
  color: '#fff',
  textAlign: 'center',
  fontSize: '22px'
}

const errMsgText: React.CSSProperties = {
  color: '#fff',
  fontSize: '26px',
  display: 'inline-block',
  margin: 0,
  padding: 0
}

export const SQLShell: React.FC<React.PropsWithChildren<IPushableWrapProps>> = observer((props) => {
  const { store, actions } = useStores()
  const [loading, setLoading] = useState(true)
  const [showShell, setShowShell] = useState(false)
  const [showIframe, setShowIframe] = useState(false)
  const iframeRef = useRef<HTMLIFrameElement>() as React.RefObject<HTMLIFrameElement>
  const [errMsg, setErrMsg] = useState('')

  const { shellVisibleUrl } = store

  const checkShellStatus = (url: string) => {
    setShowShell(true)
    setLoading(true)
    setErrMsg('')
    setShowIframe(false)

    axios
      .get(url)
      .then(() => {
        setShowIframe(true)
      })
      .catch((e) => {
        log.error('load webshell error', e)
        setErrMsg('A system error occurred, please try again later.')
        setLoading(false)
        setShowIframe(false)
      })
  }

  const onRetry = () => {
    checkShellStatus(shellVisibleUrl)
  }

  const onIframeLoad = () => {
    setLoading(false)
  }

  const onCloseShell = () => {
    actions.hideShell()
  }

  useEffect(() => {
    switch (shellVisibleUrl) {
      case '':
      case 'hide':
      case 'close':
        setShowShell(false)
        setShowIframe(false)
        setErrMsg('')
        break
      // means reset url, should show shell and reload shell
      default:
        checkShellStatus(shellVisibleUrl)
    }
  }, [shellVisibleUrl])

  if (!showShell) {
    return null
  }

  return (
    <ResizableContainer
      as="div"
      className="terminal-container"
      defaultSize={{
        width: '100%',
        height: '50vh'
      }}
      style={{
        background: '#10141D',
        position: 'fixed',
        bottom: 0,
        left: 0,
        transition: 'all 0.3s',
        zIndex: 20
      }}
      minHeight="50vh"
    >
      <Box
        component={IconXClose}
        size={20}
        sx={{
          position: 'absolute',
          top: 8,
          right: 6,
          margin: 0,
          color: 'white',
          cursor: 'pointer',
          zIndex: 9999 // TODD with zIndex const list
        }}
        onClick={onCloseShell}
      />

      {props.children}

      {errMsg ? (
        <div style={errMsgStyle}>
          <h3 style={errMsgText}>{errMsg}</h3>
          <span style={{ padding: '1.5rem', cursor: 'pointer' }} onClick={onRetry}>
            <IconRefreshCcw01 size={20} />
          </span>
        </div>
      ) : null}

      {loading && (
        <Center h="100%">
          <Loader color="gray"></Loader>
        </Center>
      )}

      {showIframe && (
        <iframe
          title="SQL Shell Terminal"
          id="sql-shell-terminal-iframe"
          style={{
            width: '100%',
            height: '100%',
            border: 'none',
            overflow: 'hidden',
            background: '#10141D',
            fontFamily: 'inherit'
          }}
          scrolling="no"
          onLoad={onIframeLoad}
          src={shellVisibleUrl}
          ref={iframeRef}
        />
      )}
    </ResizableContainer>
  )
})

export default SQLShell
