/* ============================================================================
 * Copyright (c) Palo Alto Networks
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 * ========================================================================== */

import React, { useCallback, useState, useRef, useEffect } from "react";

import { translate } from "@docusaurus/Translate";
import clsx from "clsx";

interface CopyButtonProps {
  code: string;
  className?: string;
}

async function copyToClipboard(text: string) {
  // The clipboard API is only defined in secure contexts (HTTPS / localhost).
  // See https://developer.mozilla.org/en-US/docs/Web/API/Clipboard
  if (navigator.clipboard) {
    return navigator.clipboard.writeText(text);
  }
  // Fall back to copy-text-to-clipboard for non-secure contexts (e.g. HTTP
  // on a local network). The fallback is lazily loaded to avoid bundle
  // overhead for the common HTTPS case.
  const { default: copy } = await import("copy-text-to-clipboard");
  return copy(text);
}

export default function CopyButton({
  code,
  className,
}: CopyButtonProps): React.JSX.Element {
  const [isCopied, setIsCopied] = useState(false);
  const copyTimeout = useRef<number | undefined>(undefined);
  const handleCopyCode = useCallback(async () => {
    await copyToClipboard(code);
    setIsCopied(true);
    copyTimeout.current = window.setTimeout(() => {
      setIsCopied(false);
    }, 1000);
  }, [code]);

  useEffect(() => () => window.clearTimeout(copyTimeout.current), []);

  return (
    <button
      type="button"
      aria-label={
        isCopied
          ? translate({
              id: "theme.CodeBlock.copied",
              message: "Copied",
              description: "The copied button label on code blocks",
            })
          : translate({
              id: "theme.CodeBlock.copyButtonAriaLabel",
              message: "Copy code to clipboard",
              description: "The ARIA label for copy code blocks button",
            })
      }
      title={translate({
        id: "theme.CodeBlock.copy",
        message: "Copy",
        description: "The copy button label on code blocks",
      })}
      className={clsx(
        "clean-btn",
        className,
        "openapi-explorer__code-block-copy-btn",
        isCopied && "openapi-explorer__code-block-copy-btn--copied"
      )}
      onClick={handleCopyCode}
    >
      <span
        className="openapi-explorer__code-block-copy-btn-icons"
        aria-hidden="true"
      >
        <svg
          className="openapi-explorer__code-block-copy-btn-icon"
          viewBox="0 0 24 24"
        >
          <path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z" />
        </svg>
        <svg
          className="openapi-explorer__code-block-copy-btn-icon--success"
          viewBox="0 0 24 24"
        >
          <path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z" />
        </svg>
      </span>
    </button>
  );
}
