import 'dart:async';

import 'package:flyinsono/architecture/utils/prompt_box.dart';
import 'package:flyinsono/lab/architecture/task_center.dart';
import 'package:flyinsono/lab/color/lab_colors.dart';
import 'package:flyinsono/lab/components/classify_data_selector/classify_data_selector.dart';
import 'package:flyinsono/lab/components/lab_dialog.dart';
import 'package:flyinsono/lab/manager/interfaces/analysis.dart';
import 'package:flyinsono/lab/manager/interfaces/project.dart';
import 'package:flyinsono/lab/manager/interfaces/task.dart';
import 'package:flyinsono/lab/manager/page_manager.dart';
import 'package:flyinsono/lab/mixin/tab_hook_mixin.dart';
import 'package:flyinsono/lab/pages/lab_data/controller.dart';
import 'package:flyinsono/lab/router/lab_route_names.dart';
import 'package:flyinsono/managers/interfaces/entities/task_info.dart';
import 'package:flyinsono/managers/interfaces/remedical.dart';
import 'package:flyinsono/pages/schedule/schedule_notification/schedule_notification_controller.dart';
import 'package:get/get.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:intl/intl.dart';
import 'index.dart';
import 'package:fis_common/index.dart';

class LabTaskController extends GetxController with TabHookMixin {
  LabTaskController({required this.tabHashCode});

  @override
  final int tabHashCode;

  static const taskPageId = "task_page_id"; // 页面id

  static const headerPanelId = "header_panel_id"; // 头部面板

  static const taskListId = "task_list_id"; // 任务列表

  static const taskDetailListId = "task_detail_list_id"; // 任务详情

  final state = LabTaskState();

  final serverTaskManager = Get.find<IServerTaskManager>();

  /// 项目接口
  final projectManager = Get.find<IProjectManager>();

  // 任务数据总览
  List<ClassifyData<TaskBaseDTO>> taskStatusClassifyData = [];
  //任务分类（进行中、已完成）
  int selectedClassifyIndex = 0;
  //分类中选中的位置
  int selectedTaskIndex = 0;

  // 任务详情列表（deepcopy）
  List<TaskDetail> taskDetailList = [];

  // 当前不存在任何任务
  bool noProcessingTask = false;

  ClassifyData<TaskBaseDTO> get selectedClassify =>
      taskStatusClassifyData.isNotEmpty
          ? taskStatusClassifyData[selectedClassifyIndex]
          : ClassifyData<TaskBaseDTO>(
              classifyName: "",
              data: [],
            );

  ///当前选中的任务
  TaskBaseDTO? get currentSelectedTask => selectedClassify.data.isNotEmpty
      ? selectedClassify.data[selectedTaskIndex]
      : null;

  // 轮询定时器（用于获取当前选中的任务详情进度）
  Timer? timer;

  TaskInfo currentTaskInfo = TaskInfo(
      complateCount: 0,
      elapsedTime: '',
      startTime: '',
      title: '',
      totalCount: 0,
      patientCode: "");

  void onTaskClick(int classifyIndex, int itemIndex) {
    selectedClassifyIndex = classifyIndex;
    selectedTaskIndex = itemIndex;
    _updateTaskDetailList();
    if (currentSelectedTask?.status == VTaskStatus.Processing ||
        currentSelectedTask?.status == VTaskStatus.Unhandled) {
      startUpdateTimer();
    }
    update([taskListId]);
  }

  // 开启定时器
  void startUpdateTimer() {
    if (timer != null) {
      return;
    }
    timer = Timer.periodic(
      Duration(milliseconds: 1000),
      (timer) {
        print("定时器执行 $tabHashCode");

        ///如果是未完成的状态才需要更新状态
        if (currentTaskInfo.status.index < VTaskStatus.Completed.index) {
          _updateTaskDetailList();
        } else {
          updateTaskList();
          cancelTimer();
        }
      },
    );
  }

  // 销毁定时器
  void cancelTimer() {
    timer?.cancel();
    timer = null;
  }

