import 'dart:async';

import 'package:flutter/services.dart';

/// Dart 侧对 iOS SpeechEnginePlugin 的包装。
///
/// 所有方法都 forwards 到 MethodChannel；事件流通过 [events] 暴露原始字典，
/// 上层 VoiceChatController 负责解析为状态变化。
class SpeechEnginePlugin {
  static const MethodChannel _method =
      MethodChannel('avatar_flutter_app/speech_engine');
  static const EventChannel _event =
      EventChannel('avatar_flutter_app/speech_events');

  Stream<Map<String, dynamic>>? _events;

  /// 事件流：每个事件都是 `{type: ..., ...payload}` 形式的 Map。
  /// type 取值：engine_start / engine_stop / engine_error /
  ///            asr_partial / asr_end / chat_partial / chat_end /
  ///            mouth_value / raw
  Stream<Map<String, dynamic>> get events =>
      _events ??= _event.receiveBroadcastStream().map(_castMap);

  static Map<String, dynamic> _castMap(dynamic raw) {
    if (raw is Map) {
      return raw.map((k, v) => MapEntry(k.toString(), v));
    }
    return {'type': 'raw', 'payload': raw?.toString() ?? ''};
  }

  Future<void> init({
    required String appId,
    required String appKey,
    required String token,
    required String dialogId,
    required String uid,
    required String address,
    required String uri,
    String botName = '豆包',
    String aecModelPath = '',
  }) async {
    await _method.invokeMethod('init', {
      'appId': appId,
      'appKey': appKey,
      'token': token,
      'dialogId': dialogId,
      'uid': uid,
      'address': address,
      'uri': uri,
      'botName': botName,
      'aecModelPath': aecModelPath,
    });
  }

  Future<void> start() => _method.invokeMethod('start');
  Future<void> startTalking() => _method.invokeMethod('startTalking');
  Future<void> finishTalking() => _method.invokeMethod('finishTalking');
  Future<void> pauseTalking() => _method.invokeMethod('pauseTalking');
  Future<void> resumeTalking() => _method.invokeMethod('resumeTalking');
  Future<void> cancelCurrentDialog() => _method.invokeMethod('cancelCurrentDialog');
  Future<void> sayHello(String content) =>
      _method.invokeMethod('sayHello', {'content': content});
  Future<void> stop() => _method.invokeMethod('stop');
  Future<void> destroy() => _method.invokeMethod('destroy');
}
