import { Anchor, Box, Card, CardProps, Code, PrismProps, Typography, useComputedColorScheme } from '@tidbcloud/uikit'
import { CodeBlock } from '@tidbcloud/uikit/biz'
import { useHover } from '@tidbcloud/uikit/hooks'
import React from 'react'
import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'

// import { FeedbackActions } from '../Feedback'

import { GeneratingTips } from './GeneratingTips'
import { Message, useChatStream } from './useMessages'

export const AssistantMessage: React.FC<
  React.PropsWithChildren<{
    msg: Message
    messages: Message[]
    generating: boolean
    error: any
    alwaysShowFeedback?: boolean
    onStreamFinished: (m: string) => void
    onStreamChange: (m: string) => void
    onStreamError: (e: any) => void
    onLike: () => void
    onDislike: () => void
  }>
> = ({
  msg,
  messages,
  generating,
  error,
  // alwaysShowFeedback,
  onStreamFinished,
  onStreamChange,
  onStreamError
  // onLike,
  // onDislike
}) => {
  const { messageValue, isGenerating } = useChatStream({
    msg,
    messages,
    onChange: onStreamChange,
    onFinished: onStreamFinished,
    onError: onStreamError
  })
  const { ref } = useHover()

  return (
    (!!messageValue || !!error) && (
      <Card
        maw="95%"
        px="md"
        py="xs"
        fz="sm"
        bg="carbon.3"
        c="carbon.8"
        shadow="none"
        sx={{
          position: 'relative',
          flexShrink: 0,
          alignSelf: 'start',
          overflow: 'visible',
          wordBreak: 'break-word'
        }}
        withBorder={false}
        ref={ref}
      >
        {!error ? (
          <>
            {/* <FeedbackActions
            visible={(hovered || !!alwaysShowFeedback) && !isGenerating}
            onLike={onLike}
            onDislike={onDislike}
          /> */}
            <CustomMarkdown content={messageValue} />
            {(isGenerating || generating) && <GeneratingTips />}
          </>
        ) : (
          <Typography>Sorry, the OpenAI server has reached the rate limit for now. Please try again later.</Typography>
        )}
      </Card>
    )
  )
}

export const UserMessage: React.FC<React.PropsWithChildren<{ msg: Message }>> = ({ msg }) => {
  return (
    <Card
      maw="95%"
      px="md"
      py="xs"
      fz="sm"
      bg="peacock.2"
      c="carbon.8"
      shadow="none"
      sx={{ flexShrink: 0, alignSelf: 'end', whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}
      withBorder={false}
    >
      {msg.displayed.content}
    </Card>
  )
}

const CustomMarkdown: React.FC<
  React.PropsWithChildren<{
    content: string
  }>
> = ({ content }) => {
  const colorScheme = useComputedColorScheme()

  return (
    <Box
      sx={{
        '& p:first-child': {
          marginTop: 0
        },
        '& p:last-child': {
          marginBottom: 0
        }
      }}
    >
      <ReactMarkdown
        children={content}
        remarkPlugins={[remarkGfm]}
        components={{
          a({ children, ...props }) {
            return (
              <Anchor {...props} target="_blank" sx={{ wordBreak: 'break-all' }}>
                {children}
              </Anchor>
            )
          },
          pre({ children }) {
            return <>{children}</>
          },
          code({ node, inline, children, lang, ...props }) {
            return inline ? (
              <Code
                {...props}
                sx={(theme) => ({ backgroundColor: colorScheme === 'dark' ? theme.black : theme.white })}
              >
                {children}
              </Code>
            ) : (
              <CodeBlock mb="md" language={lang as PrismProps['language']}>
                {children.map((c) => c as string).join('\n')}
              </CodeBlock>
            )
          }
        }}
      />
    </Box>
  )
}

export const TipsMessage: React.FC<React.PropsWithChildren<CardProps>> = ({ children, ...props }) => {
  return (
    <Card
      maw="95%"
      px="md"
      py="xs"
      fz="sm"
      bg="carbon.3"
      c="carbon.8"
      shadow="none"
      sx={{ flexShrink: 0, alignSelf: 'start' }}
      withBorder={false}
      {...props}
    >
      {children}
    </Card>
  )
}

export const ActionMessage: React.FC<React.PropsWithChildren<{ onClick?: () => void }>> = ({ children, onClick }) => {
  return (
    <Card
      maw="95%"
      px="xs"
      py={2}
      fz={12}
      c="sky.7"
      shadow="none"
      sx={(theme) => ({
        flexShrink: 0,
        alignSelf: 'end',
        cursor: 'pointer',
        borderColor: theme.colors.sky[5],
        ':hover': {
          color: theme.colors.sky[7],
          borderColor: theme.colors.sky[7]
        }
      })}
      onClick={onClick}
    >
      {children}
    </Card>
  )
}
