import 'dart:async';
import 'dart:io';

import 'package:flutter_sound/flutter_sound.dart';
import 'package:get/get.dart';
import 'package:path_provider/path_provider.dart';

import '../../../../common/api/index.dart';
import '../../../../common/models/index.dart';
import '../../../../common/routers/index.dart';
import '../../../../common/services/index.dart';
import '../../../../common/utils/index.dart';
import '../../../apps/meeting/index.dart';
import '../../../apps/process/process_picker/index.dart';
import '../../../common/create_form/index.dart';
import '../../../common/portal/index.dart';
import 'index.dart';

class SpeechAssistantChatController extends GetxController {
  SpeechAssistantChatController();

  final state = SpeechAssistantChatState();

  /// 录音
  FlutterSoundRecorder? _myRecorder = FlutterSoundRecorder();
  bool _mRecorderIsInited = false;
  String _mPath = "";
  final _maxLength = 60; // 最长录音时间60秒
  int _recordSecond = 0;
  StreamSubscription? _mRecordingDataSubscription;
  bool _ttsOpen = false;

  /// 在 onInit() 之后调用 1 帧。这是进入的理想场所
  @override
  void onReady() {
    state.btnTitle = 'im_chat_tools_voice'.tr;
    _loadInitCommandList();
    initTheRecorder();
    _ttsOpen = ProgramCenterService.to.extendParam()['needTTS'] ?? false;
    super.onReady();
  }

  @override
  void onClose() {
    _myRecorder?.closeRecorder();
    _myRecorder = null;
    if (_ttsOpen) {
      FlutterTTSHelper.instance.stop();
    }
    super.onClose();
  }

  /// 初始化录音功能
  Future<void> initTheRecorder() async {
    // 检查录音权限
    var isPermission = await O2Utils.microphonePermission();
    if (!isPermission) {
      OLogger.e('没有权限，无法录音');
      Loading.showError('im_chat_error_need_record_permission'.tr);
      return;
    }
    // 开启录音工具
    await _myRecorder?.openRecorder();
    //设置订阅计时器
    await _myRecorder
        ?.setSubscriptionDuration(const Duration(milliseconds: 10));
    // 初始化录音路径
    var tempDir = await getTemporaryDirectory();
    _mPath = '${tempDir.path}/o2_speech_assistant.pcm'; // pcm 格式录音 baidu 语音需要
    _mRecorderIsInited = true;
  }

  /// 开始录音
  Future<void> startRecorder() async {
    if (!_mRecorderIsInited) {
      Loading.showError('im_chat_error_record_not_init'.tr);
      return;
    }
    if (state.status.value != SpeechStatus.idle) {
      OLogger.i('正在数据加载中！');
      return;
    }
    if (_ttsOpen) {
      FlutterTTSHelper.instance.stop();
    }
    state.status.value = SpeechStatus.speaking;

    // 初始化数字
    _recordSecond = 0;
    // 初始化文件
    var outputFile = File(_mPath);
    if (outputFile.existsSync()) {
      await outputFile.delete();
    }

    _myRecorder?.startRecorder(
      toFile: _mPath,
      codec: Codec.pcm16,
    );

    /// 监听录音
    _mRecordingDataSubscription = _myRecorder?.onProgress?.listen((e) {
      final date = DateTime.fromMillisecondsSinceEpoch(
          e.duration.inMilliseconds,
          isUtc: true);
      // var txt = date.hms();
      _recordSecond = date.second; //
      //设置了最大录音时长
      if (date.second >= _maxLength) {
        stopRecorder();
        return;
      }
      //更新录音时长
      // state.btnTitle = txt;
    });
  }

  Future<void> stopRecorder() async {
    if (state.status.value != SpeechStatus.speaking) {
      OLogger.i('正在数据加载中！');
      return;
    }
    await _myRecorder!.stopRecorder();
    _cancelRecorderSubscriptions();
    OLogger.d("record time $_recordSecond");
    if (_recordSecond < 1) {
      Loading.showError('im_chat_error_record_time_too_short'.tr);
      state.status.value = SpeechStatus.idle;
    } else {
      _sendFileToServer();
    }
    OLogger.d('stop end ......');
  }

