import { useState, useEffect, useCallback } from 'react';
import { MediaSet } from './generated/media_set';
import { Frames, VideoPosition } from './App';
import { WaveformCanvas } from './WaveformCanvas';
import { HudCanvas, EmptySelectionAction } from './HudCanvas';
import { Observable } from 'rxjs';

export interface Selection {
  start: number;
  end: number;
}

interface Props {
  peaks: Observable<number[]>;
  mediaSet: MediaSet;
  height: number;
  offsetPixels: number;
  position: VideoPosition;
  viewport: Frames;
  onSelectionChange: (selection: Selection) => void;
}

export const CanvasLogicalWidth = 2_000;
export const CanvasLogicalHeight = 500;

export const Overview: React.FC<Props> = ({
  peaks,
  mediaSet,
  height,
  offsetPixels,
  position,
  viewport,
  onSelectionChange,
}: Props) => {
  const [selectedPixels, setSelectedPixels] = useState({ start: 0, end: 0 });
  const [positionPixels, setPositionPixels] = useState(0);

  // side effects

  // convert viewport from frames to canvas pixels.
  useEffect(() => {
    setSelectedPixels({
      start: Math.round(
        (viewport.start / mediaSet.audioFrames) * CanvasLogicalWidth
      ),
      end: Math.round(
        (viewport.end / mediaSet.audioFrames) * CanvasLogicalWidth
      ),
    });
  }, [viewport, mediaSet]);

  // convert position from frames to canvas pixels:
  useEffect(() => {
    const ratio =
      position.currentTime / (mediaSet.audioFrames / mediaSet.audioSampleRate);
    setPositionPixels(Math.round(ratio * CanvasLogicalWidth));
    frames;
  }, [mediaSet, position]);

  // handlers

  // convert selection change from canvas pixels to frames, and trigger callback.
  const handleSelectionChange = useCallback(
    ({ start, end }: Selection) => {
      onSelectionChange({
        start: Math.round((start / CanvasLogicalWidth) * mediaSet.audioFrames),
        end: Math.round((end / CanvasLogicalWidth) * mediaSet.audioFrames),
      });
    },
    [mediaSet]
  );

  // render component

  const containerStyles = {
    flexGrow: 0,
    position: 'relative',
    margin: `0 ${offsetPixels}px`,
    height: `${height}px`,
  } as React.CSSProperties;

  const hudStyles = {
    borderLineWidth: 4,
    borderStrokeStyle: 'red',
    positionLineWidth: 4,
    positionStrokeStyle: 'red',
  };

  return (
    <>
      <div style={containerStyles}>
        <WaveformCanvas
          peaks={peaks}
          channels={mediaSet.audioChannels}
          width={CanvasLogicalWidth}
          height={CanvasLogicalHeight}
          strokeStyle="black"
          fillStyle="#003300"
          zIndex={1}
          alpha={1}
        ></WaveformCanvas>
        <HudCanvas
          width={CanvasLogicalWidth}
          height={CanvasLogicalHeight}
          zIndex={1}
          emptySelectionAction={EmptySelectionAction.SelectPrevious}
          styles={hudStyles}
          position={positionPixels}
          selection={selectedPixels}
          onSelectionChange={handleSelectionChange}
        />
      </div>
    </>
  );
};
