import {
  Stack,
  SimpleGrid,
  Group,
  TextInput,
  Select,
  Box,
  Button,
  Typography,
  Tabs,
  PrismProps,
  Alert
} from '@tidbcloud/uikit'
import { CodeBlock } from '@tidbcloud/uikit/biz'
import { IconFileMinus03, IconTerminalSquare } from '@tidbcloud/uikit/icons'
import { observer } from 'mobx-react'

import { AccessDeniedHoverHint, AccessGuard } from 'dbaas/contexts/access-control'
import { Commonv1beta1ServicePlan } from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2/interface'
import { MixpanelEvents } from 'dbaas/utils/tracking'

import { NetworkType } from '../types'

import { ConnectionClientFooter } from './Footer'
import {
  isParamsBlock,
  getConnCode,
  getRootClientOptions,
  useCodeCopy,
  getCodeVarData,
  useConnections
} from './helpers'
import { ParamsBlock } from './ParamsBlock'
import { useDownloadCA } from './use-download-ca'

const icons = {
  terminal: <IconTerminalSquare size={16} />,
  file: <IconFileMinus03 size={16} />
}

interface ConnectionClientBlockProps {
  tidbId: string | undefined
  pwdInited?: boolean
  networkType: NetworkType
  client: string
  onClientChange: (client: string) => void
  onPwdSet: () => void
  caRequired?: boolean
  servicePlan?: Commonv1beta1ServicePlan
  host: string | undefined
  port: number | undefined
  userToken: string | undefined
}