  /// 取消录音监听
  void _cancelRecorderSubscriptions() {
    if (_mRecordingDataSubscription != null) {
      _mRecordingDataSubscription?.cancel();
      _mRecordingDataSubscription = null;
    }
  }

  /// 发送到后台
  Future<void> _sendFileToServer() async {
    state.status.value = SpeechStatus.thinking;
    File file = File(_mPath);
    final ids = await FileAssembleService.to.uploadFileForSpeechAssistant(file);
    if (ids != null) {
      OLogger.d('文件 id ${ids.id}');
      _thinking(fileId: ids.id);
    } else {
      state.status.value = SpeechStatus.idle;
      OLogger.e('上传文件失败！');
    }
  }

  /// 随机命令列表，初始化展示用
  Future<void> _loadInitCommandList() async {
    Map<String, dynamic> body = <String, dynamic>{};
    body['type'] = 'init';
    final result =
        await ProgramCenterService.to.executeScript(ProgramCenterService.to.speechScript(), body);
    var list = result == null ? [] : result as List;
    state.initCommandList.addAll(list.map((e) => e as String).toList());
  }

  Future<void> _thinking({String? fileId, String? inputText}) async {
    Map<String, dynamic> body = <String, dynamic>{};
    body['personId'] = O2ApiManager.instance.o2User?.id ?? '';
    if (fileId != null && fileId.isNotEmpty) {
      body['speechFileId'] = fileId;
    } else if (inputText != null && inputText.isNotEmpty) {
      body['inputText'] = inputText;
    }
    final result =
        await ProgramCenterService.to.executeScript(ProgramCenterService.to.speechScript(), body);
    if (result != null) {
      ImSpeechAssistantResponse res =
          ImSpeechAssistantResponse.fromJson(result);
      if (res.msg == null || res.msg!.isEmpty == true) {
        _answerMsg(res.err!);
      } else {
        res.createTime = DateTime.now();
        res.side = ImSpeechAssistantResponse.rightSide;
        state.chatList.add(res);
        final command = res.command;
        if (command == null) {
          _answerMsg('im_chat_speech_assistant_msg_unknown_command'.tr);
        } else {
          final answer = command.answer ?? '';
          final processId = command.processId ?? '';
          final portalId = command.portalId ?? '';
          final commandName = command.name ?? '';
          if (answer.isNotEmpty) {
            // 有答案 直接回复
            _answerMsg(answer);
          } else if (processId.isNotEmpty) {
            // 有流程 就启动流程工作
            _answerMsg(
                'im_chat_speech_assistant_msg_open_start_level_process'.tr);
            _startWorkByProcess(processId);
          } else if (portalId.isNotEmpty) {
            _answerMsg('im_chat_speech_assistant_msg_open_app'
                .trArgs([res.msg ?? '']));
            _openPortal(portalId, command.pageId);
          } else if (commandName.isNotEmpty) {
            // 有命令执行对应的命令
            _doCommand(commandName);
          } else if (res.err != null && res.err!.isNotEmpty == true) {
            // 有错误，比如不认识的命令 直接回复
            _answerMsg(res.err!);
          } else {
            _answerMsg('im_chat_speech_assistant_msg_unknown_command'.tr);
          }
        }
      }
    } else {
      Loading.toast('request_error'.tr);
    }
    state.status.value = SpeechStatus.idle;
    OLogger.d('_thinking 完成！');
  }