  /// 更新任务列表总览
  void updateTaskList() async {
    List<TaskBaseDTO> processingTasks = localTaskCenter.getTaskList();
    for (int i = 0; i < processingTasks.length; i++) {
      if ([VTaskStatus.Completed, VTaskStatus.Canceled]
          .contains(processingTasks[i].status)) {
        processingTasks.removeAt(i);
      }
    }
    List<TaskBaseDTO> serverProjects =
        await serverTaskManager.getTaskList(status: VTaskStatus.Processing);

    ///若Server任务和本地任务有相同的，以本地任务为准
    serverProjects = serverProjects
        .where((element) => !processingTasks.any((e) => e.code == element.code))
        .toList();
    processingTasks.addAll(serverProjects);
    processingTasks = updateTaskName(processingTasks);
    processingTasks.sort((a, b) {
      // 比较两个TaskBaseDTO对象的createTime属性
      if (a.createTime == null && b.createTime == null) {
        return 0; // 都是null，视为相等
      } else if (a.createTime == null) {
        return 1; // null的排在后面
      } else if (b.createTime == null) {
        return -1; // null的排在后面
      } else {
        return b.createTime!.compareTo(a.createTime!); // 按照时间降序排列，最近的时间排在最前面
      }
    });
    List<TaskBaseDTO> completeTasks =
        await serverTaskManager.getTaskList(status: VTaskStatus.Completed);
    completeTasks = updateTaskName(completeTasks);
    taskStatusClassifyData = [
      ClassifyData(
          classifyName: "进行中（${processingTasks.length}）",
          data: processingTasks),
      ClassifyData(
          classifyName: "已完成（${completeTasks.length}）", data: completeTasks),
    ];
    _updateTaskDetailList();
    update([taskListId]);
    if (processingTasks.isEmpty) {
      noProcessingTask = true;
      update([taskPageId]);
    }
  }

  List<TaskBaseDTO> updateTaskName(List<TaskBaseDTO> sourceTasks) {
    for (TaskBaseDTO p in sourceTasks) {
      if (p.taskName.isNullOrEmpty) {
        p.taskName = _getTaskNameByTaskType(p.taskType);
        var createTime = p.createTime?.toLocal();
        if (createTime != null) {
          DateFormat formatter = DateFormat('yyyy-MM-dd-HH:mm');
          String formattedDate = formatter.format(createTime);
          p.taskName = "${p.taskName}-$formattedDate";
        }
      }
    }
    return sourceTasks;
  }

  // 查看已完成的任务详情
  Future<void> viewTaskDetail(TaskDetail task, String? patientCode) async {
    print("查看任务详情");
    String taskCode = task.taskCode ?? '';
    TaskDTO? taskInfo =
        await Get.find<IServerTaskManager>().getTaskDetail(taskCode);
    if (taskInfo == null) {
      PromptBox.toast("获取任务失败");
      return;
    }
    var remedicalCode = taskInfo.businessCode ?? '';
    RemedicalInfoDTO imageInfo =
        await Get.find<IRemedicalManager>().findRemedicalByCode(remedicalCode);

    String recordCode = imageInfo.recordCode ?? '';
    String projectCode = imageInfo.projectCode ?? '';
    PageCollection<ResearchProjectDataDTO>? researchProjectData =
        await projectManager.getResearchProjectDataPagesAsync(
      projectCode: projectCode,
      keyWord: "",
      pageSize: 1,
      pageIndex: 1,
      sort: 0,
    );
    print("recordCode:$recordCode");
    PageManager.ins.openTab(
      LabRouteNames.Data,
      args: LabDataActiveArguments(
        patientCode: patientCode ?? '',
        projectCode: projectCode,
      ),
    );
    // PageManager.ins.openTab(
    //   LabRouteNames.Image,
    //   args: LabImageActiveArguments(
    //     patient: selectedPatient,
    //     record: selectedRecord,
    //     images: imageList,
    //     selectedImageIndex: index,
    //     patientType: patientType,
    //   ),
    // );
  }

  @override
  void onSleep() {
    cancelTimer();
    serverTaskManager.onReceiveNotification
        .removeListener(onReceiveNotification);
  }

  @override
  void onActive(arguments) {
    startUpdateTimer();

    updateTaskList();
  }

  /// 在 widget 内存中分配后立即调用。
  @override
  void onInit() {
    super.onInit();
  }

  /// 在 onInit() 之后调用 1 帧。这是进入的理想场所
  @override
  void onReady() {
    super.onReady();
    startUpdateTimer();
    updateTaskList();
    serverTaskManager.onReceiveNotification.addListener(onReceiveNotification);
  }

  /// 在 [onDelete] 方法之前调用。
  @override
  void onClose() {
    super.onClose();
    cancelTimer();

    serverTaskManager.onReceiveNotification
        .removeListener(onReceiveNotification);
  }

  /// dispose 释放内存
  @override
  void dispose() {
    super.dispose();
    cancelTimer();
  }