export const ConnectionClientBlock = observer(
  ({
    tidbId,
    pwdInited,
    networkType,
    client: rootClient,
    onClientChange: onRootClientChange,
    onPwdSet,
    caRequired,
    servicePlan,
    host,
    port,
    userToken
  }: ConnectionClientBlockProps) => {
    const rootClientOptions = getRootClientOptions(networkType)
    const codeVars = getCodeVarData({
      endpoint: {
        host,
        port
      },
      db: 'test',
      userToken
    })
    const { download: downloadCA, isUrlFetching: isCAUrlFetching } = useDownloadCA(tidbId || '')

    /**
     * connection client and codes
     */
    const { withSubClient, rootConn, subConns, currentConn, activeSubConnId, onSubConnIdChange } = useConnections({
      networkType,
      rootClient
    })

    const codeHandlers = useCodeCopy({
      networkType,
      rootClient,
      mpEvents: {
        freeCopy: MixpanelEvents.TidbConnectCode.Copy.CommandExecuted,
        btnCopy: MixpanelEvents.TidbConnectCode.Copy.ButtonClicked
      }
    })

    if (!tidbId) {
      return null
    }

    return (
      <Stack
        p="xl"
        bg="carbon.3"
        sx={(theme) => ({
          borderBottomLeftRadius: theme.defaultRadius,
          borderBottomRightRadius: theme.defaultRadius
        })}
      >
        <SimpleGrid cols={2} verticalSpacing="xl">
          <Group gap={0} wrap="nowrap">
            <TextInput
              placeholder="Connect With"
              readOnly
              styles={(theme) => ({
                wrapper: {
                  width: 'min-content',
                  minWidth: 128,
                  maxWidth: 'min-content'
                },
                input: {
                  borderTopRightRadius: 0,
                  borderBottomRightRadius: 0,
                  borderRight: 'none',
                  '&:focus, &:focus-within': {
                    borderColor: theme.colors.carbon[5]
                  },
                  '&::placeholder': {
                    color: theme.colors.carbon[7]
                  }
                }
              })}
            />
            <Select
              value={rootClient}
              data={rootClientOptions}
              onChange={(val) => onRootClientChange(val || '')}
              styles={{
                root: {
                  flexGrow: 1
                },
                input: {
                  borderTopLeftRadius: 0,
                  borderBottomLeftRadius: 0
                }
              }}
              data-testid="premium-connect-client-select"
            />
          </Group>
          <Box ta="right">
            {!pwdInited && (
              <AccessDeniedHoverHint id="TidbxRootPasswordUpdate">
                {({ accessible }) => (
                  <Button
                    variant="default"
                    disabled={!accessible}
                    onClick={onPwdSet}
                    data-mp-event={MixpanelEvents.TidbRootPassword.Update.EnterClicked}
                    data-mp-service-plan={servicePlan ?? Commonv1beta1ServicePlan.Premium}
                    data-mp-source="premium-connect-modal"
                    data-testid="premium-connect-set-root-password-btn"
                  >
                    Set Root Password
                  </Button>
                )}
              </AccessDeniedHoverHint>
            )}
          </Box>
        </SimpleGrid>
        {!pwdInited && (
          <Typography variant="body-lg">
            Your instance doesn't have a root password yet.{' '}
            <AccessGuard id="TidbxRootPasswordUpdate" fallback="Please ask your admin to set a root password.">
              Please set a root password at first and keep it in a safe place.
            </AccessGuard>
          </Typography>
        )}
        {caRequired && (
          <Alert>
            Download{' '}
            {isCAUrlFetching ? (
              <Box component="span" c="carbon.7" sx={{ cursor: 'not-allowed' }}>
                CA cert
              </Box>
            ) : (
              <a
                onClick={downloadCA}
                data-mp-event="Download TiDB Cloud Root CA Link Clicked"
                data-mp-service-plan={servicePlan ?? Commonv1beta1ServicePlan.Premium}
              >
                CA cert
              </a>
            )}{' '}
            for client TLS configuration at first time and replace {'<'}CA_PATH{'>'} with your local path.
          </Alert>
        )}

        {!withSubClient &&
          rootConn &&
          (isParamsBlock(rootConn.type) ? (
            <Box
              sx={(theme) => ({
                backgroundColor: theme.colors.carbon[1],
                border: `1px solid ${theme.colors.carbon[5]}`,
                borderRadius: theme.defaultRadius
              })}
            >
              <ParamsBlock networkType={networkType} vars={codeVars} />
            </Box>
          ) : (
            <CodeBlock
              language={rootConn.lang as PrismProps['language']}
              codeHighlightProps={{
                onCopy: () => codeHandlers.onSelectionCopy()
              }}
              onCopyClick={codeHandlers.onCopyBtnClick}
              sx={(theme) => ({
                '&>div:first-of-type': {
                  backgroundColor: theme.colors.carbon[1]
                }
              })}
              data-testid="premium-connect-codeblock"
            >
              {getConnCode(rootConn?.code, codeVars)}
            </CodeBlock>
          ))}
        {withSubClient && (
          <Tabs
            value={activeSubConnId}
            onChange={onSubConnIdChange}
            styles={(theme) => ({
              root: {
                backgroundColor: theme.colors.carbon[1],
                border: `1px solid ${theme.colors.carbon[5]}`,
                borderRadius: theme.defaultRadius
              },
              tabsList: {
                gap: 24,
                borderBottom: `1px solid ${theme.colors.carbon[4]}`
              },
              tabIcon: {
                '&:not(:only-child)': {
                  marginRight: 4
                }
              }
            })}
            data-testid="premium-connect-codeblock"
          >
            <Tabs.List mx="md">
              {subConns?.map((item) => (
                <Tabs.Tab key={item.id} value={item.id} leftSection={icons[item.iconType]} pt="md" mb={-1}>
                  {item.label}
                </Tabs.Tab>
              ))}
            </Tabs.List>
            {subConns?.map((item) => (
              <Tabs.Panel key={item.id} value={item.id}>
                {isParamsBlock(item.type) ? (
                  <ParamsBlock networkType={networkType} vars={codeVars} />
                ) : (
                  <CodeBlock
                    language={item.lang as PrismProps['language']}
                    codeHighlightProps={{
                      onCopy: () => codeHandlers.onSelectionCopy(item.label)
                    }}
                    onCopyClick={() => codeHandlers.onCopyBtnClick(item.label)}
                    sx={{
                      '&>div:first-of-type': {
                        backgroundColor: 'transparent',
                        borderWidth: 0
                      }
                    }}
                  >
                    {getConnCode(item.code, codeVars)}
                  </CodeBlock>
                )}
              </Tabs.Panel>
            ))}
          </Tabs>
        )}
        <ConnectionClientFooter docLink={currentConn?.doc} client={rootClient} />
      </Stack>
    )
  }
)
