import 'dart:convert';

import 'package:flyinsono/architecture/services/modules/config_language.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/lab/manager/interfaces/analysis.dart';
import 'package:flyinsono/lab/manager/interfaces/project.dart';
import 'package:flyinsono/lab/mock_data/mock_rpc.dart';
import 'package:flyinsono/rpc.dart';
import 'package:fis_common/logger/logger.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:get/get.dart';

import '../../managers/base_manager.dart';

// 定义项目类，实现项目管理接口
class ProjectManager extends BaseManager implements IProjectManager {
  // 创建研究项目
  @override
  Future<String?> createResearchProjectAsync({
    required String projectName,
    required OrganizationPatientTypeEnum projectType,
    required String projectIntroduction,
  }) async {
    try {
      return await rpc.researchEdition.createResearchProjectAsync(
        CreateResearchProjectRequest(
          token: token,
          name: projectName,
          patientType: projectType,
          introduction: projectIntroduction,
        ),
      );
    } catch (e) {
      logger.e('Project createResearchProjectAsync ex:', e);

      return null;
    }
  }

  // 获取研究项目列表
  @override
  Future<List<ResearchProjectBaseDTO>?> getResearchProjectListAsync({
    required String keyWord,
    required ResearchProjectSearchTypeEnum searchType,
  }) async {
    try {
      List<ResearchProjectBaseDTO>? result =
          await rpc.researchEdition.getResearchProjectListAsync(
        GetResearchProjectListRequest(
          token: token,
          keyword: keyWord,
          searchType: searchType,
        ),
      );
      return result;
    } catch (e) {
      logger.e('Project getResearchProjectListAsync ex:', e);

      return null;
    }
  }

  // 获取用户基本信息分页
  @override
  Future<PageCollection<UserBaseDTO>?> getUserBaseInfoPagesAsync({
    required String keyWord,
    required int pageIndex,
    required int pageSize,
  }) async {
    try {
      PageCollection<UserBaseDTO>? result =
          await rpc.researchEdition.getUserBaseInfoPagesAsync(
        GetRRUserPagesRequest(
          token: token,
          keyWord: keyWord,
          pageIndex: pageIndex,
          pageSize: pageSize,
        ),
      );
      return result;
    } catch (e) {
      logger.e('Project getUserBaseInfoPagesAsync ex:', e);

      return null;
    }
  }

  // 邀请研究项目成员
  @override
  Future<bool?> inviteResearchProjectMembersAsync({
    required String projectCode,
    required List<String> memberCodes,
  }) async {
    try {
      bool result = await rpc.researchEdition.inviteResearchProjectMembersAsync(
        InviteResearchProjectMembersRequest(
          token: token,
          code: projectCode,
          memberCodes: memberCodes,
        ),
      );
      return result;
    } catch (e) {
      logger.e('Project inviteResearchProjectMembersAsync ex:', e);
      return null;
    }
  }

  // 获取项目详情
  @override
  Future<ResearchProjectDTO?> getResearchProjectDetail({
    required String projectCode,
  }) async {
    try {
      ResearchProjectDTO? result =
          await rpc.researchEdition.getResearchProjectDetailAsync(
        GetResearchProjectDetailRequest(
          token: token,
          code: projectCode,
        ),
      );
      return result;
    } catch (e) {
      logger.e('Project getResearchProjectDetailAsync ex:', e);
      return null;
    }
  }

  // 移除项目成员
  @override
  Future<bool?> removeResearchProjectMembersAsync({
    required String projectCode,
    required List<String> memberCodes,
  }) async {
    try {
      bool result = await rpc.researchEdition.removeResearchProjectMembersAsync(
        RemoveResearchProjectMembersRequest(
          token: token,
          code: projectCode,
          memberCodes: memberCodes,
        ),
      );
      return result;
    } catch (e) {
      logger.e('Project removeResearchProjectMembersAsync ex:', e);
      return null;
    }
  }

  // 查询项目数据
  @override
  Future<PageCollection<ResearchProjectDataDTO>?>
      getResearchProjectDataPagesAsync({
    required String keyWord,
    required int pageIndex,
    required int pageSize,
    required int sort,
    required String projectCode,
  }) async {
    try {
      PageCollection<ResearchProjectDataDTO> result =
          await rpc.researchEdition.getResearchProjectDataPagesAsync(
        GetResearchProjectDatasRequest(
          token: token,
          projectCode: projectCode,
          pageIndex: 1,
          pageSize: 1000,
          keyWord: keyWord,
          sort: sort,
        ),
      );
      return result;
    } catch (e) {
      logger.e('Project getResearchProjectDataPagesAsync ex:', e);
      return null;
    }
  }

