 


import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';

import 'package:get/get.dart';

import '../models/index.dart';
import '../utils/index.dart';
import '../values/index.dart';

///
///流程服务
///
class ProcessSurfaceService extends GetxService {
  
  static ProcessSurfaceService get to => Get.find();

  // 缓存应用图标用
  Map<String, Uint8List> processAppIcons = <String, Uint8List>{};

  String baseUrl() {
    return O2ApiManager.instance.getModuleBaseUrl(
        O2DistributeModuleEnum.x_processplatform_assemble_surface) ?? '';
  }

  ///
  /// 附件下载地址
  /// 
  String downloadUrlWithWorkId(String workId, String attachmentId) {
    return "${baseUrl()}jaxrs/attachment/download/$attachmentId/work/$workId/stream";
  }
  ///
  /// 附件下载地址
  /// 
  String downloadUrlWithWorkcompleted(String workcompletedId, String attachmentId) {
    return "${baseUrl()}jaxrs/attachment/download/$attachmentId/workcompleted/$workcompletedId/stream";
  }

  /// 
  /// base64 应用icon 
  /// 
  Future<Uint8List?> applicationIcon(String appId) async {
    var icon = processAppIcons[appId];
    if (icon != null) {
      return icon;
    }
    ApplicationIconData? applicationIconData = await getApplicationIconData(appId);
    if (applicationIconData != null && applicationIconData.icon != null) {
      processAppIcons[appId] = base64Decode(applicationIconData.icon!);
    }
    return processAppIcons[appId];
  }


  ///
  /// 查询应用Icon
  /// 
  Future<ApplicationIconData?> getApplicationIconData(String appId) async {
    try {
      ApiResponse response = await O2HttpClient.instance.get('${baseUrl()}jaxrs/application/$appId/icon');
      return  ApplicationIconData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('查询应用Icon失败', err, stackTrace);
    }
    return null;
  }

  /// 获取流程对象
  Future<ProcessData?> getProcess(String processId) async {
     try {
      ApiResponse response = await O2HttpClient.instance.get('${baseUrl()}jaxrs/process/$processId');
      return  ProcessData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('查询流程对象失败', err, stackTrace);
    }
    return null;
  }

  /// 获取流程对象
  /// [app] 流程应用名称或标识，[process]流程名称或标识
  Future<ProcessData?> 	getWithProcessWithApplication(String app, String process) async {
     try {
      ApiResponse response = await O2HttpClient.instance.get('${baseUrl()}jaxrs/process/$process/application/$app');
      return  ProcessData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('查询流程对象失败', err, stackTrace);
    }
    return null;
  }

  ///
  /// 	根据当前用户所有可见的Application,并绑定其启动的Process.
  ///
  Future<List<ProcessApplicationData>?> listApplitionComplex() async {
    try {
      ApiResponse response =
      await O2HttpClient.instance.get('${baseUrl()}jaxrs/application/list/complex');
      var list = response.data == null ? [] : response.data as List;
      return list.map((x) => ProcessApplicationData.fromJson(x)).toList();
    } catch (err, stackTrace) {
      OLogger.e('查询流程应用列表失败', err, stackTrace);
    }
    return null;
  }

  /// 当前用户 移动端 能发起申请的流程应用列表
  Future<List<ProcessApplicationData>?> listApplitionTerminalIsMobile() async {
    try {
      ApiResponse response =
      await O2HttpClient.instance.get('${baseUrl()}jaxrs/application/list/terminal/mobile');
      var list = response.data == null ? [] : response.data as List;
      return list.map((x) => ProcessApplicationData.fromJson(x)).toList();
    } catch (err, stackTrace) {
      OLogger.e('查询流程应用列表失败', err, stackTrace);
    }
    return null;
  }

