import { useEffect, useState, useRef } from 'react';
import { Frames } from './App';
import { MediaSet } from './generated/media_set';
import { WaveformCanvas } from './WaveformCanvas';
import { secsToCanvasX } from './Helpers';
import { from, Observable } from 'rxjs';

interface Props {
  mediaSet: MediaSet;
  position: number;
  viewport: Frames;
  offsetPixels: number;
}

export const CanvasLogicalWidth = 2000;
export const CanvasLogicalHeight = 500;

export const Waveform: React.FC<Props> = ({
  mediaSet,
  position,
  viewport,
  offsetPixels,
}: Props) => {
  const [peaks, setPeaks] = useState<Observable<number[]>>(from([]));
  const hudCanvasRef = useRef<HTMLCanvasElement>(null);

  // effects

  // load peaks on MediaSet change
  useEffect(() => {
    (async function () {
      if (mediaSet == null) {
        return;
      }

      let endFrame = viewport.end;
      if (endFrame <= viewport.start) {
        endFrame = mediaSet.audioFrames;
      }

      // const resp = await fetch(
      //   `http://localhost:8888/api/media_sets/${mediaSet.id}/peaks?start=${viewport.start}&end=${endFrame}&bins=${CanvasLogicalWidth}`
      // );
      // const newPeaks = await resp.json();
      // setPeaks(newPeaks);
    })();
  }, [mediaSet, viewport]);

  // render HUD
  useEffect(() => {
    const canvas = hudCanvasRef.current;
    if (canvas == null) {
      return;
    }

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

    ctx.clearRect(0, 0, canvas.width, canvas.height);

    if (mediaSet == null) {
      return;
    }

    const x = secsToCanvasX(position, mediaSet.audioSampleRate, viewport);
    if (x == null) {
      return;
    }

    ctx.strokeStyle = 'red';
    ctx.beginPath();
    ctx.moveTo(x, 0);
    ctx.lineWidth = 4;
    ctx.lineTo(x, canvas.height);
    ctx.stroke();
  }, [viewport, position]);

  // render component

  const containerStyles = {
    background: 'black',
    margin: '0 ' + offsetPixels + 'px',
    flexGrow: 1,
    position: 'relative',
  } as React.CSSProperties;

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

  return (
    <>
      <div style={containerStyles}>
        <WaveformCanvas
          peaks={peaks}
          channels={mediaSet.audioChannels}
          width={CanvasLogicalWidth}
          height={CanvasLogicalHeight}
          strokeStyle="green"
          fillStyle="black"
          zIndex={0}
          alpha={1}
        ></WaveformCanvas>
        <canvas
          width={CanvasLogicalWidth}
          height={CanvasLogicalHeight}
          ref={hudCanvasRef}
          style={canvasStyles}
        ></canvas>
      </div>
    </>
  );
};