  /// 删除项目
  @override
  Future<bool?> deleteResearchProjectRequest({
    required String projectCode,
  }) async {
    try {
      return await rpc.researchEdition.deleteResearchProjectAsync(
        DeleteResearchProjectRequest(
          token: token,
          code: projectCode,
        ),
      );
    } catch (e) {
      logger.e('Project deleteResearchProjectRequest ex:', e);

      return null;
    }
  }

  @override
  Future<bool?> updateResearchProjectAsync({
    required String projectCode,
    required String projectName,
    OrganizationPatientTypeEnum? projectType,
    String? projectIntroduction,
  }) async {
    try {
      return await rpc.researchEdition.updateResearchProjectAsync(
        UpdateResearchProjectRequest(
          token: token,
          code: projectCode,
          name: projectName,
          patientType: projectType!,
          introduction: projectIntroduction,
        ),
      );
    } catch (e) {
      logger.e('Project deleteResearchProjectRequest ex:', e);

      return null;
    }
  }

  // 获取样本数据
  @override
  Future<List<SampleDetail>?> getSampleDetailList({
    required String patientCode,
  }) async {
    try {
      return await rpc.researchEdition.getSampleDetailList(
        GetSampleDetailsRequest(
          token: token,
          patientCode: patientCode,
        ),
      );
    } catch (e) {
      logger.e('Project getSampleDetailList ex:', e);

      return null;
    }
  }

  @override
  Future<bool?> deleteRecordAsync({
    required String recordCode,
    required String projectCode,
  }) async {
    try {
      return await rpc.recordInfo.deleteRecordAsync(
        DeleteRecordRequest(
          token: token,
          recordCode: recordCode,
          projectCode: projectCode,
        ),
      );
    } catch (e) {
      logger.e('Project deleteRecordAsync ex:', e);

      return null;
    }
  }

  @override
  Future<bool> deleteSample(
    String projectCode,
    String patientCode,
  ) async {
    try {
      return await rpc.researchEdition.deleteSampleAsync(
        DeletePatientSampleRequest(
          token: token,
          patientCode: patientCode,
          projectCode: projectCode,
        ),
      );
    } catch (e) {
      logger.e('Project deleteSample ex:', e);
      return false;
    }
  }

  @override
  Future<BaseSampleDetail?> getSampleDetailAsync({
    required String recordCode,
  }) async {
    try {
      return await rpc.researchEdition.getSampleDetailAsync(
        GetSampleDetailRequest(
          token: token,
          recordCode: recordCode,
        ),
      );
    } catch (e) {
      logger.e('Project getSampleDetailAsync ex:', e);

      return null;
    }
  }

  @override
  Future<bool?> modifySampleDetailAsync({
    required String recordCode,
    required List<PatientInfoExt>? patientInfoExtList,
    required List<DataItemDTO>? patientInfo,
  }) async {
    try {
      return await rpc.researchEdition.modifySampleDetailAsync(
        ModifySampleDetailRequest(
          token: token,
          recordCode: recordCode,
          patientInfoExtList: patientInfoExtList,
          patientInfo: patientInfo,
        ),
      );
    } catch (e) {
      logger.e('Project modifySampleDetailAsync ex:', e);

      return null;
    }
  }

  /// 获取项目时间轴
  @override
  Future<List<TimeAxisDetail>?> getTimeAxisByProjectAsync({
    required String projectCode,
  }) async {
    try {
      return await rpc.researchEdition.getTimeAxisByProjectAsync(
        GetTaskListByProjectRequest(
          token: token,
          projectCode: projectCode,
        ),
      );
    } catch (e) {
      logger.e('Project getTaskListByProjectAsync ex:', e);

      return null;
    }
  }

  @override
  Future<List<SampleRemedicalInfoDTO>?> getSampleImgList({
    required String patientCode,
  }) async {
    try {
      return await rpc.researchEdition.getSampleImgList(
        GetSampleDetailsRequest(
          token: token,
          patientCode: patientCode,
        ),
      );
    } catch (e) {
      logger.e('Project getTaskListByProjectAsync ex:', e);

      return null;
    }
  }

