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

import 'package:electronic_assistant/base/base_controller.dart';
import 'package:electronic_assistant/data/repositories/task_repository.dart';
import 'package:electronic_assistant/module/chat/view.dart';
import 'package:electronic_assistant/module/talk/summary/view.dart';
import 'package:electronic_assistant/module/talk/todo/view.dart';
import 'package:electronic_assistant/resource/assets.gen.dart';
import 'package:electronic_assistant/resource/colors.gen.dart';
import 'package:electronic_assistant/resource/string.gen.dart';
import 'package:electronic_assistant/utils/error_handler.dart';
import 'package:electronic_assistant/utils/expand.dart';
import 'package:electronic_assistant/utils/mmkv_util.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import '../../data/bean/agenda_list_all_bean.dart';
import '../../data/bean/talks.dart';
import '../../data/repositories/agenda_repository.dart';
import '../../data/repositories/talk_repository.dart';
import '../../dialog/alert_dialog.dart';
import '../../utils/toast_util.dart';
import '../record/controller.dart';
import 'original/view.dart';
import 'package:just_audio/just_audio.dart';

class TalkController extends BaseController {
  final String uploadNoPrompts = "UPLOAD_NO_PROMPTS";

  final Rxn<TalkBean> talkBean = Rxn();

  final isShowElectricLow = false.obs;

  bool isAudioLoading = false;

  final double sliderMax = 1;

  bool? audioFileIsExist;

  bool? isUploadedFile;

  Rxn<bool> isUploading = Rxn();

  final isAudioPlaying = false.obs;

  final audioProgressValue = 0.0.obs;

  final audioDuration = Duration.zero.obs;

  final agendaAllList = <AgendaListAllBean>[].obs;

  final List<String> tabBeans = [
    StringName.talkTabSummary.tr,
    StringName.talkTabMyTask.tr,
    StringName.talkTabOriginal.tr
  ];

  final _audioPlayer = AudioPlayer();

  StreamSubscription? _talkBeanListener;

  final pages = [const SummaryView(), const TodoView(), const OriginalView()];

  @override
  void onReady() {
    super.onReady();
    _initAudioPlayer();
    _initListener();
    _getArguments();
  }

  void _initAudioPlayer() {
    _audioPlayer.playerStateStream.listen((playerState) {
      if (playerState.processingState == ProcessingState.loading ||
          playerState.processingState == ProcessingState.buffering) {
        isAudioLoading = true;
        debugPrint('音频load = true');
      } else {
        debugPrint('音频load = false');
        isAudioLoading = false;
        if (playerState.processingState == ProcessingState.completed) {
          _audioPlayer.stop();
          _audioPlayer.seek(Duration.zero);
          isAudioPlaying.value = false;
          debugPrint('音频 播放结束了');
        }
      }
      isAudioPlaying.value = playerState.playing;
    }, onError: (Object e, StackTrace stackTrace) {
      debugPrint('音频加载异常 == $e');
    });

    _audioPlayer.durationStream.listen((duration) {
      if (duration != null) {
        debugPrint('音频总播放时长 == ${duration.inMilliseconds}');
        audioDuration.value = duration;
      }
    });

    _audioPlayer.positionStream.listen((position) {
      if (audioDuration.value.inMilliseconds > 0) {
        audioProgressValue.value =
            (position.inMilliseconds / audioDuration.value.inMilliseconds)
                .clamp(0.0, sliderMax);
      }
    });
  }

  void _initListener() {
    _talkBeanListener = talkBean.listen((bean) {
      _dealTalkUpdate(bean);
    });
  }

  void _dealTalkUpdate(TalkBean? bean) async {
    String? id = talkBean.value?.id;
    if (id == null) {
      return;
    }
    if (talkRepository.isUploadingTalk(id) &&
        talkBean.value?.status.value == TalkStatus.notAnalysis) {
      isUploading.value = true;
    } else {
      isUploading.value = false;
    }
    try {
      Uri uri;
      if (bean?.isExample == true && bean?.audioUrl != null) {
        uri = Uri.parse(bean!.audioUrl!);
      } else {
        File file = await RecordController.getRecordFile(id);
        uri = file.uri;
      }
      await _audioPlayer.setAudioSource(AudioSource.uri(uri));
      audioFileIsExist = true;
    } catch (e) {
      audioFileIsExist = false;
      debugPrint('音频设置异常 == $e');
    }
  }

  void _getArguments() {
    if (Get.arguments is TalkBean) {
      talkBean.value = Get.arguments as TalkBean;
    }
  }

  void updateProgress(double value) {
    final newPosition = Duration(
        milliseconds: (value * audioDuration.value.inMilliseconds).toInt());
    _audioPlayer.seek(newPosition);
  }

