'use client'

import { useState, useCallback, useRef, useEffect } from 'react'

export interface AudioRecorderState {
  isRecording: boolean
  audioBlob: Blob | null
  recordingTime: number
  isProcessing: boolean
  error: string | null
}

interface AudioRecorderProps {
  onRecordingComplete: (audioBlob: Blob) => void
  onRecordingStart?: () => void
  onRecordingStop?: () => void
  onError?: (error: string) => void
  maxDuration?: number // 最大錄音時長（秒）
  disabled?: boolean
  className?: string
}

export function AudioRecorder({
  onRecordingComplete,
  onRecordingStart,
  onRecordingStop,
  onError,
  maxDuration = 30,
  disabled = false,
  className = ""
}: AudioRecorderProps) {
  const [state, setState] = useState<AudioRecorderState>({
    isRecording: false,
    audioBlob: null,
    recordingTime: 0,
    isProcessing: false,
    error: null
  })

  const mediaRecorderRef = useRef<MediaRecorder | null>(null)
  const streamRef = useRef<MediaStream | null>(null)
  const audioChunksRef = useRef<Blob[]>([])
  const timerRef = useRef<NodeJS.Timeout | null>(null)

  // 清理函數
  const cleanup = useCallback(() => {
    if (timerRef.current) {
      clearInterval(timerRef.current)
      timerRef.current = null
    }

    if (streamRef.current) {
      streamRef.current.getTracks().forEach(track => track.stop())
      streamRef.current = null
    }

    if (mediaRecorderRef.current && mediaRecorderRef.current.state !== 'inactive') {
      mediaRecorderRef.current.stop()
    }

    audioChunksRef.current = []
  }, [])

  // 組件卸載時清理
  useEffect(() => {
    return cleanup
  }, [cleanup])

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

    try {
      setState(prev => ({ ...prev, error: null, isProcessing: true }))

      // 請求麥克風權限
      const stream = await navigator.mediaDevices.getUserMedia({
        audio: {
          echoCancellation: true,
          noiseSuppression: true,
          sampleRate: 16000 // Azure Speech Services 推薦採樣率
        }
      })

      streamRef.current = stream
      audioChunksRef.current = []

      // 創建 MediaRecorder
      const mediaRecorder = new MediaRecorder(stream, {
        mimeType: 'audio/webm;codecs=opus' // 現代瀏覽器支援的格式
      })

      mediaRecorderRef.current = mediaRecorder

      // 處理錄音資料
      mediaRecorder.ondataavailable = (event) => {
        if (event.data.size > 0) {
          audioChunksRef.current.push(event.data)
        }
      }

      // 錄音完成處理
      mediaRecorder.onstop = () => {
        setState(prev => ({ ...prev, isProcessing: true }))

        const audioBlob = new Blob(audioChunksRef.current, { type: 'audio/webm' })

        setState(prev => ({
          ...prev,
          audioBlob,
          isRecording: false,
          isProcessing: false
        }))

        onRecordingComplete(audioBlob)
        cleanup()
      }

      // 開始錄音
      mediaRecorder.start(1000) // 每秒收集一次資料

      // 啟動計時器
      let seconds = 0
      timerRef.current = setInterval(() => {
        seconds++
        setState(prev => ({ ...prev, recordingTime: seconds }))

        // 達到最大時長自動停止
        if (seconds >= maxDuration) {
          stopRecording()
        }
      }, 1000)

      setState(prev => ({
        ...prev,
        isRecording: true,
        recordingTime: 0,
        isProcessing: false
      }))

      onRecordingStart?.()

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : '麥克風存取失敗'
      setState(prev => ({
        ...prev,
        error: errorMessage,
        isProcessing: false
      }))
      onError?.(errorMessage)
      cleanup()
    }
  }, [disabled, maxDuration, onRecordingComplete, onRecordingStart, onError, cleanup])

  // 停止錄音
  const stopRecording = useCallback(() => {
    if (mediaRecorderRef.current && mediaRecorderRef.current.state === 'recording') {
      mediaRecorderRef.current.stop()
      onRecordingStop?.()
    }

    if (timerRef.current) {
      clearInterval(timerRef.current)
      timerRef.current = null
    }
  }, [onRecordingStop])

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

  return (
    <div className={`text-center ${className}`}>
      {/* 錯誤顯示 */}
      {state.error && (
        <div className="bg-red-50 border border-red-200 rounded-lg p-3 mb-4">
          <p className="text-red-700 text-sm">⚠️ {state.error}</p>
        </div>
      )}

      {/* 錄音按鈕 */}
      <div className="mb-4">
        {!state.isRecording ? (
          <button
            onClick={startRecording}
            disabled={disabled || state.isProcessing}
            className={`px-6 py-3 rounded-full font-medium transition-all ${
              disabled || state.isProcessing
                ? 'bg-gray-300 text-gray-500 cursor-not-allowed'
                : 'bg-red-500 hover:bg-red-600 text-white transform hover:scale-105'
            }`}
          >
            {state.isProcessing ? (
              <span className="flex items-center gap-2">
                <div className="animate-spin w-4 h-4 border-2 border-white border-t-transparent rounded-full"></div>
                準備中...
              </span>
            ) : (
              <span className="flex items-center gap-2">
                🎤 開始錄音
              </span>
            )}
          </button>
        ) : (
          <button
            onClick={stopRecording}
            className="px-6 py-3 bg-red-600 hover:bg-red-700 text-white rounded-full font-medium animate-pulse transition-all"
          >
            <span className="flex items-center gap-2">
              ⏹️ 停止錄音
            </span>
          </button>
        )}
      </div>

      {/* 錄音狀態顯示 */}
      {state.isRecording && (
        <div className="bg-red-50 border border-red-200 rounded-lg p-4">
          <div className="flex items-center justify-center gap-3 mb-2">
            <div className="w-3 h-3 bg-red-500 rounded-full animate-ping"></div>
            <span className="text-red-700 font-medium">錄音中</span>
          </div>

          <div className="text-red-600 text-xl font-mono">
            {formatTime(state.recordingTime)}
          </div>

          <div className="text-red-500 text-sm mt-2">
            最長 {formatTime(maxDuration)}
          </div>

          {/* 進度條 */}
          <div className="w-full bg-red-100 rounded-full h-2 mt-3">
            <div
              className="bg-red-500 h-2 rounded-full transition-all duration-1000"
              style={{ width: `${(state.recordingTime / maxDuration) * 100}%` }}
            ></div>
          </div>
        </div>
      )}

      {/* 錄音完成提示 */}
      {state.audioBlob && !state.isRecording && (
        <div className="bg-green-50 border border-green-200 rounded-lg p-3 mt-4">
          <p className="text-green-700 text-sm">
            ✅ 錄音完成！時長: {formatTime(state.recordingTime)}
          </p>
        </div>
      )}

      {/* 瀏覽器兼容性提示 */}
      {!navigator.mediaDevices?.getUserMedia && (
        <div className="bg-yellow-50 border border-yellow-200 rounded-lg p-3 mt-4">
          <p className="text-yellow-700 text-sm">
            ⚠️ 您的瀏覽器不支援錄音功能，建議使用 Chrome 或 Firefox
          </p>
        </div>
      )}
    </div>
  )
}

