/**
 * Copyright (c) 2023-present Pi Dash Software, Inc. and contributors
 * SPDX-License-Identifier: AGPL-3.0-only
 * See the LICENSE file for details.
 */

import type { Editor } from "@tiptap/core";
import { useEditorState } from "@tiptap/react";
import { useEffect, useRef, useState } from "react";

type Props = {
  editor: Editor;
  nodeId: string;
};

export function ImageUploadStatus(props: Props) {
  const { editor, nodeId } = props;
  // Displayed status that will animate smoothly
  const [displayStatus, setDisplayStatus] = useState(0);
  // Animation frame ID for cleanup
  const animationFrameRef = useRef<number | null>(null);
  // subscribe to image upload status
  const uploadStatus: number | undefined = useEditorState({
    editor,
    selector: ({ editor }) => editor.storage.utility?.assetsUploadStatus?.[nodeId],
  });

  useEffect(() => {
    const animateToValue = (start: number, end: number, startTime: number) => {
      const duration = 200;

      const animation = (currentTime: number) => {
        const elapsed = currentTime - startTime;
        const progress = Math.min(elapsed / duration, 1);

        // Easing function for smooth animation
        const easeOutCubic = 1 - Math.pow(1 - progress, 3);

        // Calculate current display value
        const currentValue = Math.floor(start + (end - start) * easeOutCubic);
        setDisplayStatus(currentValue);

        // Continue animation if not complete
        if (progress < 1) {
          animationFrameRef.current = requestAnimationFrame((time) => animation(time));
        }
      };
      animationFrameRef.current = requestAnimationFrame((time) => animation(time));
    };
    animateToValue(displayStatus, uploadStatus == undefined ? 100 : uploadStatus, performance.now());

    return () => {
      if (animationFrameRef.current) {
        cancelAnimationFrame(animationFrameRef.current);
      }
    };
  }, [displayStatus, uploadStatus]);

  if (uploadStatus === undefined) return null;

  return (
    <div className="absolute top-1 right-1 z-20 w-10 rounded-sm bg-black/60 text-center text-11 font-medium">
      {displayStatus}%
    </div>
  );
}
