'use client';

/**
 * Voice note recorder. Records audio via MediaRecorder API and uploads
 * to Firebase Storage at `events/{eventId}/photos/{photoId}/voice.webm`,
 * then writes a `voiceNoteUrl` field on the photo doc.
 */

import { useEffect, useRef, useState } from 'react';
import { Mic, Square, Trash2, Upload, Loader2, Play, Pause } from 'lucide-react';
import { storage, db } from '@/lib/firebase';
import { ref, uploadBytes, getDownloadURL } from 'firebase/storage';
import { doc, updateDoc } from 'firebase/firestore';

interface Props {
  eventId: string;
  photoId: string;
  onClose: () => void;
  onSaved?: (url: string) => void;
}

export default function VoiceRecorder({ eventId, photoId, onClose, onSaved }: Props) {
  const [recording, setRecording] = useState(false);
  const [audioBlob, setAudioBlob] = useState<Blob | null>(null);
  const [audioUrl, setAudioUrl] = useState<string | null>(null);
  const [elapsed, setElapsed] = useState(0);
  const [uploading, setUploading] = useState(false);
  const [playing, setPlaying] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const recorderRef = useRef<MediaRecorder | null>(null);
  const chunksRef = useRef<Blob[]>([]);
  const startedAtRef = useRef<number>(0);
  const audioRef = useRef<HTMLAudioElement | null>(null);

  useEffect(() => {
    if (!recording) return;
    const interval = setInterval(() => setElapsed(Math.floor((Date.now() - startedAtRef.current) / 1000)), 250);
    return () => clearInterval(interval);
  }, [recording]);

  const start = async () => {
    setError(null);
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      const recorder = new MediaRecorder(stream, { mimeType: 'audio/webm' });
      chunksRef.current = [];
      recorder.ondataavailable = (e) => { if (e.data.size > 0) chunksRef.current.push(e.data); };
      recorder.onstop = () => {
        const blob = new Blob(chunksRef.current, { type: 'audio/webm' });
        setAudioBlob(blob);
        setAudioUrl(URL.createObjectURL(blob));
        stream.getTracks().forEach((t) => t.stop());
      };
      recorderRef.current = recorder;
      startedAtRef.current = Date.now();
      setElapsed(0);
      recorder.start();
      setRecording(true);
    } catch (e: any) {
      setError(e?.message || 'Microphone access denied');
    }
  };

  const stop = () => {
    recorderRef.current?.stop();
    setRecording(false);
  };

  const discard = () => {
    if (audioUrl) URL.revokeObjectURL(audioUrl);
    setAudioBlob(null);
    setAudioUrl(null);
    setElapsed(0);
  };

  const upload = async () => {
    if (!audioBlob) return;
    setUploading(true);
    setError(null);
    try {
      const path = `events/${eventId}/photos/${photoId}/voice.webm`;
      const sref = ref(storage!, path);
      await uploadBytes(sref, audioBlob, { contentType: 'audio/webm' });
      const url = await getDownloadURL(sref);
      await updateDoc(doc(db, 'events', eventId, 'photos', photoId), {
        voiceNoteUrl: url,
        voiceNoteDuration: elapsed,
      });
      onSaved?.(url);
      onClose();
    } catch (e: any) {
      setError(e?.message || 'Upload failed');
    } finally {
      setUploading(false);
    }
  };

  const togglePlay = () => {
    if (!audioRef.current) return;
    if (playing) { audioRef.current.pause(); setPlaying(false); }
    else { audioRef.current.play(); setPlaying(true); }
  };

  return (
    <div className="fixed inset-0 z-[120] bg-black/95 flex items-center justify-center p-4" onClick={onClose}>
      <div className="bg-zinc-950 rounded-2xl border border-zinc-800 p-6 max-w-sm w-full" onClick={(e) => e.stopPropagation()}>
        <h3 className="text-base font-semibold mb-1">Voice Note</h3>
        <p className="text-xs text-zinc-500 mb-5">Record up to 60 seconds.</p>

        {error && (
          <div className="mb-4 rounded-lg bg-red-500/10 border border-red-500/30 p-2 text-xs text-red-300">{error}</div>
        )}

        <div className="flex flex-col items-center gap-4">
          <div className="text-3xl font-mono tabular-nums">
            {String(Math.floor(elapsed / 60)).padStart(2, '0')}:{String(elapsed % 60).padStart(2, '0')}
          </div>

          {!audioBlob ? (
            recording ? (
              <button
                onClick={stop}
                className="h-16 w-16 rounded-full bg-red-500 hover:bg-red-600 flex items-center justify-center"
                aria-label="Stop"
              >
                <Square className="h-7 w-7 text-white fill-white" />
              </button>
            ) : (
              <button
                onClick={start}
                className="h-16 w-16 rounded-full bg-amber-300 hover:bg-amber-200 flex items-center justify-center"
                aria-label="Record"
              >
                <Mic className="h-7 w-7 text-zinc-950" />
              </button>
            )
          ) : (
            <>
              <audio
                ref={audioRef}
                src={audioUrl!}
                onEnded={() => setPlaying(false)}
                className="hidden"
              />
              <div className="flex items-center gap-3">
                <button
                  onClick={togglePlay}
                  className="h-12 w-12 rounded-full bg-zinc-800 hover:bg-zinc-700 flex items-center justify-center"
                  aria-label={playing ? 'Pause' : 'Play'}
                >
                  {playing ? <Pause className="h-5 w-5" /> : <Play className="h-5 w-5" />}
                </button>
                <button
                  onClick={discard}
                  className="h-12 w-12 rounded-full bg-zinc-800 hover:bg-zinc-700 flex items-center justify-center"
                  aria-label="Discard"
                >
                  <Trash2 className="h-5 w-5 text-red-300" />
                </button>
                <button
                  onClick={upload}
                  disabled={uploading}
                  className="h-12 px-4 rounded-full bg-amber-300 hover:bg-amber-200 text-zinc-950 font-medium text-sm flex items-center gap-2 disabled:opacity-50"
                >
                  {uploading ? <Loader2 className="h-4 w-4 animate-spin" /> : <Upload className="h-4 w-4" />}
                  Save
                </button>
              </div>
            </>
          )}
        </div>
      </div>
    </div>
  );
}
