import { Highlight, themes } from 'prism-react-renderer'
import { styled } from 'inlines'
import { colors } from '../../utils/colors.js'
import { IconButton } from '../IconButton/index.js'
import { radius } from '../../utils/radius.js'
import { Icon } from '../Icon/index.js'
import { Tooltip } from '../Tooltip/index.js'
import { useTheme } from '../../hooks/useTheme.js'
import { useToast } from '../Toast/index.js'

type CodeBlockProps = {
  code: string
  language: 'js' | 'jsx' | 'ts' | 'tsx' | 'bash'
  fileName?: string
  lineNumbers?: boolean
  highlightedLines?: number[]
  border?: boolean
  copy?: boolean
}

function CodeBlock({
  fileName,
  language,
  highlightedLines,
  code,
  lineNumbers = true,
  border = true,
  copy = true
}: CodeBlockProps) {
  const { theme } = useTheme()
  const toast = useToast()

  return (
    <styled.div
      data-header={fileName ? 'true' : undefined}
      style={{
        position: 'relative',
        width: '100%',
        height: '100%',
        overflowY: 'scroll',
        ...(border && {
          border: `1px solid ${colors.neutral20Adjusted}`,
          borderRadius: radius[12],
          overflow: 'hidden',
        }),
        '&[data-header] .copyButton, &:hover .copyButton': {
          opacity: '1 !important',
        },
      }}
    >
      {copy && 
        <styled.div
          className="copyButton"
          style={{
            opacity: 0,
            display: 'flex',
            position: 'absolute',
            top: fileName ? 12 : 20,
            right: fileName ? 16 : 20,
            zIndex: 2,
            '&:focus-within': {
              opacity: 1,
            },
          }}
        >
          <Tooltip value="Copy code">
            <styled.button
              style={{
                appearance: 'none',
                background: 'transparent',
                border: 'none',
                color: colors.neutral60,
                display: 'flex',
                borderRadius: radius[8],
                padding: 4,
                margin: -4,
                '&:hover': {
                  background: colors.neutral10Adjusted,
                  color: colors.neutral100,
                },
                transition: 'transform 100ms cubic-bezier(0.2,0,0,1)',
                '&:active': {
                  transform: 'scale(0.945)',
                },
                '&:focus-visible': {
                  background: colors.neutral10Adjusted,
                  color: colors.neutral100,
                  outline: `${colors.neutral20} solid 4px`,
                },
              }}
              onClick={() => {
                navigator.clipboard.writeText(code)
                toast('Code copied')
              }}
            >
              <Icon variant="copy" />
            </styled.button>
          </Tooltip>
        </styled.div>
      }
      {fileName && (
        <div
          style={{
            height: 48,
            display: 'flex',
            alignItems: 'center',
            padding: '0 16px',
            boxShadow: `0 1px 0 ${colors.neutral20Adjusted}`,
            background: colors.neutral5,
          }}
        >
          <div
            style={{
              fontSize: 13,
              fontFamily: 'Geist Mono',
              color: colors.neutral60,
            }}
          >
            {fileName}
          </div>
        </div>
      )}
      <Highlight
        theme={theme === 'light' ? themes.oneLight : themes.oneDark}
        code={code}
        language={language}
      >
        {({ tokens, getTokenProps }) => (
          <pre style={{ padding: '20px 0', overflow: 'auto' }}>
            {tokens.map((line, i) => (
              <styled.div
                key={i}
                style={{
                  padding: '0 20px',
                  position: 'relative',
                  fontSize: 13,
                  fontFamily: 'Geist Mono',
                  lineHeight: '20px',
                  counterIncrement: 'line',
                  ...(lineNumbers && {
                    '&:before': {
                      display: 'inline-block',
                      minWidth: 16,
                      textAlign: 'right',
                      marginRight: 20,
                      content: 'counter(line)',
                      color: colors.neutral60,
                    },
                  }),
                  ...(highlightedLines?.includes(i) && {
                    background: colors.neutral5,
                    '&:after': {
                      content: '""',
                      position: 'absolute',
                      left: 0,
                      top: 0,
                      bottom: 0,
                      width: 2,
                      background: colors.neutral10,
                    },
                  }),
                }}
              >
                {line.map((token, ii) => (
                  <span key={ii} {...getTokenProps({ token })} />
                ))}
              </styled.div>
            ))}
          </pre>
        )}
      </Highlight>
    </styled.div>
  )
}

export { CodeBlock }
export type { CodeBlockProps }
