import { useState } from "react";
import { useCopyToClipboard } from "react-use";
import classNames from "classnames";
import Highlight from "react-highlight";
import { Options } from "redaxios";
import {
  BiSolidCopy,
  BiLogoJavascript,
  BiLogoPython,
  BiCodeCurly,
} from "react-icons/bi";

import { ApiRoute } from "@/utils/type";

const LANGUAGES = [
  {
    value: "curl",
    icon: <BiCodeCurly className=" text-xl text-slate-300" />,
  },
  {
    value: "javascript",
    icon: <BiLogoJavascript className=" text-xl text-yellow-500" />,
  },
  {
    value: "python",
    icon: <BiLogoPython className=" text-xl text-blue-500" />,
  },
];

export const Snippet = ({
  endpoint,
  headers,
  parameters,
  body,
}: {
  endpoint: ApiRoute;
  parameters?: Record<string, any>;
  headers?: Record<string, any>;
  body?: Options | undefined;
}) => {
  const [_, copyToClipboard] = useCopyToClipboard();
  const [isCopied, setIsCopied] = useState<boolean>(false);

  const generateRequestFromEndpoint = (language: string) => {
    const { method, path } = endpoint;

    const needBody = ["post", "put", "patch", "delete"].includes(
      method.toLocaleLowerCase()
    );
    const fullpath = `${process.env.NEXT_PUBLIC_APP_APIURL}${path}`;

    if (language === "curl") {
      if (needBody && body) {
        return (
          `curl -X ${method.toLocaleUpperCase()} ${fullpath}` +
          "\n" +
          `  -H 'Content-Type: application/json'` +
          "\n" +
          `  -H 'Authorization: ${headers?.Authorization}'` +
          "\n" +
          `  -d '${JSON.stringify(body, null, 2)}'`
        );
      }

      if (parameters) {
        return (
          `curl -X ${method.toLocaleUpperCase()} ${fullpath}?` +
          Object.entries(parameters)
            .map(([key, value]) => `${key}=${value}`)
            .join("&")
        );
      }

      return `curl -X ${method.toLocaleUpperCase()} ${fullpath}`;
    }

    if (language === "javascript") {
      if (needBody && body) {
        return `const response = await fetch("${fullpath}", {
  method: "${method.toLocaleUpperCase()}",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "${headers?.Authorization}",
  },
  body: JSON.stringify(${JSON.stringify(body, null, 2)}),
});`;
      }
      if (parameters) {
        return `const response = await fetch("${fullpath}?${Object.entries(
          parameters
        )
          .map(([key, value]) => `${key}=${value}`)
          .join("&")}", {
  method: "${method.toLocaleUpperCase()}",
});`;
      }
    }

    if (language === "python") {
      if (needBody && body) {
        return `import requests
  response = requests.${method.toLocaleLowerCase()}(
  "${fullpath}",
  headers={
    Authorization: "${headers?.Authorization}",
  },
  json=${JSON.stringify(body, null, 2)})`;
      }
      if (parameters) {
        return `import requests
  response = requests.${method.toLocaleLowerCase()}("${fullpath}", params={
    ${Object.entries(parameters)
      .map(([key, value]) => `${key}: ${value}`)
      .join(",\n    ")}
  })`;
      }
    }

    return "";
  };

  const handleCopyToClipboard = (language: string) => {
    copyToClipboard(generateRequestFromEndpoint(language));
    setIsCopied(true);
    setTimeout(() => {
      setIsCopied(false);
    }, 2000);
  };

  return (
    <div className="mt-8 grid grid-cols-1 gap-4 w-full">
      {LANGUAGES.map((lang, key) => (
        <div key={key} className="bg-slate-950/50 rounded-xl overflow-hidden">
          <header className="bg-slate-950 flex items-center justify-start px-5 py-4 uppercase gap-2">
            {lang.icon}
            <p className="text-slate-300 text-xs font-semibold">{lang.value}</p>
          </header>
          <main className="px-6 py-6">
            <Highlight
              className={`${lang.value} text-xs font-code !bg-transparent !p-0 !whitespace-pre-wrap break-all !leading-relaxed`}
            >
              {generateRequestFromEndpoint(lang.value)}
            </Highlight>
            <div
              className="flex justify-end relative"
              onClick={() => handleCopyToClipboard(lang.value)}
            >
              <BiSolidCopy className="text-slate-500 cursor-pointer hover:text-slate-300 transition-all duration-75" />
              <div
                className={classNames(
                  "bg-indigo-500/60 text-slate-100 text-xs font-semibold absolute bottom-0 right-0 z-10 rounded-lg px-2 py-1 pointer-events-none -translate-y-full transition-all duration-200",
                  {
                    "opacity-0": !isCopied,
                  }
                )}
              >
                Copied!
              </div>
            </div>
          </main>
        </div>
      ))}
    </div>
  );
};