// Hook 版本，提供更靈活的使用方式
export function useAudioRecorder(maxDuration: number = 30) {
  const [state, setState] = useState<AudioRecorderState>({
    isRecording: false,
    audioBlob: null,
    recordingTime: 0,
    isProcessing: false,
    error: null
  })

  const mediaRecorderRef = useRef<MediaRecorder | null>(null)
  const streamRef = useRef<MediaStream | null>(null)
  const audioChunksRef = useRef<Blob[]>([])
  const timerRef = useRef<NodeJS.Timeout | null>(null)

  const cleanup = useCallback(() => {
    if (timerRef.current) {
      clearInterval(timerRef.current)
      timerRef.current = null
    }

    if (streamRef.current) {
      streamRef.current.getTracks().forEach(track => track.stop())
      streamRef.current = null
    }

    if (mediaRecorderRef.current && mediaRecorderRef.current.state !== 'inactive') {
      mediaRecorderRef.current.stop()
    }

    audioChunksRef.current = []
  }, [])

  const startRecording = useCallback(async () => {
    try {
      setState(prev => ({ ...prev, error: null, isProcessing: true }))

      const stream = await navigator.mediaDevices.getUserMedia({
        audio: {
          echoCancellation: true,
          noiseSuppression: true,
          sampleRate: 16000
        }
      })

      streamRef.current = stream
      audioChunksRef.current = []

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

      mediaRecorderRef.current = mediaRecorder

      mediaRecorder.ondataavailable = (event) => {
        if (event.data.size > 0) {
          audioChunksRef.current.push(event.data)
        }
      }

      mediaRecorder.onstop = () => {
        const audioBlob = new Blob(audioChunksRef.current, { type: 'audio/webm' })
        setState(prev => ({
          ...prev,
          audioBlob,
          isRecording: false,
          isProcessing: false
        }))
        cleanup()
      }

      mediaRecorder.start(1000)

      let seconds = 0
      timerRef.current = setInterval(() => {
        seconds++
        setState(prev => ({ ...prev, recordingTime: seconds }))

        if (seconds >= maxDuration) {
          stopRecording()
        }
      }, 1000)

      setState(prev => ({
        ...prev,
        isRecording: true,
        recordingTime: 0,
        isProcessing: false
      }))

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : '錄音失敗'
      setState(prev => ({
        ...prev,
        error: errorMessage,
        isProcessing: false
      }))
      cleanup()
    }
  }, [maxDuration, cleanup])

  const stopRecording = useCallback(() => {
    if (mediaRecorderRef.current && mediaRecorderRef.current.state === 'recording') {
      mediaRecorderRef.current.stop()
    }

    if (timerRef.current) {
      clearInterval(timerRef.current)
      timerRef.current = null
    }
  }, [])

  const resetRecording = useCallback(() => {
    cleanup()
    setState({
      isRecording: false,
      audioBlob: null,
      recordingTime: 0,
      isProcessing: false,
      error: null
    })
  }, [cleanup])

  // 清理函數
  useEffect(() => {
    return cleanup
  }, [cleanup])

  return {
    ...state,
    startRecording,
    stopRecording,
    resetRecording
  }
}