'use client';

import { useState, useRef, useCallback, useEffect } from 'react';
import { Mic, Square, Play, Upload } from 'lucide-react';

export interface PronunciationScore {
  overall: number;
  accuracy: number;
  fluency: number;
  completeness: number;
  prosody: number;
  phonemes: PhonemeScore[];
  suggestions: string[];
}

export interface PhonemeScore {
  phoneme: string;
  score: number;
  suggestion?: string;
}

export interface VoiceRecorderProps {
  targetText: string;
  onScoreReceived?: (score: PronunciationScore) => void;
  onRecordingComplete?: (audioBlob: Blob) => void;
  maxDuration?: number;
  userLevel?: string;
  className?: string;
}

export default function VoiceRecorder({
  targetText,
  onScoreReceived,
  onRecordingComplete,
  maxDuration = 30, // 30 seconds default
  userLevel = 'B1',
  className = ''
}: VoiceRecorderProps) {
  const [isRecording, setIsRecording] = useState(false);
  const [isProcessing, setIsProcessing] = useState(false);
  const [recordingTime, setRecordingTime] = useState(0);
  const [audioBlob, setAudioBlob] = useState<Blob | null>(null);
  const [audioUrl, setAudioUrl] = useState<string | null>(null);
  const [score, setScore] = useState<PronunciationScore | null>(null);
  const [error, setError] = useState<string | null>(null);

  const mediaRecorderRef = useRef<MediaRecorder | null>(null);
  const streamRef = useRef<MediaStream | null>(null);
  const timerRef = useRef<NodeJS.Timeout | null>(null);
  const audioRef = useRef<HTMLAudioElement>(null);

  // 檢查瀏覽器支援
  const checkBrowserSupport = () => {
    if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
      setError('Your browser does not support audio recording');
      return false;
    }
    return true;
  };

  // 開始錄音
  const startRecording = useCallback(async () => {
    if (!checkBrowserSupport()) return;

    try {
      setError(null);
      setScore(null);
      setAudioBlob(null);
      setAudioUrl(null);

      // 請求麥克風權限
      const stream = await navigator.mediaDevices.getUserMedia({
        audio: {
          echoCancellation: true,
          noiseSuppression: true,
          sampleRate: 16000
        }
      });

      streamRef.current = stream;

      // 設置 MediaRecorder
      const mediaRecorder = new MediaRecorder(stream, {
        mimeType: 'audio/webm;codecs=opus'
      });

      const audioChunks: Blob[] = [];

      mediaRecorder.ondataavailable = (event) => {
        if (event.data.size > 0) {
          audioChunks.push(event.data);
        }
      };

      mediaRecorder.onstop = () => {
        const blob = new Blob(audioChunks, { type: 'audio/webm' });
        setAudioBlob(blob);
        setAudioUrl(URL.createObjectURL(blob));
        onRecordingComplete?.(blob);

        // 停止所有音軌
        stream.getTracks().forEach(track => track.stop());
      };

      mediaRecorderRef.current = mediaRecorder;
      mediaRecorder.start();
      setIsRecording(true);
      setRecordingTime(0);

      // 開始計時
      timerRef.current = setInterval(() => {
        setRecordingTime(prev => {
          const newTime = prev + 1;
          if (newTime >= maxDuration) {
            stopRecording();
          }
          return newTime;
        });
      }, 1000);

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Failed to start recording';
      setError(errorMessage);
      console.error('Recording error:', error);
    }
  }, [maxDuration, onRecordingComplete]);

  // 停止錄音
  const stopRecording = useCallback(() => {
    if (mediaRecorderRef.current && isRecording) {
      mediaRecorderRef.current.stop();
      setIsRecording(false);

      if (timerRef.current) {
        clearInterval(timerRef.current);
        timerRef.current = null;
      }

      if (streamRef.current) {
        streamRef.current.getTracks().forEach(track => track.stop());
        streamRef.current = null;
      }
    }
  }, [isRecording]);

  // 播放錄音
  const playRecording = useCallback(() => {
    if (audioUrl && audioRef.current) {
      audioRef.current.src = audioUrl;
      audioRef.current.play();
    }
  }, [audioUrl]);

  // 評估發音
  const evaluatePronunciation = useCallback(async () => {
    if (!audioBlob || !targetText) {
      setError('No audio to evaluate');
      return;
    }

    try {
      setIsProcessing(true);
      setError(null);

      const formData = new FormData();
      formData.append('audioFile', audioBlob, 'recording.webm');
      formData.append('targetText', targetText);
      formData.append('userLevel', userLevel);

      const token = localStorage.getItem('token');
      if (!token) {
        throw new Error('Authentication required');
      }

      const response = await fetch('/api/audio/pronunciation/evaluate', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${token}`
        },
        body: formData
      });

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      const result = await response.json();

      if (result.error) {
        throw new Error(result.error);
      }

      setScore(result);
      onScoreReceived?.(result);

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Failed to evaluate pronunciation';
      setError(errorMessage);
    } finally {
      setIsProcessing(false);
    }
  }, [audioBlob, targetText, userLevel, onScoreReceived]);

  // 格式化時間
  const formatTime = (seconds: number) => {
    const mins = Math.floor(seconds / 60);
    const secs = seconds % 60;
    return `${mins}:${secs.toString().padStart(2, '0')}`;
  };

  // 獲取評分顏色
  const getScoreColor = (score: number) => {
    if (score >= 90) return 'text-green-600';
    if (score >= 80) return 'text-blue-600';
    if (score >= 70) return 'text-yellow-600';
    if (score >= 60) return 'text-orange-600';
    return 'text-red-600';
  };

  // 清理資源
  useEffect(() => {
    return () => {
      if (timerRef.current) {
        clearInterval(timerRef.current);
      }
      if (streamRef.current) {
        streamRef.current.getTracks().forEach(track => track.stop());
      }
      if (audioUrl) {
        URL.revokeObjectURL(audioUrl);
      }
    };
  }, [audioUrl]);

  return (
    <div className={`voice-recorder p-6 border-2 border-dashed border-gray-300 rounded-xl ${className}`}>
      {/* 隱藏的音頻元素 */}
      <audio ref={audioRef} />

      {/* 目標文字顯示 */}
      <div className="text-center mb-6">
        <h3 className="text-lg font-semibold mb-2">請朗讀以下內容：</h3>
        <p className="text-2xl font-medium text-gray-800 p-4 bg-blue-50 rounded-lg">
          {targetText}
        </p>
      </div>

      {/* 錄音控制區 */}
      <div className="flex flex-col items-center gap-4">
        {/* 錄音按鈕 */}
        <button
          onClick={isRecording ? stopRecording : startRecording}
          disabled={isProcessing}
          className={`
            w-20 h-20 rounded-full flex items-center justify-center transition-all
            ${isRecording
              ? 'bg-red-500 hover:bg-red-600 animate-pulse'
              : 'bg-blue-500 hover:bg-blue-600'
            }
            ${isProcessing ? 'opacity-50 cursor-not-allowed' : ''}
            text-white shadow-lg
          `}
          title={isRecording ? 'Stop Recording' : 'Start Recording'}
        >
          {isRecording ? <Square size={32} /> : <Mic size={32} />}
        </button>

        {/* 錄音狀態 */}
        {isRecording && (
          <div className="text-center">
            <div className="text-red-600 font-semibold">
              🔴 錄音中...
            </div>
            <div className="text-sm text-gray-600">
              {formatTime(recordingTime)} / {formatTime(maxDuration)}
            </div>
          </div>
        )}

        {/* 播放和評估按鈕 */}
        {audioBlob && !isRecording && (
          <div className="flex gap-3">
            <button
              onClick={playRecording}
              className="flex items-center gap-2 px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors"
            >
              <Play size={16} />
              播放錄音
            </button>
            <button
              onClick={evaluatePronunciation}
              disabled={isProcessing}
              className="flex items-center gap-2 px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors disabled:opacity-50"
            >
              <Upload size={16} />
              {isProcessing ? '評估中...' : '評估發音'}
            </button>
          </div>
        )}

        {/* 處理狀態 */}
        {isProcessing && (
          <div className="flex items-center gap-2 text-blue-600">
            <div className="animate-spin w-4 h-4 border-2 border-blue-600 border-t-transparent rounded-full" />
            正在評估您的發音...
          </div>
        )}

        {/* 錯誤顯示 */}
        {error && (
          <div className="text-red-600 bg-red-50 p-3 rounded-lg text-center max-w-md">
            {error}
          </div>
        )}

        {/* 評分結果 */}
        {score && (
          <div className="score-display w-full max-w-md mx-auto mt-4 p-4 bg-white border rounded-lg shadow">
            {/* 總分 */}
            <div className="text-center mb-4">
              <div className={`text-4xl font-bold ${getScoreColor(score.overall)}`}>
                {score.overall}
              </div>
              <div className="text-sm text-gray-600">總體評分</div>
            </div>

            {/* 詳細評分 */}
            <div className="grid grid-cols-2 gap-3 mb-4 text-sm">
              <div className="flex justify-between">
                <span>準確度:</span>
                <span className={getScoreColor(score.accuracy)}>{score.accuracy.toFixed(1)}</span>
              </div>
              <div className="flex justify-between">
                <span>流暢度:</span>
                <span className={getScoreColor(score.fluency)}>{score.fluency.toFixed(1)}</span>
              </div>
              <div className="flex justify-between">
                <span>完整度:</span>
                <span className={getScoreColor(score.completeness)}>{score.completeness.toFixed(1)}</span>
              </div>
              <div className="flex justify-between">
                <span>音調:</span>
                <span className={getScoreColor(score.prosody)}>{score.prosody.toFixed(1)}</span>
              </div>
            </div>

            {/* 改進建議 */}
            {score.suggestions.length > 0 && (
              <div className="suggestions">
                <h4 className="font-semibold mb-2 text-gray-800">💡 改進建議：</h4>
                <ul className="text-sm text-gray-700 space-y-1">
                  {score.suggestions.map((suggestion, index) => (
                    <li key={index} className="flex items-start gap-2">
                      <span className="text-blue-500">•</span>
                      {suggestion}
                    </li>
                  ))}
                </ul>
              </div>
            )}
          </div>
        )}
      </div>
    </div>
  );
}