import { useRef, useState, type ReactNode } from "react";
import { useTranslation } from "react-i18next";
import { Copy, CopyCheck } from "lucide-react";
import copy from "copy-to-clipboard";
import { Button } from "@/components/Internal/Button";
import { capitalize, get } from "radash";

import "./highlight.css";
import "./style.css";

const langAlias = {
  ino: "Arduino",
  sh: "Bash",
  zsh: "Base",
  h: "C",
  cpp: "C++",
  cc: "C++",
  "h++": "C++",
  hpp: "C++",
  hh: "C++",
  hxx: "C++",
  cxx: "C++",
  csharp: "C#",
  cs: "C#",
  css: "CSS",
  patch: "Diff",
  golang: "Go",
  graphql: "GraphQL",
  gql: "GraphQL",
  ini: "INI",
  toml: "TOML",
  jsp: "Java",
  javascript: "JavaScript",
  js: "JavaScript",
  jsx: "JavaScript",
  mjs: "JavaScript",
  cjs: "JavaScript",
  json: "JSON",
  jsonc: "JSON",
  kt: "Kotlin",
  kts: "Kotlin",
  pluto: "Lua",
  mk: "Makefile",
  mak: "Makefile",
  make: "Makefile",
  md: "Markdown",
  mkdown: "Markdown",
  mkd: "Markdown",
  objectivec: "Objective-C",
  mm: "Objective-C",
  objc: "Objective-C",
  "obj-c": "Objective-C",
  "obj-c++": "Objective-C",
  "objective-c++": "Objective-C",
  pl: "Perl",
  pm: "Perl",
  plaintext: "Plain text",
  text: "Plain text",
  txt: "Plain text",
  py: "Python",
  gyp: "Python",
  ipython: "Python",
  rb: "Ruby",
  gemspec: "Ruby",
  podspec: "Ruby",
  thor: "Ruby",
  irb: "Ruby",
  rs: "Rust",
  scss: "SCSS",
  shell: "Shell Session",
  console: "Shell Session",
  shellsession: "Shell Session",
  sql: "SQL",
  typescript: "TypeScript",
  ts: "TypeScript",
  tsx: "TypeScript",
  mts: "TypeScript",
  cts: "TypeScript",
  vbnet: "Visual Basic .NET",
  vb: "Visual Basic .NET",
  wasm: "WebAssembly",
  xml: "XML",
  html: "HTML",
  xhtml: "XML",
  rss: "XML",
  atom: "XML",
  xjb: "XML",
  xsd: "XML",
  xsl: "XML",
  plist: "XML",
  wsf: "XML",
  svg: "XML",
  yaml: "YAML",
  yml: "YAML",
} as const;

type Props = {
  children: ReactNode;
  lang: string;
};

function getLangAlias(lang: string): string {
  return get(langAlias, lang, capitalize(lang)) || "";
}

function Code({ children, lang }: Props) {
  const { t } = useTranslation();
  const codeWrapperRef = useRef<HTMLDivElement>(null);
  const [waitingCopy, setWaitingCopy] = useState<boolean>(false);

  const handleCopy = () => {
    if (codeWrapperRef.current) {
      setWaitingCopy(true);
      copy(codeWrapperRef.current.innerText);
      setTimeout(() => {
        setWaitingCopy(false);
      }, 1200);
    }
  };

  return (
    <>
      <div className="flex h-10 w-full items-center justify-between overflow-x-auto break-all rounded-t bg-slate-200 pl-4 pr-3 text-sm text-slate-500 dark:bg-slate-900">
        {lang ? <span title={lang}>{getLangAlias(lang)}</span> : <span></span>}
        <div>
          <Button
            className="h-6 w-6 rounded-sm p-1 dark:hover:bg-slate-900/80 print:hidden"
            variant="ghost"
            title={t("editor.copy")}
            onClick={() => handleCopy()}
          >
            {waitingCopy ? (
              <CopyCheck className="h-full w-full text-green-500" />
            ) : (
              <Copy className="h-full w-full" />
            )}
          </Button>
        </div>
      </div>
      <div
        ref={codeWrapperRef}
        className="overflow-auto rounded-b bg-slate-50 dark:bg-slate-800"
      >
        {children}
      </div>
    </>
  );
}

export default Code;
