"use client";

import { useEffect, useRef, useState } from 'react';
import MidiPlayer from 'midi-player-js';
import Soundfont from 'soundfont-player';

export default function HomePage() {
  const audioCtxRef = useRef<AudioContext | null>(null);
  const instrumentRef = useRef<any>(null);
  const playerRef = useRef<any>(null);

  const [soundfontLoading, setSoundfontLoading] = useState(true);
  const [fileLoaded, setFileLoaded] = useState(false);
  const [isPlaying, setIsPlaying] = useState(false);
  const [tempo, setTempo] = useState(120);
  const [fileFormat, setFileFormat] = useState<number | null>(null);
  const [progress, setProgress] = useState(0);

  useEffect(() => {
    const AudioContext = window.AudioContext || (window as any).webkitAudioContext;
    const audioCtx = new AudioContext();
    audioCtxRef.current = audioCtx;

    Soundfont.instrument(audioCtx, 'acoustic_grand_piano').then(instrument => {
      instrumentRef.current = instrument;

      const player = new MidiPlayer.Player((event: any) => {
        if (!instrumentRef.current) return;
        if (event.name === 'Note on' && event.velocity > 0) {
          instrumentRef.current.play(event.noteName, audioCtx.currentTime, { gain: 1 });
        } else if ((event.name === 'Note on' && event.velocity === 0) || event.name === 'Note off') {
          instrumentRef.current.stop(event.noteName, audioCtx.currentTime);
        }
      });

      player.on('endOfFile', () => {
        setIsPlaying(false);
        setProgress(0);
      });

      player.on('fileLoaded', () => {
        try {
          setFileFormat(player.getFormat());
        } catch {
          setFileFormat(null);
        }
        setTempo(120);
        setFileLoaded(true);
        setProgress(0);
      });

      playerRef.current = player;
      setSoundfontLoading(false);
    });

    return () => {
      audioCtx.close();
    };
  }, []);

  useEffect(() => {
    if (!playerRef.current) return;
    let interval: any;
    if (isPlaying) {
      interval = setInterval(() => {
        const remaining = playerRef.current.getSongPercentRemaining();
        setProgress(100 - (remaining || 0));
      }, 200);
    }
    return () => clearInterval(interval);
  }, [isPlaying]);

  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file && playerRef.current) {
      const reader = new FileReader();
      reader.onload = () => {
        const arrayBuffer = reader.result;
        if (!arrayBuffer) return;
        playerRef.current.stop();
        playerRef.current.loadArrayBuffer(arrayBuffer);
      };
      reader.readAsArrayBuffer(file);
    }
  };

  const handlePlayPause = () => {
    if (isPlaying) {
      playerRef.current.pause();
    } else {
      playerRef.current.play();
    }
    setIsPlaying(!isPlaying);
  };

  const handleStop = () => {
    playerRef.current.stop();
    setIsPlaying(false);
    setProgress(0);
  };

  const handleTempoChange = (newTempo: number) => {
    playerRef.current.pause();
    playerRef.current.setTempo(newTempo);
    playerRef.current.play();
    setTempo(newTempo);
    setIsPlaying(true);
  };

  return (
    <main className="max-w-xl mx-auto p-4">
      <h1 className="text-3xl font-bold">♬ MidiPlayerJS</h1>
      {soundfontLoading ? "Loading soundfont..." : (
        <input type="file" accept=".mid,.midi" onChange={handleFileChange} />
      )}
      <button onClick={handlePlayPause} disabled={!fileLoaded}>
        {isPlaying ? "Pause" : "Play"}
      </button>
      <button onClick={handleStop}>Stop</button>
      <input type="range" min="50" max="200" value={tempo} onChange={(e) => handleTempoChange(Number(e.target.value))} />
      <div>MIDI Format: {fileFormat}</div>
      <div>Progress: {progress}%</div>
    </main>
  );
}