  Future<void> _updateTaskDetailList() async {
    String currentSelectedTaskId = currentSelectedTask?.code ?? "";
    if (currentSelectedTaskId.isEmpty) {
      return;
    }
    List<TaskDetail> localTasks =
        localTaskCenter.getLocalTasks(currentSelectedTaskId);
    if (localTasks.isNotEmpty) {
      taskDetailList = localTasks;
      currentTaskInfo = localTaskCenter.getTaskInfo(currentSelectedTaskId)!;
      if ([VTaskStatus.Completed, VTaskStatus.Canceled]
          .contains(currentTaskInfo.status)) {
        var targetTask = localTasks
            .firstWhereOrNull((element) => element.id == currentSelectedTaskId);
        if (targetTask != null) {
          localTasks.remove(targetTask);
        }
        taskDetailList = localTasks;
        updateTaskList();
      }
      if (localTasks.isNotEmpty) {
        noProcessingTask = false;
      }
    }
    if (localTasks.isEmpty) {
      MainTaskDTO? serverTaskInfo = await Get.find<IServerTaskManager>()
          .getMainTaskDetailAsync(currentSelectedTaskId);
      if (serverTaskInfo != null) {
        taskDetailList = [];
        for (TaskDetail task in serverTaskInfo.taskDetailList ?? []) {
          if (task.name.isNullOrEmpty) {
            task.name = task.taskCode;
          }
          if (task.description.isNullOrEmpty) {
            task.description =
                task.rate.toStringAsFixed(2).replaceAll(RegExp(r'\.00$'), '') +
                    "%";
          }
          taskDetailList.add(task);
        }
        taskDetailList = serverTaskInfo.taskDetailList ?? [];
        if (taskDetailList.isNotEmpty) {
          noProcessingTask = false;
        }
        int complateCount = taskDetailList
            .where((element) => element.status == VTaskStatus.Completed)
            .length;
        DateFormat formatter = DateFormat('yyyy-MM-dd HH:mm:ss');
        var startTime = serverTaskInfo.createTime?.toLocal() ?? DateTime.now();
        String formattedDate = formatter.format(startTime);
        Duration difference;
        var endTime = serverTaskInfo.endTime?.toLocal();
        if (endTime == null || endTime.year == 1) {
          difference = DateTime.now().difference(startTime);
        } else {
          difference = endTime.difference(startTime);
        }
        // 提取分钟和秒钟
        int minutes = difference.inMinutes;
        int seconds = difference.inSeconds % 60;
        String elapsedTime = '${minutes}min${seconds}s';
        currentTaskInfo = TaskInfo(
            complateCount: complateCount,
            elapsedTime: elapsedTime,
            startTime: formattedDate,
            status: serverTaskInfo.status,
            title: _getTaskNameByTaskType(serverTaskInfo.taskType),
            totalCount: taskDetailList.length,
            patientCode: serverTaskInfo.patientCode);
      }
    }

    update([taskPageId, taskDetailListId, headerPanelId]);
  }

  String _getTaskNameByTaskType(VTaskType status) {
    switch (status) {
      case VTaskType.Analysis:
        return "URM 分析";
      case VTaskType.DeviceUpload:
        return "上传";
      case VTaskType.UserExport:
        return "数据导出";
      case VTaskType.UserImport:
        return "数据导入";
      case VTaskType.URMSaveVideo:
        return "视频保存";
      default:
        return "";
    }
  }

  Future<void> cancelCurrentTask() async {
    cancelTimer();
    String currentSelectedTaskId = currentSelectedTask?.code ?? "";
    if (currentSelectedTaskId.isEmpty) {
      return;
    }

    if (currentSelectedTask?.taskType == VTaskType.UserExport ||
        currentSelectedTask?.taskType == VTaskType.UserImport) {
      TaskInfo? task = localTaskCenter.getTaskInfo(currentSelectedTaskId);
      if (task != null) {
        localTaskCenter.canCelTask(currentSelectedTaskId);
      } else {
        bool result = await Get.find<IServerTaskManager>()
            .canCelTasks(currentSelectedTaskId, taskDetailList);
        if (result) {
          PromptBox.toast("取消成功");
        }
      }
    } else {
      if (taskDetailList.any((element) => element.rate == 100)) {
        PromptBox.toast("当前没有可以取消的任务");
      } else {
        var dialogResult = await Get.dialog(
          LabDialog(
            title: "提示",
            content: "处理中的任务无法取消，是否取消待开始的任务？",
          ),
          barrierColor: LabColors.base100.withOpacity(0.1),
        );
        if (dialogResult) {
          bool result = await Get.find<IURMFunctionManager>()
              .cancelAnalysis(currentSelectedTaskId);
          if (result) {
            PromptBox.toast("取消成功");
          }
        }
      }
    }
    updateTaskList();
    Future.delayed(Duration(milliseconds: 1000), () {
      updateTaskList();
    });
    //3秒是壳子通讯超时时间
    Future.delayed(Duration(milliseconds: 3100), () {
      updateTaskList();
    });
  }

  void onReceiveNotification(Object sender, ApplicationNotification e) {
    String currentSelectedTaskId = currentSelectedTask?.code ?? "";
    print("通知接收：${e.code}");
    if (e.code == currentSelectedTaskId) {
      Future.delayed(Duration(milliseconds: 800), () {
        updateTaskList();
      });
    }
  }
}