  // 执行特殊命令，一般是打开某个应用
  _doCommand(String command) {
    switch (command) {
      case 'task':
        _answerMsg('im_chat_speech_assistant_msg_open_app'
            .trArgs([O2NativeAppEnum.task.name]));
        Get.toNamed(O2OARoutes.appTask);
        break;
      case 'taskCompleted':
        _answerMsg('im_chat_speech_assistant_msg_open_app'
            .trArgs([O2NativeAppEnum.taskcompleted.name]));
        Get.toNamed(O2OARoutes.appTaskcompleted);
        break;
      case 'read':
        _answerMsg('im_chat_speech_assistant_msg_open_app'
            .trArgs([O2NativeAppEnum.read.name]));
        Get.toNamed(O2OARoutes.appRead);
        break;
      case 'readCompleted':
        _answerMsg('im_chat_speech_assistant_msg_open_app'
            .trArgs([O2NativeAppEnum.readcompleted.name]));
        Get.toNamed(O2OARoutes.appReadcompleted);
        break;
      case 'startProcess':
        _answerMsg('im_chat_speech_assistant_msg_open_start_process'.tr);
        // 打开启动流程工具
        _startProcess();
        break;
      case 'meeting':
        _answerMsg('im_chat_speech_assistant_msg_open_app'
            .trArgs([O2NativeAppEnum.meeting.name]));
        // 打开会议管理
        MeetingPage.startMeetingApp();
        break;
      case 'createMeeting':
        _answerMsg('im_chat_speech_assistant_msg_open_meeting_create'.tr);
        // 打开创建会议
        MeetingPage.startMeetingApp(openCreate: true);
        break;
      case 'attendance':
        _answerMsg('im_chat_speech_assistant_msg_open_app'
            .trArgs([O2NativeAppEnum.attendance.name]));
        // 打开考勤打卡
        FastCheckInService.instance.stop(); // 进入考勤 先关闭极速打卡
        Get.toNamed(O2OARoutes.appAttendance);
        break;
      case 'bbs': // 论坛
        _answerMsg('im_chat_speech_assistant_msg_open_app'
            .trArgs([O2NativeAppEnum.bbs.name]));
        Get.toNamed(O2OARoutes.appBBS);
        break;
      case 'yunpan': // 网盘
        _answerMsg('im_chat_speech_assistant_msg_open_app'
            .trArgs([O2NativeAppEnum.yunpan.name]));
        Get.toNamed(FileAssembleService.to.isV3()
            ? O2OARoutes.appCloudDiskV3
            : O2OARoutes.appYunpan);
        break;
      case 'cms': // 信息中心
        _answerMsg('im_chat_speech_assistant_msg_open_app'
            .trArgs([O2NativeAppEnum.cms.name]));
        Get.toNamed(O2OARoutes.appCms);
        break;
      case 'calendar': // 信息中心
        _answerMsg('im_chat_speech_assistant_msg_open_app'
            .trArgs([O2NativeAppEnum.calendar.name]));
        Get.toNamed(O2OARoutes.appCalendar);
        break;
      case 'mindMap': // 信息中心
        _answerMsg('im_chat_speech_assistant_msg_open_app'
            .trArgs([O2NativeAppEnum.mindMap.name]));
        Get.toNamed(O2OARoutes.appMindMap);
        break;
      default:
        _answerMsg('im_chat_speech_assistant_msg_unknown_command'.tr);
        break;
    }
  }

  /// 回复信息
  _answerMsg(String msg) {
    state.chatList.add(ImSpeechAssistantResponse(
        msg: msg,
        side: ImSpeechAssistantResponse.leftSide,
        createTime: DateTime.now()));
    if (_ttsOpen) {
      FlutterTTSHelper.instance.speak(msg);
    }
  }

  /// 新建工作
  Future<void> _startProcess() async {
    // 选择启动流程
    var result = await ProcessPickerPage.startPicker(ProcessPickerMode.process);
    if (result != null && result is ProcessData) {
      CreateFormPage.startProcess(true, process: result);
    }
  }

  /// 启动流程，创建工作
  /// 先查询请假流程对象，然后启动流程
  Future<void> _startWorkByProcess(String processId) async {
    if (processId.isEmpty) {
      _answerMsg('im_chat_speech_assistant_msg_not_found_level_process'.tr);
      return;
    }
    final processInfo = await ProcessSurfaceService.to.getProcess(processId);
    if (processInfo == null) {
      _answerMsg('im_chat_speech_assistant_msg_not_found_level_process'.tr);
      return;
    }
    CreateFormPage.startProcess(true, process: processInfo);
  }

  /// 打开门户
  void _openPortal(String portalId, String? pageId) {
    PortalPage.open(portalId, pageId: pageId);
  }
}