  @override
  Future<List<RecordModel>> getRecordDetail({
    required String patientCode,
    required PatientModel selectedPatient,
    required OrganizationPatientTypeEnum patientType,
  }) async {
    List<SampleDetail>? sampleDetailList = await getSampleDetailList(
      patientCode: patientCode,
    );
    List<RecordModel> result = [];
    for (int i = 0; i < (sampleDetailList ?? []).length; i++) {
      List<ImageModel> resultImage = [];
      Set<String> applicationSet = {};
      List<DataItemDTO> resultpatientInfo = [];

      sampleDetailList?[i].sampleRemedicalInfoList?.forEach(
        (ext) {
          SampleRemedicalFileDataTypeEnum fileDataType = ext.fileDataType;
          // find urm result vid
          ImageType imageType =
              Get.find<IURMFunctionManager>().getImageType(ext);
          String vidUrl = ext.imageUrl ?? '';
          if (imageType == ImageType.URM_Result) {
            String? urmResultVid =
                Get.find<IURMFunctionManager>().findURMResultVid(ext);
            if (urmResultVid != null) {
              vidUrl = urmResultVid;
            }
          }
          resultImage.add(
            ImageModel(
              id: ext.businessCode ?? '',
              createTime: ext.createTime ?? DateTime.now(),
              description: '',
              fileTypeName: '',
              fileDataType: fileDataType,
              vidDataInfo: VidDataInfo(
                vidUrl: vidUrl,
                id: ext.businessCode ?? '',
                coverUrl: ext.coverImgUrl ?? '',
                sampleRemedicalFileDataTypeEnum: ext.fileDataType,
                imageType: imageType,
              ),
              urmOriginalCode: ext.urmOriginalCode,
            ),
          );
          if (ext.application != null && ext.application!.isNotEmpty) {
            applicationSet.add(ext.application!);
          }
        },
      );
      sampleDetailList?[i].patientInfo?.forEach((element) {
        resultpatientInfo.add(element);
      });

      final applicationList = applicationSet.toList();

      /// 将应用名称逐个翻译为中文，使用“，”连接
      String applicationDescription =
          applicationList.map((e) => getApplicationValue(e)).toList().join('，');
      result.add(
        RecordModel(
          createTime: sampleDetailList?[i].recordTime ?? DateTime.now(),
          id: sampleDetailList?[i].recordCode ?? '',
          imageCount: sampleDetailList?[i].sampleRemedicalInfoList?.length ?? 0,
          description:
              applicationDescription, // 部分应用名称需要server新增翻译例如 “Rat Craniotomy”
          images: resultImage,
          patient: selectedPatient,
          patientInfo: resultpatientInfo,
          organizationPatientTypeEnum: patientType,
        ),
      );
    }
    return result;
  }

  /// 获取超声应用的翻译值
  String getApplicationValue(String application) {
    final languageService = Get.find<LanguageService>();
    var value =
        languageService.findLanguageValueByCode('application', application);
    return value;
  }

  @override
  Future<List<SampleRemedicalInfoDTO>?> getUrmRemedicalInfosAsync(
      String urmRemedicalCode) async {
    try {
      var request = GetUrmRemedicalInfosRequest(
          token: Store.user.token, urmRemedicalCode: urmRemedicalCode);
      print(jsonEncode(request.toJson()));
      var result = await rpc.researchEdition.getUrmRemedicalInfosAsync(request);
      print("SampleRemedicalInfoDTO.Length:${result.length}");
      return result;
    } catch (e) {
      print("$e");
      return null;
    }
  }

  @override
  Future<bool> saveUserUrmConfigAsync(String code, String configName,
      int configType, List<UrmProcessConfigDTO>? configInfo) async {
    try {
      var request = SaveUserUrmConfigRequest(
        token: Store.user.token,
        code: code.isEmpty ? null : code,
        configName: configName,
        configType: configType,
        configInfo: configInfo,
      );
      var result = await rpc.researchEdition.saveUserUrmConfigAsync(request);
      if (result.code?.isNotEmpty ?? false) {
        return true;
      }
    } catch (e) {}

    return false;
  }

  @override
  Future<bool> deletePatientUrmConfigAsync(String code) async {
    try {
      var request =
          DeletePatientUrmConfigRequest(token: Store.user.token, code: code);
      var result =
          await rpc.researchEdition.deletePatientUrmConfigAsync(request);
      return result;
    } catch (e) {}
    return false;
  }

  @override
  Future<bool> setDefaultPatientUrmConfigAsync(String code) async {
    try {
      var request = SetDefaultPatientUrmConfigRequest(
          token: Store.user.token, code: code);
      var result =
          await rpc.researchEdition.setDefaultPatientUrmConfigAsync(request);
      return result;
    } catch (e) {}
    return false;
  }

  @override
  Future<List<UserUrmConfigDTO>> getUserUrmConfigsAsync() async {
    try {
      var request = GetUserUrmConfigsRequest(token: Store.user.token);
      var result = await rpc.researchEdition.getUserUrmConfigsAsync(request);
      return result;
    } catch (e) {}
    return [];
  }

  // 验证是否有权限或者项目是否有效
  @override
  Future<bool?> validateResearchProjectAuthAsync(
      {required String projectCode}) async {
    try {
      bool result = await rpc.researchEdition.validateResearchProjectAuthAsync(
        GetResearchProjectDetailRequest(token: token, code: projectCode),
      );
      return result;
    } catch (e) {
      logger.e('Project validateResearchProjectAuthAsync ex:', e);
      return null;
    }
  }
}
