import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class DubbingLib {

  static final DubbingLib _instance = DubbingLib();

  static DubbingLib get instance => _instance;

  static const MethodChannel _channel =
      const MethodChannel('dubbing_lib');

  StreamController _onProgressChange;
  StreamController _onRecordProgressChange;
  StreamController _onDecodeResultChange;

  Stream<int> get progressChange => _onProgressChange.stream;
  Stream<int> get recordProgressChange => _onRecordProgressChange.stream;
  Stream<Map> get decodeResultChange => _onDecodeResultChange.stream;

  /// 路径文件夹地址
  String videoPath;
  String recordPath;
  String recordDecodePath;
  String bgmPath;
  String bgmDecodePath;
  String audioSyncPath;
  String audioSyncDecodePath;
  String videoMixInPath;

  static Future<String> get platformVersion async {
    final String version = await _channel.invokeMethod('getPlatformVersion');
    return version;
  }

  Future<void> init() {
    return _channel.invokeMethod("initSpeechSdk");
  }

  Future<void> setExtraFullScreen() {
    //todo 暂时视频播放时全屏StatusBar bug
    return _channel.invokeMethod("setExtraFullScreen");
  }

  Future<String> downLoadVideo(String videoUrl) {
    return _channel.invokeMethod("downLoadVideo", {"url": videoUrl});
  }

  Future<void> pauseRecordAudio() {
    return _channel.invokeMethod("pauseRecordAudio");
  }

  /// 返回录音文件地址
  Future<String> startRecord(int index, int duration, String fileName) {
    return _channel.invokeMethod("startRecord",
        {"duration": duration, "fileName": fileName, "index": index, "pathAudio": recordPath, "pathAudioDecode": recordDecodePath}
        );
  }

  Future<void> playRecordAudio(String filePath) {
    return _channel.invokeMethod("playRecordAudio", {"fileName": filePath});
  }

  /// 返回合成视频文件地址 这里的bgmPath是已经下载的背景音乐文件地址:
  Future<String> startMixinAudio(String videoId, String bgmUrl, String bgmPath, List<int> endTimeList,
      List<String> decodeAudioPathList, List<int> durationList, String localVideoPath) {
    return _channel.invokeMethod("startMixinAudio", {"videoId": videoId, "bgmUrl": bgmUrl,
      "endTimeList": endTimeList, "audioDecodePaths": decodeAudioPathList, "durationList": durationList, "videoPath": localVideoPath,
      "bgmPath": bgmPath, "pathBgmDecode": bgmDecodePath, "pathBgmRecordSync": audioSyncPath, "pathBgmRecordDecodeSync": audioSyncDecodePath, "pathVideoMixin": videoMixInPath});
  }

  Future<void> cleanAudioData(String videoId) {
    return _channel.invokeMethod("cleanAudioData", {"videoId": videoId, "pathAudio": recordPath, "pathAudioDecode": recordDecodePath});
  }

  /// 初始化路径
  void initPath({@required String videoPath, @required String recordPath, @required String recordDecodePath,
    @required String bgmPath, @required String bgmDecodePath, @required String audioSyncPath, @required String audioSyncDecodePath,
    @required String videoMixInPath}) {
    this.videoPath = videoPath;
    this.recordPath = recordPath;
    this.recordDecodePath = recordDecodePath;
    this.bgmPath = bgmPath;
    this.bgmDecodePath = bgmDecodePath;
    this.audioSyncPath = audioSyncPath;
    this.audioSyncDecodePath = audioSyncDecodePath;
    this. videoMixInPath = videoMixInPath;
  }

  /// 初始化listener 进入录音页面时调用
  void initListener() {
    _onProgressChange = new StreamController<int>.broadcast();
    _onRecordProgressChange = new StreamController<int>.broadcast();
    _onDecodeResultChange = new StreamController<Map>.broadcast();
    _channel.setMethodCallHandler(_onMethodCallHandler);
  }

  /// 1,下载视频进度 2.录音进度 3.解码录音回调 4.语音评测结果
  Future _onMethodCallHandler(MethodCall call) {
    switch (call.method) {
      case "downloadUpdate":
        _onProgressChange.add(call.arguments['progress']);
        break;
      case "recordProgress":
        _onRecordProgressChange.add(call.arguments['progress']);
        break;
      case "decodeResult":
        _onDecodeResultChange.add(call.arguments);
        break;
    }
    return null;
  }

  /// 关闭stream
  void closeStream() {
    _channel.setMethodCallHandler(null);
    _onProgressChange.close();
    _onRecordProgressChange.close();
    _onDecodeResultChange.close();
  }
}