  ///
  /// 分页查询待办列表
  /// @param lastId 传入列表最后一个对象的id， 第一页传默认 O2.o2DefaultPageFirstKey 
  ///
  Future<List<TaskData>?> getTaskListByPage(String lastId, { int limit = O2.o2DefaultPageSize, Map<String, dynamic>? body }) async {
    try {
      Map<String, dynamic> data = {};
      if (body != null) {
        data = body;
      }
      ApiResponse response =
      await O2HttpClient.instance.post('${baseUrl()}jaxrs/task/v2/list/$lastId/next/$limit', data);
      var list = response.data == null ? [] : response.data as List;
      return list.map((group) => TaskData.fromJson(group)).toList();
    } catch (err, stackTrace) {
      OLogger.e('查询待办列表失败', err, stackTrace);
    }
    return null;
  }
  ///
  /// 分页查询待办列表
  /// @param lastId 传入列表最后一个对象的id， 第一页传默认 O2.o2DefaultPageFirstKey 
  ///
  Future<List<TaskData>?> getMyTaskListByPage(int page, { int size = O2.o2DefaultPageSize, Map<String, dynamic>? body }) async {
    try {
      Map<String, dynamic> data = {};
      if (body != null) {
        data = body;
      }
      ApiResponse response =
      await O2HttpClient.instance.post('${baseUrl()}jaxrs/task/list/my/filter/$page/size/$size', data);
      var list = response.data == null ? [] : response.data as List;
      return list.map((group) => TaskData.fromJson(group)).toList();
    } catch (err, stackTrace) {
      OLogger.e('查询待办列表失败', err, stackTrace);
    }
    return null;
  }
  
  /// 查询待办对象
  Future<TaskData?> getTaskData(String id) async {
    try {
      ApiResponse response = await O2HttpClient.instance.get('${baseUrl()}jaxrs/task/$id');
      return TaskData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('查询待办失败', err, stackTrace);
    }
    return null;
  }

  /// 提交待办处理
  Future<IdData?> processing(TaskData task) async {
    try {
      ApiResponse response = await O2HttpClient.instance.post('${baseUrl()}jaxrs/task/${task.id!}/processing', task.toJson());
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('提交待办失败', err, stackTrace);
    }
    return null;
  }

  ///
  /// 分页查询已办列表
  /// @param lastId 传入列表最后一个对象的id， 第一页传默认 O2.o2DefaultPageFirstKey 
  ///
  Future<List<TaskCompletedData>?> getTaskCompletedListByPage(String lastId, { int limit = O2.o2DefaultPageSize, Map<String, dynamic>? body }) async {
    try {
      Map<String, dynamic> data = {};
      if (body != null) {
        data = body;
      }
      data['latest'] = true; // 同一Job,同一处理人只显示最后一条已办.
      ApiResponse response =
      await O2HttpClient.instance.post('${baseUrl()}jaxrs/taskcompleted/v2/list/$lastId/next/$limit', data);
      var list = response.data == null ? [] : response.data as List;
      return list.map((group) => TaskCompletedData.fromJson(group)).toList();
    } catch (err, stackTrace) {
      OLogger.e('查询已办列表失败', err, stackTrace);
    }
    return null;
  }


  ///
  /// 分页查询待阅列表
  /// @param lastId 传入列表最后一个对象的id， 第一页传默认 O2.o2DefaultPageFirstKey 
  ///
  Future<List<ReadData>?> getReadListByPage(String lastId, { int limit = O2.o2DefaultPageSize, Map<String, dynamic>? body }) async {
    try {
      Map<String, dynamic> data = {};
      if (body != null) {
        data = body;
      }
      ApiResponse response =
      await O2HttpClient.instance.post('${baseUrl()}jaxrs/read/v2/list/$lastId/next/$limit', data);
      var list = response.data == null ? [] : response.data as List;
      return list.map((group) => ReadData.fromJson(group)).toList();
    } catch (err, stackTrace) {
      OLogger.e('查询待阅列表失败', err, stackTrace);
    }
    return null;
  }


  ///
  /// 分页查询已阅列表
  /// @param lastId 传入列表最后一个对象的id， 第一页传默认 O2.o2DefaultPageFirstKey 
  ///
  Future<List<ReadCompletedData>?> getReadCompletedListByPage(String lastId, { int limit = O2.o2DefaultPageSize, Map<String, dynamic>? body }) async {
    try {
      Map<String, dynamic> data = {};
      if (body != null) {
        data = body;
      }
      ApiResponse response =
      await O2HttpClient.instance.post('${baseUrl()}jaxrs/readcompleted/v2/list/$lastId/next/$limit', data);
      var list = response.data == null ? [] : response.data as List;
      return list.map((group) => ReadCompletedData.fromJson(group)).toList();
    } catch (err, stackTrace) {
      OLogger.e('查询已阅列表失败', err, stackTrace);
    }
    return null;
  }

  ///
  /// 根据workid或workcompletedid 查询对象
  /// 
  Future<WorkOrWorkcompletedInfo?> getWorkOrWorkcompletedWithId(String id) async {
    try {
      ApiResponse response = await O2HttpClient.instance.get('${baseUrl()}jaxrs/work/v2/workorworkcompleted/$id');
      return  WorkOrWorkcompletedInfo.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('查询Work对象失败', err, stackTrace);
    }
    return null;
  }

