import React, { useState, useEffect, useRef } from 'react';
import { getPitch, IPitchDetectionConfig } from '../function/getPitch';
import hark from 'hark';

interface VolumeProps {
}

const Volume: React.FC<VolumeProps> = () => {
  const [config, setConfig] = useState({
    SRATE: 48000,
    fxmin: 50,
    fxlow: 100,
    fxhigh: 400,
    fxmax: 600
  });
  const [pitch, setPitch] = useState<number | null>(null);
  const [volume, setVolume] = useState(0);
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const dataPoints = useRef<{ x: number; y: number | null }[]>([]);

  useEffect(() => {
    let cleanup: () => void;
    (async () => {
      cleanup = await getPitch(config, setPitch);
    })();

    return () => {
      if (cleanup) {
        cleanup();
      }
    };
  }, []);

  useEffect(() => {
    navigator.mediaDevices.getUserMedia({ audio: true, video: false })
      .then(stream => {
        const harkInstance = hark(stream, {});

        harkInstance.on('volume_change', (volume, threshold) => {
          setVolume(volume);
        });

        return () => harkInstance.stop();
      })
      .catch(error => {
        console.error('Error accessing the microphone', error);
      });
  }, []);
  useEffect(() => {
    if (canvasRef.current) {
      const ctx = canvasRef.current.getContext('2d');
      if (ctx) {
        ctx.clearRect(0, 0, canvasRef.current.width, canvasRef.current.height);
  
        // Add the latest data point to the array
        dataPoints.current.push({ x: volume + 100, y: pitch });
  
        // If the data points array exceeds 20 points, remove the oldest point
        if (dataPoints.current.length > 20) {
          dataPoints.current.shift();
        }
  
        // Draw the coordinate axes
        ctx.strokeStyle = 'black';
        ctx.lineWidth = 1;
        ctx.beginPath();
        ctx.moveTo(50, 50);
        ctx.lineTo(50, canvasRef.current.height - 50);
        ctx.lineTo(canvasRef.current.width - 50, canvasRef.current.height - 50);
        ctx.stroke();
  
        // Draw the grid lines
        ctx.strokeStyle = 'lightgray';
        ctx.lineWidth = 0.5;
        ctx.beginPath();
  
        // Draw vertical grid lines
        for (let i = 100; i < canvasRef.current.width - 50; i += 100) {
          ctx.moveTo(i, 50);
          ctx.lineTo(i, canvasRef.current.height - 50);
        }
  
        // Draw horizontal grid lines
        for (let i = 100; i < canvasRef.current.height - 50; i += 100) {
          ctx.moveTo(50, i);
          ctx.lineTo(canvasRef.current.width - 50, i);
        }
  
        ctx.stroke();
  
        // Draw the coordinate axis labels
        ctx.fillStyle = 'black';
        ctx.font = '12px Arial';
  
        // Draw x-axis labels
        ctx.textAlign = 'center';
        ctx.textBaseline = 'top';
        for (let i = 0; i <= 100; i += 10) {
          const x = 50 + (i * (canvasRef.current.width - 100)) / 100;
          ctx.fillText(i.toString(), x, canvasRef.current.height - 40);
        }
  
        // Draw y-axis labels
        ctx.textAlign = 'right';
        ctx.textBaseline = 'middle';
        for (let i = 0; i <= 1000; i += 100) {
          const y = canvasRef.current.height - 50 - (i * (canvasRef.current.height - 100) / 1000);
          ctx.fillText(i.toString(), 45, y);
        }
  
        // Draw the x-axis title
        ctx.textAlign = 'center';
        ctx.textBaseline = 'bottom';
        ctx.fillText('Volume', canvasRef.current.width / 2, canvasRef.current.height - 10);
  
        // Draw the y-axis title
        ctx.save();
        ctx.translate(10, canvasRef.current.height / 2);
        ctx.rotate(-Math.PI / 2);
        ctx.textAlign = 'center';
        ctx.textBaseline = 'top';
        ctx.fillText('Pitch', 0, 0);
        ctx.restore();
  
        // Draw the data points
        ctx.strokeStyle = 'blue';
        ctx.lineWidth = 2;
        ctx.beginPath();
        dataPoints.current.forEach((point, index) => {
          if (canvasRef.current) {
            const x = 50 + (point.x * (canvasRef.current.width - 100)) / 100;
            const y = point.y !== null ? canvasRef.current.height - 50 - (point.y * (canvasRef.current.height - 100) / 1000) : canvasRef.current.height - 50;
            if (index === 0) {
              ctx.moveTo(x, y);
            } else {
              ctx.lineTo(x, y);
            }
          }
        });
        ctx.stroke();
      }
    }
  }, [volume, pitch]);

  return (
    <div>
      <canvas ref={canvasRef} width="900" height="900" style={{ border: '0px solid black' }}></canvas>
    </div>
  );
};

export default Volume;