//
//  SpeakAudioToTextConverter.swift
//  SpeakEasyLearnEnglish
//
//  Created by edy on 2025/8/7.
//

import UIKit
import Speech


class SpeakAudioToTextConverter: NSObject, SFSpeechRecognizerDelegate {
    
    static let share = SpeakAudioToTextConverter()
    // 语音识别器
    private let speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: "en-US"))!
    // 语音识别请求
    private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?
    // 语音识别任务
    private var recognitionTask: SFSpeechRecognitionTask?
    // 音频引擎（用于实时录音）
    private let audioEngine = AVAudioEngine()
    // 识别结果回调
    var onResult: ((String) -> Void)?
    // 错误回调
    var onError: ((Error) -> Void)?
    
    
    var isRunning:Bool {
        set { }
        get {
            return audioEngine.isRunning ?? false
        }
    }
    
    private override init() {
        super.init()
        speechRecognizer.delegate = self
    }
    // 检查语音识别权限
    func checkPermissions() -> Bool {
        let status = SFSpeechRecognizer.authorizationStatus()
        switch status {
        case .authorized:
            return true
            break
        case .denied:
            break
        case .notDetermined:
            requestPermissions { su in
                
            }
            break
        default:
            break
        }
        return false
    }
    
    private func requestPermissions(completion: @escaping (Bool) -> Void) -> Void {
        SFSpeechRecognizer.requestAuthorization { authStatus in
            DispatchQueue.main.async {
                switch authStatus {
                case .authorized:
                    completion(true)
                case .denied, .restricted, .notDetermined:
                    completion(false)
                @unknown default:
                    completion(false)
                }
            }
        }
    }
    
    // 开始实时录音识别
    func startRecording() throws {
        // 取消之前的任务
        do{
            let audioSession = AVAudioSession.sharedInstance()
            try audioSession.setCategory(.playAndRecord ,mode: AVAudioSession.Mode.spokenAudio , options: [.duckOthers,.allowBluetoothA2DP])
            try audioSession.setActive(true)
        }catch{ }
        
        if let recognitionTask = recognitionTask {
            recognitionTask.cancel()
            self.recognitionTask = nil
        }
        recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
        guard let recognitionRequest = recognitionRequest else {
            fatalError("无法创建识别请求")
        }
        recognitionRequest.shouldReportPartialResults = true // 实时返回部分结果
        // 检查音频引擎输入
        let inputNode = audioEngine.inputNode
        guard let inputFormat = inputNode.inputFormat(forBus: 0) as AVAudioFormat? else {
            fatalError("无法获取音频输入格式")
        }
        // 启动识别任务
        recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest) { [weak self] result, error in
            guard let self = self else { return }
            
            if let error = error {
                self.onError?(error)
                return
            }
            
            guard let result = result else { return }
            // 返回识别结果（最终结果或部分结果）
            let transcribedText = result.bestTranscription.formattedString
            self.onResult?(transcribedText)
            
            // 如果识别完成，停止音频引擎
            if result.isFinal {
                self.stopRecording()
            }
        }
        inputNode.removeTap(onBus: 0)
        // 将音频数据添加到识别请求
        inputNode.installTap(onBus: 0, bufferSize: 1024, format: inputFormat) { buffer, _ in
            recognitionRequest.append(buffer)
        }
        
        // 启动音频引擎
        audioEngine.prepare()
        try audioEngine.start()
    }
    
    // 停止录音识别
    func stopRecording() {
        do {
            let audioSession = AVAudioSession.sharedInstance()
            try audioSession.setCategory(.playback ,mode: AVAudioSession.Mode.spokenAudio , options: [.duckOthers,.allowBluetoothA2DP])
            try audioSession.setActive(true)
        }catch {}
        if audioEngine.isRunning {
            audioEngine.stop()
            recognitionRequest?.endAudio()
            audioEngine.inputNode.removeTap(onBus: 0)
        }
        recognitionTask?.cancel()
        recognitionTask = nil
        recognitionRequest = nil
    }
    
    // 识别本地音频文件（支持 .wav, .mp3 等格式）
    func recognizeAudioFile(at url: URL) {
        let recognitionRequest = SFSpeechURLRecognitionRequest(url: url)
        recognitionRequest.shouldReportPartialResults = true
        
        recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest) { [weak self] result, error in
            guard let self = self else { return }
            
            if let error = error {
                self.onError?(error)
                return
            }
            
            guard let result = result else { return }
            
            let transcribedText = result.bestTranscription.formattedString

            if result.isFinal {
                self.onResult?(transcribedText)
                self.recognitionTask = nil
            }
        }
    }
    
    // 语音识别器可用性变化
    func speechRecognizer(_ speechRecognizer: SFSpeechRecognizer, availabilityDidChange available: Bool) {
        if available {
            print("语音识别可用")
        } else {
            print("语音识别不可用")
        }
    }
}
