import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/lab/manager/interfaces/task.dart';
import 'package:flyinsono/lab/mock_data/mock_rpc.dart';
import 'package:fis_common/event/event_type.dart';
import 'package:flyinsono/lab/pages/lab_task/index.dart';
import 'package:flyinsono/rpc.dart';
import 'package:get/get.dart';
import 'entities/export_data.dart';
import 'entities/process_arg.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:fis_common/logger/logger.dart';
import 'package:flyinsono/lab/pages/lab_task/controller.dart' as c;
import 'package:fis_common/env/env.dart';

class ShellIOTaskManager {
  final processChange = FEventHandler<ExportProcessArg>();
  String taskId = "";
  VTaskStatus status = VTaskStatus.Unhandled;
  DateTime startTime = DateTime(2024);
  DateTime? endTime;
  List<ShellIOBaseData> datas = [];
  String taskName = '';

  Future<List<UDiskDriveInfoDTO>> getExternalStorageList() async {
    List<UDiskDriveInfoDTO> result = [];
    try {
      result = await rpc.platform.getUDiskDriveInfo();
    } catch (e) {
      logger.e("ImportExportDataManager getExternalStorageList ex:", e);
    }
    return result;
  }

  List<TaskDetail> getLocalTasks(String currentSelectedTaskId) {
    List<TaskDetail> tasks = [];
    if (currentSelectedTaskId != taskId) {
      print(
          "getLocalTasks failed,taskId:$taskId,target taskId:$currentSelectedTaskId");
      return tasks;
    }
    for (var data in datas) {
      VTaskStatus cStatus = VTaskStatus.Unhandled;
      if (data.progress > 0 && data.progress < 1) {
        cStatus = VTaskStatus.Processing;
      } else if (data.progress == 1) {
        cStatus = VTaskStatus.Completed;
      }
      String content = data.id;
      if (data is ExportDataItem) {
        content = data.typeName;
      }
      double rate = data.progress * 100;
      tasks.add(
        TaskDetail(
          name: data.name,
          description: content,
          rate: rate,
          status: cStatus,
          result: rate == 100,
        ),
      );
    }

    return tasks;
  }

  Future<void> onProcessChange(Object sender, ExportProcessArg e) async {
    var data = datas.firstWhereOrNull((element) => element.id == e.id);
    if (data != null) {
      data.progress = e.progress;
      bool isCancel = e.exportState == 5;
      if (isCancel) {
        datas.remove(data);
      }
      print("${data.name}进度更新：${e.progress}");
      if (data.progress == 1) {
        await _endTaskToServer(data.id, isCancel: isCancel);
      }
      if (!datas.any((element) => element.progress != 1)) {
        print("状态更新：Completed");
        status = VTaskStatus.Completed;
        endTime = DateTime.now();
        Get.find<IServerTaskManager>().onTaskCompleted(
          TaskCompletedNotification(
            taskName: taskName,
            taskCode: taskId,
          ),
        );
      }
    }
  }

  void cancelTask() {
    for (ShellIOBaseData data in datas) {
      if (data.progress != 1) {
        _updateResearchProjectTask(data.id, VTaskStatus.Canceled);
      }
    }
  }

  Future<void> _endTaskToServer(String id, {bool isCancel = false}) async {
    return _updateResearchProjectTask(
        id, isCancel ? VTaskStatus.Canceled : VTaskStatus.Completed);
  }

  Future<void> _updateResearchProjectTask(String id, VTaskStatus status) async {
    rpc.researchEdition.updateResearchProjectTaskAsync(
      UpdateResearchProjectTaskRequest(
        token: Store.user.token,
        id: id,
        status: status,
        rate: 100,
        result: true,
        mainTaskCode: taskId,
      ),
    );
  }
}
