import { Box, Button, Group, Paper, Stack, Typography } from '@tidbcloud/uikit'
import { CodeBlock } from '@tidbcloud/uikit/biz'
import { useMemoizedFn } from 'ahooks'
import { useRef, useState } from 'react'

import claimFail from 'media/claim_fail.svg'
import claimLoading from 'media/claim_loading.svg'
import claimSuccess from 'media/claim_success.svg'

export type ClaimProvisioningStage = 'claiming' | 'polling' | 'resetting' | 'failed' | 'done'

interface ClaimProvisioningProps {
  stage: ClaimProvisioningStage
  errorMessage?: string
  connectionString?: string
  onOpenConsole?: () => void
}

const stageConfig: Record<ClaimProvisioningStage, { image: string; title: string; description: string }> = {
  claiming: {
    image: claimLoading,
    title: 'Setting up your Starter instance...',
    description: "We're saving your database to TiDB Cloud. This usually takes less than a minute."
  },
  polling: {
    image: claimLoading,
    title: 'Setting up your Starter instance...',
    description: "We're saving your database to TiDB Cloud. This usually takes less than a minute."
  },
  resetting: {
    image: claimLoading,
    title: 'Finishing setup...',
    description: 'Preparing your new connection details.'
  },
  failed: {
    image: claimFail,
    title: 'Failed to claim Starter instance',
    description: 'Please try again, or contact support if the issue persists.'
  },
  done: {
    image: claimSuccess,
    title: 'Your database is now ready in your TiDB Cloud account!',
    description: 'Your database has been saved as a Starter instance. Use the connection string below to connect.'
  }
}

const buildAgentInstruction = (connectionString: string) =>
  `The TiDB Cloud Zero database has been claimed and saved as a permanent TiDB Cloud Starter instance. ` +
  `Please update your database connection to use the new connection string:\n\n${connectionString}\n\n` +
  `Verify the connection works, then update any configuration or environment variables accordingly.`

export function ClaimProvisioning({ stage, errorMessage, connectionString, onOpenConsole }: ClaimProvisioningProps) {
  const config = stageConfig[stage]
  const description = stage === 'failed' ? errorMessage || config.description : config.description

  const [copied, setCopied] = useState(false)
  const copiedTimerRef = useRef<ReturnType<typeof setTimeout>>()

  const handleCopyInstruction = useMemoizedFn(() => {
    if (!connectionString) return
    void navigator.clipboard.writeText(buildAgentInstruction(connectionString)).then(() => {
      setCopied(true)
      clearTimeout(copiedTimerRef.current)
      copiedTimerRef.current = setTimeout(() => setCopied(false), 2000)
    })
  })

  return (
    <Paper
      w="100%"
      radius="md"
      bg="white"
      shadow="sm"
      data-testid="claim-provisioning-panel"
      sx={{
        maxWidth: 960,
        maxHeight: 574,
        minHeight: 'min(640px, 82vh)',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center'
      }}
    >
      <Stack align="center" justify="center" gap="md" maw={960}>
        <Box component="img" src={config.image} alt={stage} w={180} data-testid={`claim-provisioning-${stage}-img`} />

        <Stack gap={4}>
          <Typography fw={700} fz={18} lh={1.2} c="carbon.8" ta="center">
            {config.title}
          </Typography>
          <Typography variant="body-lg" c="carbon.7" fz={14} lh={1.5} ta="center" maw={900}>
            {description}
          </Typography>
        </Stack>
        {stage === 'done' && !!connectionString && (
          <>
            <Box data-testid="claim-provisioning-connection-box">
              <CodeBlock>{connectionString}</CodeBlock>
            </Box>
            <Group gap="sm">
              <Button
                variant="default"
                onClick={handleCopyInstruction}
                miw={230}
                data-testid="claim-provisioning-copy-agent-instruction-btn"
              >
                {copied ? 'Copied!' : 'Copy Instruction for Agent'}
              </Button>
              <Button
                onClick={onOpenConsole}
                disabled={!onOpenConsole}
                data-testid="claim-provisioning-open-console-btn"
              >
                Open in TiDB Cloud Console
              </Button>
            </Group>
          </>
        )}
      </Stack>
    </Paper>
  )
}
