import Foundation
import Speech
import AVFAudio

/// 流式语音识别，使用 Apple Speech Recognition 框架
final class SpeechRecognizer: NSObject, SFSpeechRecognizerDelegate {

    private var recognizer: SFSpeechRecognizer?
    private var request: SFSpeechAudioBufferRecognitionRequest?
    private var task: SFSpeechRecognitionTask?
    private let engine = AVAudioEngine()
    private var isRunning = false

    var onResult: ((String) -> Void)?
    var onError: ((Error) -> Void)?
    var onStateChange: ((Bool) -> Void)?  // true = 开始识别中

    override init() {
        super.init()
    }

    /// 请求权限
    func requestAuthorization() async -> Bool {
        let status = await withCheckedContinuation { (continuation: CheckedContinuation<SFSpeechRecognizerAuthorizationStatus, Never>) in
            SFSpeechRecognizer.requestAuthorization { status in
                continuation.resume(returning: status)
            }
        }
        return status == .authorized
    }

    /// 使用指定语言启动识别
    func start(language: String) async -> Bool {
        guard !isRunning else { return true }

        let authorized = await requestAuthorization()
        guard authorized else {
            onError?(NSError(domain: "SpeechRecognizer", code: -1,
                             userInfo: [NSLocalizedDescriptionKey: "Speech recognition not authorized"]))
            return false
        }

        guard let recognizer = SFSpeechRecognizer(locale: Locale(identifier: language)),
              recognizer.isAvailable else {
            let msg = "Speech recognizer unavailable for \(language)"
            onError?(NSError(domain: "SpeechRecognizer", code: -2,
                             userInfo: [NSLocalizedDescriptionKey: msg]))
            return false
        }

        self.recognizer = recognizer
        recognizer.delegate = self
        recognizer.defaultTaskHint = .dictation

        // 创建新的请求
        request = SFSpeechAudioBufferRecognitionRequest()
        guard let request = request else { return false }
        request.shouldReportPartialResults = true
        request.addsPunctuation = true

        // 获取音频输入
        let inputNode = engine.inputNode
        let format = inputNode.outputFormat(forBus: 0)
        inputNode.installTap(onBus: 0, bufferSize: 1024, format: format) { [weak self] buffer, _ in
            self?.request?.append(buffer)
        }

        do {
            try engine.start()
        } catch {
            onError?(error)
            return false
        }

        // 开始识别任务
        task = recognizer.recognitionTask(with: request) { [weak self] result, error in
            guard let self = self else { return }

            if let error = error {
                DispatchQueue.main.async {
                    self.onError?(error)
                }
                return
            }

            if let result = result {
                // 获取当前最佳转录及未完成的备选
                let text = result.bestTranscription.formattedString
                DispatchQueue.main.async {
                    self.onResult?(text)
                }
            }
        }

        isRunning = true
        onStateChange?(true)
        print("[Speech] Started recognition for \(language)")
        return true
    }

    func stop() -> String? {
        guard isRunning else { return nil }
        isRunning = false

        engine.inputNode.removeTap(onBus: 0)
        engine.stop()

        // 结束识别流
        request?.endAudio()
        task?.finish()

        // 结果已在回调中处理
        request = nil
        task = nil
        recognizer = nil

        onStateChange?(false)
        print("[Speech] Stopped recognition")
        return nil
    }

    func cancel() {
        task?.cancel()
        _ = stop()
    }

    // MARK: - SFSpeechRecognizerDelegate

    func speechRecognizer(_ speechRecognizer: SFSpeechRecognizer,
                          availabilityDidChange available: Bool) {
        print("[Speech] Availability changed: \(available)")
    }
}
