import {
  Alert,
  Anchor,
  Box,
  Button,
  Code,
  Divider,
  Group,
  List,
  Loader,
  Paper,
  PasswordInput,
  Select,
  SimpleGrid,
  Stack,
  Tabs,
  Typography
} from '@tidbcloud/uikit'
import { IconLinkExternal01, IconMagicWand02 } from '@tidbcloud/uikit/icons'
import { observer } from 'mobx-react'
import { useState } from 'react'

import { CopyActionIcon } from 'dbaas/components/Copy/CopyActionIcon'
import { AccessGuard, useAccessCheck } from 'dbaas/contexts/access-control'
import { FirewallRulesAlert } from 'dbaas/screens/ClusterV2/features/Connection/serverless/FirewallRules'

import { McpGuideList } from './guide/McpGuideList'
import {
  DEFAULT_MCP_CLIENT,
  getCurrentBranchData,
  getMcpEnvData,
  MAIN_BRANCH_NAME,
  useBranchList,
  useCodeCopy,
  useDatabaseList,
  useGetCluster,
  useTrackEnterRootPwd,
  useUpdateRootPwd
} from './helpers'
import { PublicEndpointAlert } from './PublicEndpointAlert'
import { ContentType } from './types'

interface McpConfigModalBodyProps {
  clusterId: string
  contentType: ContentType
  onToggleContent: (type?: ContentType) => void
}

