import 'package:electronic_assistant/base/app_base_request.dart';
import 'package:electronic_assistant/data/api/atmob_api.dart';
import 'package:electronic_assistant/data/api/response/talk_query_response.dart';
import 'package:electronic_assistant/data/bean/talks.dart';
import 'package:electronic_assistant/data/repositories/account_repository.dart';
import 'package:electronic_assistant/data/repositories/agenda_repository.dart';
import 'package:electronic_assistant/data/repositories/talk_repository.dart';
import 'package:electronic_assistant/utils/async_util.dart';
import 'package:flutter/cupertino.dart';

import '../../dialog/analyse_status_dialog.dart';
import '../../module/talk/view.dart';
import '../../utils/http_handler.dart';
import '../../utils/notification_util.dart';
import '../api/request/talk_query_request.dart';
import '../api/response/tasks_running_response.dart';
import '../consts/error_code.dart';

class TaskRepository {
  final Set<String> electronicTasks = {};
  final Set<String> _recordSuccessTalkIds = {};
  CancelableFuture? _taskStatusCheckFuture;

  TaskRepository._();

  void stopTask() {
    _taskStatusCheckFuture?.cancel();
  }

  void addTask(String taskId) {
    electronicTasks.add(taskId);
    _startTaskStatusCheck();
  }

  void startUnfinishedTask() {
    debugPrint('开始获取未完成任务==');
    AsyncUtil.retryWithExponentialBackoff(() => _tasksRunning(), 10,
        predicate: (error) {
      if (error is ServerErrorException) {
        return error.code != ErrorCode.errorCodeNoLogin;
      }
      return true;
    }).then((data) {
      List<String>? list = data.taskIds;
      debugPrint('获取未完成任务成功-${list?.length}');
      electronicTasks.clear();
      if (list != null) {
        electronicTasks.addAll(list);
      }
      _startTaskStatusCheck();
    }).catchError((error) {
      debugPrint('获取未完成任务失败');
    });
  }

  void _startTaskStatusCheck() {
    if (electronicTasks.isEmpty) {
      return;
    }
    debugPrint('开始检查任务状态');
    if (_taskStatusCheckFuture != null) {
      _taskStatusCheckFuture?.cancel();
    }
    _taskStatusCheckFuture = AsyncUtil.retry(
        () => _checkAllTaskStatusFinished(), const Duration(seconds: 3),
        predicate: (error) {
      if (error is ServerErrorException) {
        return error.code != ErrorCode.errorCodeNoLogin;
      }
      return true;
    });
  }

  Future<void> _checkAllTaskStatusFinished() {
    String taskIds = electronicTasks.join(',');
    return atmobApi
        .talkQuery(TalkQueryRequest(taskIds))
        .then(HttpHandler.handle(true))
        .then((response) => _dealTaskStatus(response))
        .then((data) {
      if (electronicTasks.isEmpty) {
        return;
      } else {
        throw Exception('task not finished');
      }
    });
  }

  Future<void> _dealTaskStatus(TalkQueryResponse response) {
    response.talks?.forEach((element) {
      if (element.status.value == TalkStatus.analysing ||
          element.status.value == TalkStatus.waitAnalysis) {
        talkRepository.renovateTalkData(element);
      } else if (element.status.value == TalkStatus.analysisSuccess ||
          element.status.value == TalkStatus.analysisFail) {
        electronicTasks.remove(element.taskId);
        if (!_recordSuccessTalkIds.contains(element.id)) {
          _recordSuccessTalkIds.add(element.id);
          _notifyGenerationStatus(element);
        }
      }
    });
    return Future.value();
  }

  void _notifyGenerationStatus(TalkBean element) {
    talkRepository.renovateTalkData(element);
    if (element.status.value == TalkStatus.analysisSuccess) {
      debugPrint('生成成功-${element.id}');
      NotificationUtil.showAnalyseSuccessNotification(element.id);
      showAnalyseSuccessDialog(onViewClick: () {
        TalkPage.start(element);
      });
      accountRepository.refreshUserInfo();
      agendaRepository.requestHomeAgendaData();
    } else if (element.status.value == TalkStatus.analysisFail) {
      debugPrint('生成失败-${element.id}');
      // ToastUtil.showToast('生成失败');
    }
  }

  Future<TasksRunningResponse> _tasksRunning() {
    return atmobApi
        .tasksRunning(AppBaseRequest())
        .then(HttpHandler.handle(true));
  }
}

final taskRepository = TaskRepository._();
