import * as React from "react";
import Box, { BoxProps } from "@mui/material/Box";
import {
  Light as SyntaxHighlighter,
  SyntaxHighlighterProps,
} from "react-syntax-highlighter";
import js from "react-syntax-highlighter/dist/cjs/languages/hljs/javascript";
import sql from "react-syntax-highlighter/dist/cjs/languages/hljs/sql";
import yaml from "react-syntax-highlighter/dist/cjs/languages/hljs/yaml";
import json from "react-syntax-highlighter/dist/cjs/languages/hljs/json";
// @ts-ignore /* tslint:disable-next-line */
import { stackoverflowLight } from "react-syntax-highlighter/dist/cjs/styles/hljs";

import CopyIconButton, {
  CopySquareIconButton,
} from "@/components/Button/CopyButton";

SyntaxHighlighter.registerLanguage("javascript", js);
SyntaxHighlighter.registerLanguage("sql", sql);
SyntaxHighlighter.registerLanguage("yaml", yaml);
SyntaxHighlighter.registerLanguage("json", json);

export interface CommonCodeBlockProps extends Partial<SyntaxHighlighterProps> {
  text: string;
  language: "javascript" | "sql" | "yaml" | "json";
}

export interface CodeBlockProps extends CommonCodeBlockProps {
  transparentBackground?: boolean;
  disableCopy?: boolean;
  boxSxProps?: BoxProps["sx"];
  CustomContent?: (props: { show?: boolean }) => JSX.Element;
}

export default function CodeBlock(props: CodeBlockProps) {
  const {
    text,
    language,
    transparentBackground,
    disableCopy,
    boxSxProps,
    CustomContent,
    ...others
  } = props;

  const [showButton, setshowButton] = React.useState(false);

  const handleMouseEnter = () => {
    setshowButton(true);
  };

  const handleMouseLeave = () => {
    setshowButton(false);
  };

  return (
    <Box
      className="code-block"
      sx={{
        borderRadius: 1,
        p: (theme) => theme.spacing(1),
        fontSize: 14,
        position: "relative",
        backgroundColor: transparentBackground ? "transparent" : "#F6F8FC",
        minHeight: 100,
        ...boxSxProps,
      }}
      onMouseEnter={handleMouseEnter}
      onMouseLeave={handleMouseLeave}
    >
      <SyntaxHighlighter
        language={language}
        style={stackoverflowLight}
        customStyle={{
          backgroundColor: "transparent",
        }}
        {...others}
      >
        {text}
      </SyntaxHighlighter>
      {!disableCopy && (
        <CopySquareIconButton
          content={text}
          disableRipple
          sx={{
            position: "absolute",
            top: (theme) => theme.spacing(1.6),
            right: (theme) => theme.spacing(1.6),
            opacity: showButton ? 1 : 0,
            transition: (theme) => theme.transitions.create("opacity"),
          }}
        />
      )}
      {CustomContent && <CustomContent show={showButton} />}
    </Box>
  );
}

export function CodeSnippet(props: CommonCodeBlockProps) {
  const { text, language, ...others } = props;

  return (
    <SyntaxHighlighter
      language={language}
      style={stackoverflowLight}
      customStyle={{
        fontSize: 14,
        padding: "0px",
      }}
      {...others}
    >
      {text}
    </SyntaxHighlighter>
  );
}

export interface UnifiedCodeDiffHighlightProps
  extends Partial<SyntaxHighlighterProps> {
  text: string;
  language: "javascript" | "sql" | "yaml" | "json";
  ADDED?: number[];
  REMOVED?: number[];
}

export function UnifiedCodeDiffHighlight(props: UnifiedCodeDiffHighlightProps) {
  const { text, language, ADDED = [], REMOVED = [], ...others } = props;

  return (
    <>
      <SyntaxHighlighter
        language={language}
        style={stackoverflowLight}
        customStyle={{
          backgroundColor: "transparent",
          fontSize: "12px",
          padding: "0px",
          ...others.customStyle,
        }}
        lineProps={(lineNumber) => {
          let style: any = { display: "block" };
          if (ADDED.includes(lineNumber)) {
            style.backgroundColor = "#F0FFF0";
          } else if (REMOVED.includes(lineNumber)) {
            style.backgroundColor = "#ffecec";
          }
          return { style };
        }}
        codeTagProps={{
          style: {
            lineHeight: "inherit",
            fontSize: "inherit",
            display: "table",
          },
        }}
        {...others}
      >
        {text}
      </SyntaxHighlighter>
    </>
  );
}
