import { MediaSet, MediaSetServiceClientImpl } from './generated/media_set';
import { newRPC } from './App';
import { useEffect, useRef } from 'react';

interface Props {
  mediaSet: MediaSet;
  position: number;
  duration: number;
  height: number;
  video: HTMLVideoElement;
}

export const VideoPreview: React.FC<Props> = ({
  mediaSet,
  position,
  duration,
  height,
  video,
}: Props) => {
  const videoCanvasRef = useRef<HTMLCanvasElement>(null);

  // effects

  // load thumbnail, to display when the component is loaded for the first
  // time. This is needed because of browser autoplay limitations.
  useEffect(() => {
    (async function () {
      if (mediaSet == null) {
        return;
      }

      const canvas = videoCanvasRef.current;
      if (canvas == null) {
        console.error('no canvas ref available');
        return;
      }

      const ctx = canvas.getContext('2d');
      if (ctx == null) {
        console.error('no 2d context available');
        return;
      }

      // Set aspect ratio.
      canvas.width = canvas.height * (canvas.clientWidth / canvas.clientHeight);

      console.log('getting video thumbnail...');
      const rpc = newRPC();
      const service = new MediaSetServiceClientImpl(rpc);

      const thumbnail = await service.GetVideoThumbnail({ id: mediaSet.id });

      console.log('got thumbnail', thumbnail);

      const url = URL.createObjectURL(
        new Blob([thumbnail.image], { type: 'image/jpeg' })
      );
      const img = new Image(thumbnail.width, thumbnail.height);

      img.src = url;
      console.log('img', img);
      img.onerror = console.error;
      img.onload = () => {
        ctx.drawImage(img, 0, 0, 177, 100);
      };

      console.log('set src to', url);
    })();
  }, [mediaSet]);

  // render canvas
  useEffect(() => {
    // TODO: not sure if requestAnimationFrame is recommended here.
    requestAnimationFrame(() => {
      const canvas = videoCanvasRef.current;
      if (canvas == null) {
        console.error('no canvas ref available');
        return;
      }

      const ctx = canvas.getContext('2d');
      if (ctx == null) {
        console.error('no 2d context available');
        return;
      }

      // Set aspect ratio.
      canvas.width = canvas.height * (canvas.clientWidth / canvas.clientHeight);

      const durSecs = duration / 1000;
      const ratio = position / durSecs;
      const x = (canvas.width - 177) * ratio;

      ctx.clearRect(0, 0, x, canvas.height);
      ctx.clearRect(x + 177, 0, canvas.width - 177 - x, canvas.height);

      ctx.drawImage(video, x, 0, 177, 100);
    });
  }, [position]);

  // render component

  const containerStyles = {
    height: height + 'px',
    position: 'relative',
    flexGrow: 0,
  } as React.CSSProperties;

  const canvasStyles = {
    position: 'absolute',
    width: '100%',
    height: '100%',
    display: 'block',
    zIndex: 1,
  } as React.CSSProperties;

  return (
    <>
      <div style={containerStyles}>
        <canvas
          width="500"
          height="100"
          ref={videoCanvasRef}
          style={canvasStyles}
        ></canvas>
        <canvas style={canvasStyles}></canvas>
      </div>
    </>
  );
};