  ///
  /// 列示指定已办后续的所有Work和WorkCompleted.
  /// 
  Future<WorkReference?> getTaskCompletedReference(String taskCompletedId) async {
     try {
      ApiResponse response = await O2HttpClient.instance.get('${baseUrl()}jaxrs/taskcompleted/$taskCompletedId/reference');
      return  WorkReference.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('查询已办后续失败', err, stackTrace);
    }
    return null;
  } 

  ///
  /// 列示指定待阅后续的所有Work和WorkCompleted.
  /// 
  Future<WorkReference?> getReadReference(String readId) async {
     try {
      ApiResponse response = await O2HttpClient.instance.get('${baseUrl()}jaxrs/read/$readId/reference');
      return  WorkReference.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('查询待阅后续失败', err, stackTrace);
    }
    return null;
  } 

  ///
  /// 列示指定已阅后续的所有Work和WorkCompleted.
  /// 
  Future<WorkReference?> getReadCompletedReference(String readCompletedId) async {
     try {
      ApiResponse response = await O2HttpClient.instance.get('${baseUrl()}jaxrs/readcompleted/$readCompletedId/reference');
      return  WorkReference.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('查询已阅后续失败', err, stackTrace);
    }
    return null;
  } 

  ///
  /// 根据workId查询附件对象
  /// 
  Future<WorkAttachmentInfo?> getAttachmentInfoWithWorkid(String workid, String attId) async {
    try {
      ApiResponse response = await O2HttpClient.instance.get('${baseUrl()}jaxrs/attachment/$attId/work/$workid');
      return  WorkAttachmentInfo.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('查询附件对象失败 ， workid： $workid, attId: $attId', err, stackTrace);
    }
    return null;
  }


  ///
  /// 根据workcompletedId查询附件对象
  /// 
  Future<WorkAttachmentInfo?> getAttachmentInfoWithWorkcompletedId(String workcompletedId, String attId) async {
    try {
      ApiResponse response = await O2HttpClient.instance.get('${baseUrl()}jaxrs/attachment/$attId/workcompleted/$workcompletedId');
      return  WorkAttachmentInfo.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('查询附件对象失败 ， workcompletedId $workcompletedId, attId: $attId', err, stackTrace);
    }
    return null;
  }

  ///
  /// 上传附件
  /// 
  Future<IdData?> uploadAttachment(String workId, String site, File file) async {
    try {
      ApiResponse response = await O2HttpClient.instance.postUploadFile('${baseUrl()}jaxrs/attachment/upload/work/$workId', file, body: {'site': site});
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('上传附件失败', err, stackTrace);
    }
    return null;
  }
  ///
  /// 替换附件
  /// 
  Future<IdData?> replaceAttachment(String workId, String attachmentId, File file) async {
    try {
      ApiResponse response = await O2HttpClient.instance.putUploadFile('${baseUrl()}jaxrs/attachment/update/$attachmentId/work/$workId', file);
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('替换附件失败', err, stackTrace);
    }
    return null;
  }



  ///
  /// 启动流程
  /// 
  Future<List<ProcessWorkData>?> startProcess(String processId, Map<String, dynamic> body) async {
    try {
      ApiResponse response = await O2HttpClient.instance.post('${baseUrl()}jaxrs/work/process/$processId', body);
       var list = response.data == null ? [] : response.data as List;
      return list.map((group) => ProcessWorkData.fromJson(group)).toList();
    } catch (err, stackTrace) {
      OLogger.e('启动流程失败', err, stackTrace);
    }
    return null;
  }

  ///
  /// 启动草稿
  /// 
  Future<ProcessDraftData?> startDraft(String processId, Map<String, dynamic> body) async {
    try {
      ApiResponse response = await O2HttpClient.instance.post('${baseUrl()}jaxrs/draft/process/$processId', body);
      return ProcessDraftData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('启动草稿失败', err, stackTrace);
    }
    return null;
  }

  /// 根据 job 查询工作 
  /// 
  /// 没有 catch 异常 方便业务处理
  Future<WorkReference?> getWorkByJob(String job) async {
    ApiResponse response = await O2HttpClient.instance.get('${baseUrl()}jaxrs/job/$job/find/work/workcompleted');
    return WorkReference.fromJson(response.data);
  }

  /// 获取工作数量
  Future<WorkCount?> workCountWithPerson(String person) async {
    ApiResponse response = await O2HttpClient.instance.get('${baseUrl()}jaxrs/work/count/$person');
    return WorkCount.fromJson(response.data);
  }
  
}