export const McpConfigModalBody = observer(({ contentType, onToggleContent, clusterId }: McpConfigModalBodyProps) => {
  const { data: clusterData, ...clusterQuery } = useGetCluster(clusterId)
  const initializing = clusterQuery.isLoading
  const publicEndpointDisabled = clusterQuery.isSuccess && clusterData?.endpoints?.public?.disabled

  /**
   * branch
   */
  const [branch, setBranch] = useState(MAIN_BRANCH_NAME)
  const { options: branchOptions, list: branchList, queryResult: branchQuery } = useBranchList({ clusterId })
  const isMainBranch = branch === MAIN_BRANCH_NAME
  const currentBranch = getCurrentBranchData({
    cluster: clusterData,
    branchList,
    branchId: branch
  })

  /**
   * database
   */
  const dbListAccessible = useAccessCheck('TidbxRead', { tidbId: clusterId })
  const [db, setDB] = useState('')
  const { dbOptions, queryResult: dbQuery } = useDatabaseList(
    { clusterId, branchId: branch },
    {
      onSuccess: (data) => setDB(data?.[0])
    }
  )
  const onDBChange = (db: string) => setDB(db)
  const onBranchChange = (branch: string) => {
    setBranch(branch)
    // Reset db if branch changed
    setDB('')
  }

  /**
   * Root user password
   */
  const {
    stage: pwdStage,
    updating: pwdUpdating,
    rootPwd,
    setRootPwd,
    update: updateRootPwd,
    cancelUpdate: cancelRootPwdUpdate
  } = useUpdateRootPwd({
    initializing: initializing || branchQuery.isLoading,
    clusterId,
    branchId: branch,
    rootPwdSet: currentBranch.rootPwdSet,
    onFinish: contentType === ContentType.McpConfig ? undefined : () => onToggleContent(ContentType.McpConfig),
    onCancel: contentType === ContentType.McpConfig ? undefined : () => onToggleContent(ContentType.McpConfig)
  })
  const trackEnterRootPwd = useTrackEnterRootPwd(branch)

  /**
   * mcp environment data
   */
  const envData = getMcpEnvData({
    publicEndpoint: currentBranch.publicEndpoint,
    userToken: currentBranch.userToken,
    pwd: rootPwd,
    db
  })

  const [mcpClient, setMcpClient] = useState(DEFAULT_MCP_CLIENT)
  const codeHandlers = useCodeCopy({
    branchId: branch,
    mcpClientId: mcpClient,
    mpEvents: {
      freeCopy: 'MCP Server config string copied',
      btnCopy: 'MCP Server config copy button clicked'
    }
  })

  if (contentType === ContentType.Reset) {
    return (
      <Stack p="xl">
        <Typography variant="body-lg">
          Resetting the password cannot be undone. The previous password will be permanently invalidated. Are you sure
          you want to reset your password?
        </Typography>
        {pwdStage.resetError && <Alert color="red">Failed to reset password. Please try again later.</Alert>}
        <Group justify="flex-end">
          <Button
            variant="default"
            onClick={cancelRootPwdUpdate}
            data-mp-event="Cancel resetting password Button Clicked"
            data-mp-location="Starter AI tools modal"
            data-mp-is-main-branch={isMainBranch}
          >
            Keep the old one
          </Button>
          <Button
            color="red"
            variant="light"
            loading={pwdUpdating}
            onClick={updateRootPwd}
            data-mp-event="Confirm resetting password Button Clicked"
            data-mp-location="Starter AI tools modal"
            data-mp-is-main-branch={isMainBranch}
          >
            Sure, reset it
          </Button>
        </Group>
      </Stack>
    )
  }

  return (
    <>
      {(clusterQuery.isError || branchQuery.isError || dbQuery.isError) && (
        <Box p="xl" pb={0}>
          <Alert color="red">
            <Group gap={0}>
              Oops, something went wrong when getting configurations.
              <Button
                variant="white"
                color="peacock"
                onClick={() => {
                  if (clusterQuery.isError) {
                    return clusterQuery.refetch()
                  } else if (branchQuery.isError) {
                    return branchQuery.refetch()
                  } else if (dbQuery.isError) {
                    return dbQuery.refetch()
                  }
                }}
                loading={clusterQuery.isRefetching || branchQuery.isRefetching || dbQuery.isRefetching}
                bg="transparent"
                fw={600}
                h={20}
                px={4}
                data-mp-event="Retry getting cluster/branch/database configurations button in AI tools modal clicked"
                data-mp-location="Starter AI tools modal"
                data-mp-is-main-branch={isMainBranch}
              >
                Retry
              </Button>
            </Group>
          </Alert>
        </Box>
      )}
      {clusterQuery.isSuccess && branchQuery.isSuccess && dbQuery.isSuccess && (
        <>
          {publicEndpointDisabled && <PublicEndpointAlert clusterId={clusterId} alertProps={{ mx: 'xl', mt: 'xl' }} />}
          {!publicEndpointDisabled && (
            <FirewallRulesAlert clusterId={clusterId} allowConnectHidden={true} alertProps={{ mx: 'xl', mt: 'xl' }} />
          )}
        </>
      )}
      <Stack p="xl">
        <Typography variant="title-lg">1. Select the environment</Typography>
        <SimpleGrid cols={2}>
          <Select
            label="Branch"
            value={branch}
            data={branchOptions}
            allowDeselect={false}
            placeholder="Select a branch"
            disabled={initializing || branchQuery.isLoading}
            rightSection={initializing || branchQuery.isLoading ? <Loader size="xs" /> : undefined}
            onChange={onBranchChange}
          />
          <Select
            label="Database"
            value={db}
            data={dbOptions}
            allowDeselect={false}
            placeholder="Select a database"
            disabled={initializing || branchQuery.isFetching || dbQuery.isFetching || !dbListAccessible}
            rightSection={
              initializing || branchQuery.isFetching || dbQuery.isFetching ? <Loader size="xs" /> : undefined
            }
            onChange={onDBChange}
          />
        </SimpleGrid>
      </Stack>
      <Divider color="carbon.3" mx="xl" />
      <Stack p="xl">
        <Typography variant="title-lg">2. Prerequisites</Typography>
        <List spacing={4}>
          <List.Item>
            <Typography variant="body-lg">
              <Anchor
                href="https://www.python.org/downloads/"
                target="_blank"
                rel="noopener noreferrer"
                sx={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}
              >
                Python 3.11 or higher <IconLinkExternal01 />
              </Anchor>{' '}
              installed;
            </Typography>
          </List.Item>
          <List.Item>
            <Typography variant="body-lg">
              <Anchor
                href="https://docs.astral.sh/uv/getting-started/installation/"
                target="_blank"
                rel="noopener noreferrer"
                sx={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}
              >
                UV <IconLinkExternal01 />
              </Anchor>{' '}
              installed;
            </Typography>
          </List.Item>
          <List.Item>
            <Typography variant="body-lg" component="div">
              Root user password for this instance.{' '}
              {pwdStage.resetUnset && (
                <AccessGuard id="TidbxRootPasswordUpdate" scopeProps={{ tidbId: clusterId }}>
                  Forget it?{' '}
                  <Anchor
                    component="button"
                    underline="never"
                    onClick={() => onToggleContent(ContentType.Reset)}
                    data-mp-event="Reset password Button Clicked"
                    data-mp-location="Starter AI tools modal"
                    data-mp-is-main-branch={isMainBranch}
                  >
                    Reset password
                  </Anchor>
                </AccessGuard>
              )}
            </Typography>
          </List.Item>
        </List>
        {pwdStage.newUnset && (
          <Alert color="yellow" px="sm" py="xs">
            <Group justify="space-between">
              <Typography variant="body-lg">You haven't set a password yet. Please generate one first.</Typography>
              <AccessGuard id="TidbxRootPasswordUpdate" scopeProps={{ tidbId: clusterId }}>
                <Button
                  variant="default"
                  size="sm"
                  loading={pwdUpdating}
                  onClick={updateRootPwd}
                  data-mp-event="Create password Button Clicked"
                  data-mp-location="Starter AI tools modal"
                  data-mp-is-main-branch={isMainBranch}
                >
                  Generate Password
                </Button>
              </AccessGuard>
            </Group>
          </Alert>
        )}
        {pwdStage.newError && (
          <Alert color="red" px="sm" py="xs">
            <Group justify="space-between">
              <Typography variant="body-lg">Failed to generate the password. Please try again later.</Typography>
              <AccessGuard id="TidbxRootPasswordUpdate" scopeProps={{ tidbId: clusterId }}>
                <Button
                  variant="default"
                  size="sm"
                  loading={pwdUpdating}
                  onClick={updateRootPwd}
                  data-mp-event="Create password Button Clicked"
                  data-mp-location="Starter AI tools modal"
                  data-mp-is-main-branch={isMainBranch}
                >
                  Retry
                </Button>
              </AccessGuard>
            </Group>
          </Alert>
        )}
        {pwdStage.newSuccess && (
          <Alert color="green" px="sm" py="xs">
            <Box>
              Generated password:{' '}
              <Group gap={0} display="inline-flex">
                <Code bg="transparent" c="carbon.9">
                  {rootPwd}
                </Code>
                <CopyActionIcon
                  text={rootPwd}
                  actionIconProps={{
                    variant: 'transparent',
                    size: 'sm',
                    c: 'carbon.8'
                  }}
                  iconProps={{ size: 14 }}
                  data-mp-event="Copy password Button Clicked"
                  data-mp-location="Starter AI tools modal"
                  data-mp-is-main-branch={isMainBranch}
                />
              </Group>
            </Box>
            <Box>For security reasons, this password won't be shown again. Please store it safely.</Box>
          </Alert>
        )}
        {pwdStage.resetSuccess && (
          <Alert color="green" px="sm" py="xs">
            <Box>
              Password reset successfully! Password:{' '}
              <Group gap={0} display="inline-flex">
                <Code bg="transparent" c="carbon.9">
                  {rootPwd}
                </Code>
                <CopyActionIcon
                  text={rootPwd}
                  actionIconProps={{ variant: 'transparent', size: 'sm', c: 'carbon.8' }}
                  iconProps={{ size: 14 }}
                  data-mp-event="Copy password Button Clicked"
                  data-mp-location="Starter AI tools modal"
                  data-mp-is-main-branch={isMainBranch}
                />
              </Group>
            </Box>
            <Box>Password cannot be displayed next time for safety. Please keep it in a safe place.</Box>
          </Alert>
        )}
      </Stack>
      <Divider color="carbon.3" mx="xl" />
      <Stack p="xl">
        <Typography variant="title-lg">3. Connect to MCP clients</Typography>
        {pwdStage.resetUnset && (
          <Paper bg="carbon.2" p="md">
            <Stack>
              <Group gap={8}>
                <IconMagicWand02 c="purple" />
                <Typography variant="label-lg">Enter the password for easy setup</Typography>
              </Group>
              <Typography variant="body-lg">
                This configuration requires the root user password in plain text. Enter it below to enable one-click
                installation and auto-populate the configuration. Your password will not be saved or sent to TiDB Cloud.
              </Typography>
              <PasswordInput
                placeholder="Enter the root user password"
                value={rootPwd}
                onChange={(e) => {
                  setRootPwd(e.target.value)
                  trackEnterRootPwd()
                }}
                data-autofocus
              />
            </Stack>
          </Paper>
        )}
        <Tabs value={mcpClient} onChange={(value) => setMcpClient(value || DEFAULT_MCP_CLIENT)}>
          <Tabs.List mb="md">
            {McpGuideList?.map((item) => (
              <Tabs.Tab key={item.id} value={item.id} leftSection={item.icon}>
                {item.name}
              </Tabs.Tab>
            ))}
          </Tabs.List>
          {McpGuideList?.map(({ guide: Guide, ...item }) => (
            <Tabs.Panel key={item.id} value={item.id}>
              <Guide
                {...envData}
                {...codeHandlers}
                oneClickProps={{
                  'data-mp-event': 'One-click install MCP client button clicked',
                  'data-mp-mcp-client': item.name,
                  'data-mp-location': 'Starter AI tools modal',
                  'data-mp-is-main-branch': isMainBranch
                }}
              />
            </Tabs.Panel>
          ))}
        </Tabs>
      </Stack>
    </>
  )
})