  void clickPlayAudio() {
    if (audioFileIsExist != true) {
      ToastUtil.showToast(StringName.talkFileNotFind.tr);
      return;
    }
    if (isAudioLoading) {
      ToastUtil.showToast(StringName.talkAudioLoading.tr);
      return;
    }
    if (_audioPlayer.playing) {
      _audioPlayer.pause();
      isAudioPlaying.value = false;
    } else {
      _audioPlayer.play();
      isAudioPlaying.value = true;
    }
  }

  void _checkFileSizeAndNet() async {
    String? id = talkBean.value?.id;
    if (id == null) {
      return;
    }
    File file = await RecordController.getRecordFile(id);
    if (!file.existsSync()) {
      ToastUtil.showToast(StringName.talkUploadFileNotExist.tr);
      return;
    }
    bool isCheckRemind = KVUtil.getBool(uploadNoPrompts, false);
    if (isCheckRemind) {
      _requestAnalyze(file);
      return;
    }
    //如果文件大小低于250MB 不弹窗提醒
    if (file.lengthSync() < 250 * 1024 * 1024) {
      _requestAnalyze(file);
      return;
    }

    final List<ConnectivityResult> connectivityResult =
        await (Connectivity().checkConnectivity());
    if (connectivityResult.contains(ConnectivityResult.wifi)) {
      _requestAnalyze(file);
    } else {
      _showTrafficRemindDialog(file.lengthSync().toReadableSize(),
          confirmOnTap: (isCheckRemind) {
        if (isCheckRemind) {
          KVUtil.putBool(uploadNoPrompts, true);
        }
        _requestAnalyze(file);
      });
    }
  }

  void _showTrafficRemindDialog(String holderTxt,
      {void Function(bool isCheckRemind)? confirmOnTap}) {
    final remindTrafficConsume = false.obs;

    Widget getSelectIcon() {
      return Obx(() {
        return remindTrafficConsume.value
            ? Assets.images.iconSelectTrue.image()
            : Assets.images.iconSelectFalse.image();
      });
    }

    Assets.images.iconSelectTrue.image();

    EAAlertDialog.show(
        contentWidget: Column(
          children: [
            Text(
              StringName.talkTrafficRemindTitle.tr
                  .replacePlaceholders([holderTxt]),
              style:
                  TextStyle(fontSize: 15.sp, color: ColorName.primaryTextColor),
            ),
            SizedBox(height: 8.h),
            GestureDetector(
              onTap: () {
                remindTrafficConsume.value = !remindTrafficConsume.value;
              },
              child: IntrinsicWidth(
                child: Row(
                  children: [
                    SizedBox(width: 20.w, height: 20.w, child: getSelectIcon()),
                    SizedBox(width: 5.w),
                    Text(
                      StringName.talkTrafficRemindTips.tr,
                      style: TextStyle(
                          fontSize: 15.sp, color: ColorName.tertiaryTextColor),
                    )
                  ],
                ),
              ),
            )
          ],
        ),
        cancelText: StringName.cancel.tr,
        confirmText: StringName.sure.tr,
        confirmOnTap: () {
          confirmOnTap?.call(remindTrafficConsume.value);
        });
  }

  void checkCanAnalyze() async {
    String? id = talkBean.value?.id;
    double? duration = talkBean.value?.duration;
    if (id == null || duration == null) {
      return;
    }
    talkRepository.checkElectric(duration).then((data) {
      if (data.enough) {
        //检查网络以及文件大小
        _checkFileSizeAndNet();
      } else {
        ToastUtil.showToast(StringName.talkAnalyseLowToast.tr);
        isShowElectricLow.value = true;
      }
    }).catchError((error) {
      ToastUtil.showToast(error);
    });
  }

  void _requestAnalyze(File file) {
    String? talkId = talkBean.value?.id;
    double? duration = talkBean.value?.duration;

    if (talkId == null || duration == null || isUploadedFile == true) {
      return;
    }
    isUploading.value = true;
    talkRepository.uploadTalkFile(talkId, duration, file).then((taskId) {
      isUploadedFile = true;
      taskRepository.addTask(taskId);
    }).catchError((error) {
      isUploading.value = false;
      ErrorHandler.toastError(error);
    });
  }

  void goElectricStore() {
    //TODO 跳转至商店页
  }

  void refreshAgendaAllData() {
    String? id = talkBean.value?.id;
    if (id == null || agendaAllList.isNotEmpty) {
      return;
    }
    agendaRepository.agendaListAll(id).then((agenda) {
      if (agenda.list != null) {
        agendaAllList.value = agenda.list!;
      }
    });
  }

  void clickAIAnalysis() {
    if (talkBean.value != null) {
      ChatPage.startByTalk(talkBean.value!);
    }
  }

  @override
  void onClose() {
    super.onClose();
    _talkBeanListener?.cancel();
    _audioPlayer.dispose();
  }
}
