import React, { useState } from 'react';
import styled from 'styled-components';
import { PrismLight as SyntaxHighlighter } from 'react-syntax-highlighter';
import tsx from 'react-syntax-highlighter/dist/cjs/languages/prism/tsx';
import { oneDark } from 'react-syntax-highlighter/dist/cjs/styles/prism';
import ContentCopy from '@mui/icons-material/ContentCopy';
import Check from '@mui/icons-material/Check';
import { IconButton, Tooltip } from '@mui/material';
import { copyTextToClipboard } from '../../utils/clipboard';
import { showToast } from '../../utils/toastBus';

SyntaxHighlighter.registerLanguage('tsx', tsx);

const Wrapper = styled.div`
  position: relative;
  max-width: 100%;
`;

const CopyBtn = styled(IconButton)`
  && {
    position: absolute;
    top: 0.35rem;
    right: 0.35rem;
    z-index: 1;
    color: #fff;
    background: rgba(0, 0, 0, 0.35);
    padding: 0.25rem;

    &:hover {
      background: rgba(0, 0, 0, 0.55);
    }
  }
`;

type CustomCodeBlockProps = {
  children: string;
  className?: string;
};

const CustomCodeBlock = ({
  children,
  className,
}: CustomCodeBlockProps): JSX.Element => {
  const [copied, setCopied] = useState(false);
  const language = className?.replace('lang-', '').replace('language-', '') || undefined;
  const code = typeof children === 'string' ? children : String(children ?? '');

  const handleCopy = async () => {
    try {
      await copyTextToClipboard(code.replace(/\n$/, ''));
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    } catch {
      showToast('Could not copy code', 'error');
    }
  };

  return (
    <Wrapper>
      <Tooltip title={copied ? 'Copied' : 'Copy code'}>
        <CopyBtn aria-label="Copy code block" size="small" onClick={() => void handleCopy()}>
          {copied ? <Check fontSize="inherit" /> : <ContentCopy fontSize="inherit" />}
        </CopyBtn>
      </Tooltip>
      <SyntaxHighlighter language={language} style={oneDark}>
        {code}
      </SyntaxHighlighter>
    </Wrapper>
  );
};

export default CustomCodeBlock;
