'use client';

// AudioInput.tsx
import React, { useRef, useState } from "react";
import { readAudio } from './audioUtils'; // Import the updated utility

interface AudioInputProps {
  input: Blob | null;
  setInput: (v: Blob | null) => void;
  classify: (input: Float32Array) => void; // Still needs Float32Array
  ready: boolean | null;
}

export const AudioInput = ({ input, setInput, classify, ready }: AudioInputProps) => {
  const [recording, setRecording] = useState(false);
  const [audioUrl, setAudioUrl] = useState<string | null>(null);
  const mediaRecorderRef = useRef<MediaRecorder | null>(null);
  const chunks = useRef<Blob[]>([]);
  const fileInputRef = useRef<HTMLInputElement>(null);

  const handleDrop = async (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    if (e.dataTransfer.files.length > 0) {
      const file = e.dataTransfer.files[0];
      if (file.type.startsWith("audio/")) {
        setInput(file);
        // Revoke previous URL to free memory
        if (audioUrl) URL.revokeObjectURL(audioUrl);
        setAudioUrl(URL.createObjectURL(file));
        try {
            const audioData = await readAudio(file); // Now decodes AND resamples to Float32Array PCM
            classify(audioData);
        } catch (error) {
             console.error("Error reading or processing audio file:", error);
             // Handle error, e.g., show a message to the user
        }
      }
    }
  };

  const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files && e.target.files.length > 0) {
      const file = e.target.files[0];
      if (file.type.startsWith("audio/")) {
        setInput(file);
         // Revoke previous URL to free memory
        if (audioUrl) URL.revokeObjectURL(audioUrl);
        setAudioUrl(URL.createObjectURL(file));
        try {
            const audioData = await readAudio(file); // Now decodes AND resamples to Float32Array PCM
            classify(audioData);
        } catch (error) {
            console.error("Error reading or processing audio file:", error);
            // Handle error
        }
      }
    }
  };

  const startRecording = async () => {
    try {
        setRecording(true);
        chunks.current = [];
        // Ensure audioUrl is cleared for new recording
         if (audioUrl) URL.revokeObjectURL(audioUrl);
         setAudioUrl(null);
         setInput(null); // Clear previous input blob

        const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
        const mediaRecorder = new window.MediaRecorder(stream);
        mediaRecorderRef.current = mediaRecorder;

        mediaRecorder.ondataavailable = (e) => {
          if (e.data.size > 0) {
            chunks.current.push(e.data);
          }
        };

        mediaRecorder.onstop = async () => {
          const blob = new Blob(chunks.current, { type: "audio/webm" }); // MediaRecorder outputs a Blob
          setInput(blob); // Set the Blob input if needed elsewhere
           // Revoke previous URL
          if (audioUrl) URL.revokeObjectURL(audioUrl);
          setAudioUrl(URL.createObjectURL(blob)); // Create URL for playback

          try {
            const audioData = await readAudio(blob); // Decode AND resample Blob to Float32Array PCM
            classify(audioData); // Pass the Float32Array PCM data
          } catch (error) {
             console.error("Error reading or processing recorded audio:", error);
             // Handle error
          } finally {
             // Always stop tracks after recording stops
             stream.getTracks().forEach(track => track.stop());
          }
        };

        mediaRecorder.start();
    } catch (error) {
        console.error("Error starting recording:", error);
        setRecording(false); // Ensure recording state is reset on error
        // Handle error, e.g., show a message to the user that mic access failed
    }
  };

  const stopRecording = async () => {
     if (!mediaRecorderRef.current) return;
     // The actual classification and setting of input/audioUrl happens in mediaRecorder.onstop
     mediaRecorderRef.current.stop();
     setRecording(false); // Set recording state to false immediately
  };

  // Added error handling and URL cleanup
  React.useEffect(() => {
      // Cleanup object URLs when component unmounts or audioUrl changes
      return () => {
          if (audioUrl) URL.revokeObjectURL(audioUrl);
      };
  }, [audioUrl]);


  return (
    <div className="flex flex-col gap-4 h-full">
      <label className="block text-gray-600 mb-2 text-sm font-medium">Upload or record audio</label>
      <div
        className={`flex-1 flex flex-col items-center justify-center border-2 border-dashed rounded-lg p-6 bg-gray-50 transition
          ${ready === false ? 'border-gray-200 text-gray-400 cursor-not-allowed' : 'border-gray-300 cursor-pointer hover:border-blue-400'}
        `}
        onDrop={handleDrop}
        onDragOver={e => e.preventDefault()}
        onClick={() => ready !== false && fileInputRef.current?.click()} // Prevent click if not ready
        style={{ minHeight: 120 }}
      >
        <input
          ref={fileInputRef}
          type="file"
          accept="audio/*"
          style={{ display: "none" }}
          onChange={handleFileChange}
          disabled={ready === false}
        />
        <span className="text-gray-500 text-center">
           { ready === false ? "Loading models..." : "Drag & drop audio file here or click to select" }
        </span>
      </div>
      <div className="flex items-center gap-4">
        {!recording ? (
          <button
            className="px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700 transition disabled:opacity-50 disabled:cursor-not-allowed"
            onClick={startRecording}
            disabled={ready === false} // Disable record button if not ready
          >
            Record
          </button>
        ) : (
          <button
            className="px-4 py-2 bg-red-600 text-white rounded hover:bg-red-700 transition"
            onClick={stopRecording}
          >
            Stop
          </button>
        )}
        {/* Only show audio player if not recording and audioUrl exists */}
        {!recording && audioUrl && (
          <audio controls src={audioUrl} className="ml-4 flex-1">
            Your browser does not support the audio element.
          </audio>
        )}
         {ready === false && <span className="text-gray-600 ml-auto">Loading...</span>} {/* Optional loading indicator */}
      </div>
    </div>
  );
};