import 'liveConsultation.m.dart';
import 'patient.m.dart';
import 'notification.m.dart';

import 'package:fis_jsonrpc/utils.dart';

class PatientInfoExt {
	String? patientScanType;
	List<DataItemDTO>? content;

	PatientInfoExt({
		this.patientScanType,
		this.content,
	});

	factory PatientInfoExt.fromJson(Map<String, dynamic> map) {
		return PatientInfoExt( 
			patientScanType: map['PatientScanType'],
			content: map['Content'] != null ? (map['Content'] as List).map((e)=>DataItemDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
		);
	}

	Map<String, dynamic> toJson() {
		final map = Map<String, dynamic>();
		if(patientScanType != null) {
			map['PatientScanType'] = patientScanType;
		}
		if(content != null) {
			map['Content'] = content;
		}
		return map;
	}
}

class CreateRecordRequest extends TokenRequest{
	String? patientCode;
	String? deviceCode;
	List<DataItemDTO>? patientDatas;
	List<PatientInfoExt>? patientInfoExtList;

	CreateRecordRequest({
		this.patientCode,
		this.deviceCode,
		this.patientDatas,
		this.patientInfoExtList,
		String? token,
	}) : super(
			token: token,
		);

	factory CreateRecordRequest.fromJson(Map<String, dynamic> map) {
		return CreateRecordRequest( 
			patientCode: map['PatientCode'],
			deviceCode: map['DeviceCode'],
			patientDatas: map['PatientDatas'] != null ? (map['PatientDatas'] as List).map((e)=>DataItemDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
			patientInfoExtList: map['PatientInfoExtList'] != null ? (map['PatientInfoExtList'] as List).map((e)=>PatientInfoExt.fromJson(e as Map<String,dynamic>)).toList() : null,
			token: map['Token'],
		);
	}

	Map<String, dynamic> toJson() {
		final map = super.toJson();
		if(patientCode != null)
			map['PatientCode'] = patientCode;
		if(deviceCode != null)
			map['DeviceCode'] = deviceCode;
		if(patientDatas != null)
			map['PatientDatas'] = patientDatas;
		if(patientInfoExtList != null)
			map['PatientInfoExtList'] = patientInfoExtList;
		return map;
	}
}

enum QueryRecordStatusEnum {
	All,
	NotScanned,
	Uploaded,
	NotReport,
	Completed,
	NotCompleted,
}

enum QueryRecordCreateTypeEnum {
	All,
	Reservation,
	Normal,
}

class GetRecordsPageRequest extends PageRequest{
	String? patientCode;
	QueryRecordStatusEnum queryRecordStatus;
	QueryRecordCreateTypeEnum queryRecordCreateType;

	GetRecordsPageRequest({
		this.patientCode,
		this.queryRecordStatus = QueryRecordStatusEnum.All,
		this.queryRecordCreateType = QueryRecordCreateTypeEnum.All,
		int pageIndex = 0,
		int pageSize = 0,
		String? token,
	}) : super(
			pageIndex: pageIndex,
			pageSize: pageSize,
			token: token,
		);

	factory GetRecordsPageRequest.fromJson(Map<String, dynamic> map) {
		return GetRecordsPageRequest( 
			patientCode: map['PatientCode'],
			queryRecordStatus: QueryRecordStatusEnum.values.firstWhere((e) => e.index == map['QueryRecordStatus']),
			queryRecordCreateType: QueryRecordCreateTypeEnum.values.firstWhere((e) => e.index == map['QueryRecordCreateType']),
			pageIndex: map['PageIndex'],
			pageSize: map['PageSize'],
			token: map['Token'],
		);
	}

	Map<String, dynamic> toJson() {
		final map = super.toJson();
		if(patientCode != null)
			map['PatientCode'] = patientCode;
		map['QueryRecordStatus'] = queryRecordStatus.index;
		map['QueryRecordCreateType'] = queryRecordCreateType.index;
		return map;
	}
}

class QueryRecordResult {
	DateTime? createTime;
	String? deptName;
	String? patientName;
	String? patientAge;
	List<DataItemDTO>? patientAgeInfo;
	int patientSex;
	String? creatorName;
	String? deviceName;
	String? displayName;
	RecordStatusEnum recordStatus;
	List<PatientInfoExt>? patientInfoExtList;
	DiagnosisStatusEnum diagnosisStatus;
	List<DiagnosisInfoDTO>? diagnosisInfos;
	bool isCollecting;
	DateTime? startCollectingTime;
	String? customDoctor;
	String? customOrganzation;
	String? equipmentSN;
	String? deviceOrganzationName;

	QueryRecordResult({
		this.createTime,
		this.deptName,
		this.patientName,
		this.patientAge,
		this.patientAgeInfo,
		this.patientSex = 0,
		this.creatorName,
		this.deviceName,
		this.displayName,
		this.recordStatus = RecordStatusEnum.NotScanned,
		this.patientInfoExtList,
		this.diagnosisStatus = DiagnosisStatusEnum.NotRequired,
		this.diagnosisInfos,
		this.isCollecting = false,
		this.startCollectingTime,
		this.customDoctor,
		this.customOrganzation,
		this.equipmentSN,
		this.deviceOrganzationName,
	});

	factory QueryRecordResult.fromJson(Map<String, dynamic> map) {
		return QueryRecordResult( 
			createTime: map['CreateTime'] != null ? DateTime.parse(map['CreateTime']) : null,
			deptName: map['DeptName'],
			patientName: map['PatientName'],
			patientAge: map['PatientAge'],
			patientAgeInfo: map['PatientAgeInfo'] != null ? (map['PatientAgeInfo'] as List).map((e)=>DataItemDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
			patientSex: map['PatientSex'],
			creatorName: map['CreatorName'],
			deviceName: map['DeviceName'],
			displayName: map['DisplayName'],
			recordStatus: RecordStatusEnum.values.firstWhere((e) => e.index == map['RecordStatus']),
			patientInfoExtList: map['PatientInfoExtList'] != null ? (map['PatientInfoExtList'] as List).map((e)=>PatientInfoExt.fromJson(e as Map<String,dynamic>)).toList() : null,
			diagnosisStatus: DiagnosisStatusEnum.values.firstWhere((e) => e.index == map['DiagnosisStatus']),
			diagnosisInfos: map['DiagnosisInfos'] != null ? (map['DiagnosisInfos'] as List).map((e)=>DiagnosisInfoDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
			isCollecting: map['IsCollecting'],
			startCollectingTime: map['StartCollectingTime'] != null ? DateTime.parse(map['StartCollectingTime']) : null,
			customDoctor: map['CustomDoctor'],
			customOrganzation: map['CustomOrganzation'],
			equipmentSN: map['EquipmentSN'],
			deviceOrganzationName: map['DeviceOrganzationName'],
		);
	}

	Map<String, dynamic> toJson() {
		final map = Map<String, dynamic>();
		if(createTime != null) {
			map['CreateTime'] = JsonRpcUtils.dateFormat(createTime!);
		}
		if(deptName != null) {
			map['DeptName'] = deptName;
		}
		if(patientName != null) {
			map['PatientName'] = patientName;
		}
		if(patientAge != null) {
			map['PatientAge'] = patientAge;
		}
		if(patientAgeInfo != null) {
			map['PatientAgeInfo'] = patientAgeInfo;
		}
		map['PatientSex'] = patientSex;
		if(creatorName != null) {
			map['CreatorName'] = creatorName;
		}
		if(deviceName != null) {
			map['DeviceName'] = deviceName;
		}
		if(displayName != null) {
			map['DisplayName'] = displayName;
		}
		map['RecordStatus'] = recordStatus.index;
		if(patientInfoExtList != null) {
			map['PatientInfoExtList'] = patientInfoExtList;
		}
		map['DiagnosisStatus'] = diagnosisStatus.index;
		if(diagnosisInfos != null) {
			map['DiagnosisInfos'] = diagnosisInfos;
		}
		map['IsCollecting'] = isCollecting;
		if(startCollectingTime != null) {
			map['StartCollectingTime'] = JsonRpcUtils.dateFormat(startCollectingTime!);
		}
		if(customDoctor != null) {
			map['CustomDoctor'] = customDoctor;
		}
		if(customOrganzation != null) {
			map['CustomOrganzation'] = customOrganzation;
		}
		if(equipmentSN != null) {
			map['EquipmentSN'] = equipmentSN;
		}
		if(deviceOrganzationName != null) {
			map['DeviceOrganzationName'] = deviceOrganzationName;
		}
		return map;
	}
}

class QueryRecordRequest extends TokenRequest{
	String? recordCode;

	QueryRecordRequest({
		this.recordCode,
		String? token,
	}) : super(
			token: token,
		);

	factory QueryRecordRequest.fromJson(Map<String, dynamic> map) {
		return QueryRecordRequest( 
			recordCode: map['RecordCode'],
			token: map['Token'],
		);
	}

	Map<String, dynamic> toJson() {
		final map = super.toJson();
		if(recordCode != null)
			map['RecordCode'] = recordCode;
		return map;
	}
}

class ProcessRecordDataResult {
	List<DataItemDTO>? content;

	ProcessRecordDataResult({
		this.content,
	});

	factory ProcessRecordDataResult.fromJson(Map<String, dynamic> map) {
		return ProcessRecordDataResult( 
			content: map['Content'] != null ? (map['Content'] as List).map((e)=>DataItemDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
		);
	}

	Map<String, dynamic> toJson() {
		final map = Map<String, dynamic>();
		if(content != null) {
			map['Content'] = content;
		}
		return map;
	}
}

enum AnimalSpeciesEnum {
	Bovine,
	Canidae,
	Equidae,
	Felidae,
	Caprinae,
	Suidae,
}

class ProcessRecordDataRequest extends TokenRequest{
	String? methodName;
	List<DataItemDTO>? content;
	OrganizationPatientTypeEnum patientType;
	AnimalSpeciesEnum speciesEnum;

	ProcessRecordDataRequest({
		this.methodName,
		this.content,
		this.patientType = OrganizationPatientTypeEnum.Person,
		this.speciesEnum = AnimalSpeciesEnum.Bovine,
		String? token,
	}) : super(
			token: token,
		);

	factory ProcessRecordDataRequest.fromJson(Map<String, dynamic> map) {
		return ProcessRecordDataRequest( 
			methodName: map['MethodName'],
			content: map['Content'] != null ? (map['Content'] as List).map((e)=>DataItemDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
			patientType: OrganizationPatientTypeEnum.values.firstWhere((e) => e.index == map['PatientType']),
			speciesEnum: AnimalSpeciesEnum.values.firstWhere((e) => e.index == map['SpeciesEnum']),
			token: map['Token'],
		);
	}

	Map<String, dynamic> toJson() {
		final map = super.toJson();
		if(methodName != null)
			map['MethodName'] = methodName;
		if(content != null)
			map['Content'] = content;
		map['PatientType'] = patientType.index;
		map['SpeciesEnum'] = speciesEnum.index;
		return map;
	}
}

class RelevanceRecordRequest extends TokenRequest{
	String? examCode;
	String? rservationCode;

	RelevanceRecordRequest({
		this.examCode,
		this.rservationCode,
		String? token,
	}) : super(
			token: token,
		);

	factory RelevanceRecordRequest.fromJson(Map<String, dynamic> map) {
		return RelevanceRecordRequest( 
			examCode: map['ExamCode'],
			rservationCode: map['RservationCode'],
			token: map['Token'],
		);
	}

	Map<String, dynamic> toJson() {
		final map = super.toJson();
		if(examCode != null)
			map['ExamCode'] = examCode;
		if(rservationCode != null)
			map['RservationCode'] = rservationCode;
		return map;
	}
}

class FinishRecordRequest extends TokenRequest{
	String? recordCode;

	FinishRecordRequest({
		this.recordCode,
		String? token,
	}) : super(
			token: token,
		);

	factory FinishRecordRequest.fromJson(Map<String, dynamic> map) {
		return FinishRecordRequest( 
			recordCode: map['RecordCode'],
			token: map['Token'],
		);
	}

	Map<String, dynamic> toJson() {
		final map = super.toJson();
		if(recordCode != null)
			map['RecordCode'] = recordCode;
		return map;
	}
}

class AddRemedicalMeasuredInfoDTO {
	String? remedicalCode;
	int frameIndex;
	String? measuredFileToken;
	String? previewFileToken;
	String? measuredData;

	AddRemedicalMeasuredInfoDTO({
		this.remedicalCode,
		this.frameIndex = 0,
		this.measuredFileToken,
		this.previewFileToken,
		this.measuredData,
	});

	factory AddRemedicalMeasuredInfoDTO.fromJson(Map<String, dynamic> map) {
		return AddRemedicalMeasuredInfoDTO( 
			remedicalCode: map['RemedicalCode'],
			frameIndex: map['FrameIndex'],
			measuredFileToken: map['MeasuredFileToken'],
			previewFileToken: map['PreviewFileToken'],
			measuredData: map['MeasuredData'],
		);
	}

	Map<String, dynamic> toJson() {
		final map = Map<String, dynamic>();
		if(remedicalCode != null) {
			map['RemedicalCode'] = remedicalCode;
		}
		map['FrameIndex'] = frameIndex;
		if(measuredFileToken != null) {
			map['MeasuredFileToken'] = measuredFileToken;
		}
		if(previewFileToken != null) {
			map['PreviewFileToken'] = previewFileToken;
		}
		if(measuredData != null) {
			map['MeasuredData'] = measuredData;
		}
		return map;
	}
}

class AddRemedicalMeasuredInfoRequest extends TokenRequest{
	BusinessTypeEnum businessType;
	String? recordCode;
	List<AddRemedicalMeasuredInfoDTO>? remedicalMeasuredInfos;

	AddRemedicalMeasuredInfoRequest({
		this.businessType = BusinessTypeEnum.RemoteDiagnosis,
		this.recordCode,
		this.remedicalMeasuredInfos,
		String? token,
	}) : super(
			token: token,
		);

	factory AddRemedicalMeasuredInfoRequest.fromJson(Map<String, dynamic> map) {
		return AddRemedicalMeasuredInfoRequest( 
			businessType: BusinessTypeEnum.values.firstWhere((e) => e.index == map['BusinessType']),
			recordCode: map['RecordCode'],
			remedicalMeasuredInfos: map['RemedicalMeasuredInfos'] != null ? (map['RemedicalMeasuredInfos'] as List).map((e)=>AddRemedicalMeasuredInfoDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
			token: map['Token'],
		);
	}

	Map<String, dynamic> toJson() {
		final map = super.toJson();
		map['BusinessType'] = businessType.index;
		if(recordCode != null)
			map['RecordCode'] = recordCode;
		if(remedicalMeasuredInfos != null)
			map['RemedicalMeasuredInfos'] = remedicalMeasuredInfos;
		return map;
	}
}

class FindRemedicalMeasuredInfoRequest extends TokenRequest{
	BusinessTypeEnum businessType;
	String? recordCode;

	FindRemedicalMeasuredInfoRequest({
		this.businessType = BusinessTypeEnum.RemoteDiagnosis,
		this.recordCode,
		String? token,
	}) : super(
			token: token,
		);

	factory FindRemedicalMeasuredInfoRequest.fromJson(Map<String, dynamic> map) {
		return FindRemedicalMeasuredInfoRequest( 
			businessType: BusinessTypeEnum.values.firstWhere((e) => e.index == map['BusinessType']),
			recordCode: map['RecordCode'],
			token: map['Token'],
		);
	}

	Map<String, dynamic> toJson() {
		final map = super.toJson();
		map['BusinessType'] = businessType.index;
		if(recordCode != null)
			map['RecordCode'] = recordCode;
		return map;
	}
}

class CheckCollectingImgRequest extends TokenRequest{
	String? deviceCode;

	CheckCollectingImgRequest({
		this.deviceCode,
		String? token,
	}) : super(
			token: token,
		);

	factory CheckCollectingImgRequest.fromJson(Map<String, dynamic> map) {
		return CheckCollectingImgRequest( 
			deviceCode: map['DeviceCode'],
			token: map['Token'],
		);
	}

	Map<String, dynamic> toJson() {
		final map = super.toJson();
		if(deviceCode != null)
			map['DeviceCode'] = deviceCode;
		return map;
	}
}

class StartCollectingImgRequest extends TokenRequest{
	String? recordCode;

	StartCollectingImgRequest({
		this.recordCode,
		String? token,
	}) : super(
			token: token,
		);

	factory StartCollectingImgRequest.fromJson(Map<String, dynamic> map) {
		return StartCollectingImgRequest( 
			recordCode: map['RecordCode'],
			token: map['Token'],
		);
	}

	Map<String, dynamic> toJson() {
		final map = super.toJson();
		if(recordCode != null)
			map['RecordCode'] = recordCode;
		return map;
	}
}

enum ReferralTypeEnum {
	Normal,
	ReferralIn,
	ReferralOut,
}

class SimpleRecordInfoDTO extends BaseDTO{
	String? recordCode;
	RecordStatusEnum recordStatus;
	ReferralTypeEnum referralType;
	String? patientCode;
	String? patientName;
	String? age;
	String? sex;
	String? devicePatientID;
	String? deviceCode;
	String? deviceName;
	String? rootOrganizationCode;
	String? rootOrganizationName;
	String? languge;
	bool canCreateReport;
	bool isCollecting;
	bool canCollcetImg;
	String? customDoctor;
	String? customOrganzation;
	String? equipmentSN;
	List<DiagnosisInfoDTO>? diagnosisInfos;

	SimpleRecordInfoDTO({
		this.recordCode,
		this.recordStatus = RecordStatusEnum.NotScanned,
		this.referralType = ReferralTypeEnum.Normal,
		this.patientCode,
		this.patientName,
		this.age,
		this.sex,
		this.devicePatientID,
		this.deviceCode,
		this.deviceName,
		this.rootOrganizationCode,
		this.rootOrganizationName,
		this.languge,
		this.canCreateReport = false,
		this.isCollecting = false,
		this.canCollcetImg = false,
		this.customDoctor,
		this.customOrganzation,
		this.equipmentSN,
		this.diagnosisInfos,
		DateTime? createTime,
		DateTime? updateTime,
	}) : super(
			createTime: createTime,
			updateTime: updateTime,
		);

	factory SimpleRecordInfoDTO.fromJson(Map<String, dynamic> map) {
		return SimpleRecordInfoDTO( 
			recordCode: map['RecordCode'],
			recordStatus: RecordStatusEnum.values.firstWhere((e) => e.index == map['RecordStatus']),
			referralType: ReferralTypeEnum.values.firstWhere((e) => e.index == map['ReferralType']),
			patientCode: map['PatientCode'],
			patientName: map['PatientName'],
			age: map['Age'],
			sex: map['Sex'],
			devicePatientID: map['DevicePatientID'],
			deviceCode: map['DeviceCode'],
			deviceName: map['DeviceName'],
			rootOrganizationCode: map['RootOrganizationCode'],
			rootOrganizationName: map['RootOrganizationName'],
			languge: map['Languge'],
			canCreateReport: map['CanCreateReport'],
			isCollecting: map['IsCollecting'],
			canCollcetImg: map['CanCollcetImg'],
			customDoctor: map['CustomDoctor'],
			customOrganzation: map['CustomOrganzation'],
			equipmentSN: map['EquipmentSN'],
			diagnosisInfos: map['DiagnosisInfos'] != null ? (map['DiagnosisInfos'] as List).map((e)=>DiagnosisInfoDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
			createTime: map['CreateTime'] != null ? DateTime.parse(map['CreateTime']) : null,
			updateTime: map['UpdateTime'] != null ? DateTime.parse(map['UpdateTime']) : null,
		);
	}

	Map<String, dynamic> toJson() {
		final map = super.toJson();
		if(recordCode != null)
			map['RecordCode'] = recordCode;
		map['RecordStatus'] = recordStatus.index;
		map['ReferralType'] = referralType.index;
		if(patientCode != null)
			map['PatientCode'] = patientCode;
		if(patientName != null)
			map['PatientName'] = patientName;
		if(age != null)
			map['Age'] = age;
		if(sex != null)
			map['Sex'] = sex;
		if(devicePatientID != null)
			map['DevicePatientID'] = devicePatientID;
		if(deviceCode != null)
			map['DeviceCode'] = deviceCode;
		if(deviceName != null)
			map['DeviceName'] = deviceName;
		if(rootOrganizationCode != null)
			map['RootOrganizationCode'] = rootOrganizationCode;
		if(rootOrganizationName != null)
			map['RootOrganizationName'] = rootOrganizationName;
		if(languge != null)
			map['Languge'] = languge;
		map['CanCreateReport'] = canCreateReport;
		map['IsCollecting'] = isCollecting;
		map['CanCollcetImg'] = canCollcetImg;
		if(customDoctor != null)
			map['CustomDoctor'] = customDoctor;
		if(customOrganzation != null)
			map['CustomOrganzation'] = customOrganzation;
		if(equipmentSN != null)
			map['EquipmentSN'] = equipmentSN;
		if(diagnosisInfos != null)
			map['DiagnosisInfos'] = diagnosisInfos;
		return map;
	}
}

enum RecordQueryStateEnum {
	All,
	NotScanned,
	Uploaded,
	NotReport,
	Completed,
}

enum RecordProcessStateEnum {
	All,
	Wait,
	Done,
	ReferralOut,
}

class FindRecordPagesRequest extends PageRequest{
	List<String>? organizationCodes;
	List<String>? deviceCodes;
	RecordQueryStateEnum recordQueryState;
	RecordProcessStateEnum recordProcessState;
	String? language;
	String? keyWord;
	DateTime? startTime;
	DateTime? endTime;
	String? patientCode;

	FindRecordPagesRequest({
		this.organizationCodes,
		this.deviceCodes,
		this.recordQueryState = RecordQueryStateEnum.All,
		this.recordProcessState = RecordProcessStateEnum.All,
		this.language,
		this.keyWord,
		this.startTime,
		this.endTime,
		this.patientCode,
		int pageIndex = 0,
		int pageSize = 0,
		String? token,
	}) : super(
			pageIndex: pageIndex,
			pageSize: pageSize,
			token: token,
		);

	factory FindRecordPagesRequest.fromJson(Map<String, dynamic> map) {
		return FindRecordPagesRequest( 
			organizationCodes: map['OrganizationCodes']?.cast<String>().toList(),
			deviceCodes: map['DeviceCodes']?.cast<String>().toList(),
			recordQueryState: RecordQueryStateEnum.values.firstWhere((e) => e.index == map['RecordQueryState']),
			recordProcessState: RecordProcessStateEnum.values.firstWhere((e) => e.index == map['RecordProcessState']),
			language: map['Language'],
			keyWord: map['KeyWord'],
			startTime: map['StartTime'] != null ? DateTime.parse(map['StartTime']) : null,
			endTime: map['EndTime'] != null ? DateTime.parse(map['EndTime']) : null,
			patientCode: map['PatientCode'],
			pageIndex: map['PageIndex'],
			pageSize: map['PageSize'],
			token: map['Token'],
		);
	}

	Map<String, dynamic> toJson() {
		final map = super.toJson();
		if(organizationCodes != null)
			map['OrganizationCodes'] = organizationCodes;
		if(deviceCodes != null)
			map['DeviceCodes'] = deviceCodes;
		map['RecordQueryState'] = recordQueryState.index;
		map['RecordProcessState'] = recordProcessState.index;
		if(language != null)
			map['Language'] = language;
		if(keyWord != null)
			map['KeyWord'] = keyWord;
		if(startTime != null)
			map['StartTime'] = JsonRpcUtils.dateFormat(startTime!);
		if(endTime != null)
			map['EndTime'] = JsonRpcUtils.dateFormat(endTime!);
		if(patientCode != null)
			map['PatientCode'] = patientCode;
		return map;
	}
}

class CreateRecordNewRequest extends TokenRequest{
	String? patientCode;
	List<DataItemDTO>? patientDatas;
	String? deviceCode;
	List<PatientInfoExt>? patientInfoExtList;

	CreateRecordNewRequest({
		this.patientCode,
		this.patientDatas,
		this.deviceCode,
		this.patientInfoExtList,
		String? token,
	}) : super(
			token: token,
		);

	factory CreateRecordNewRequest.fromJson(Map<String, dynamic> map) {
		return CreateRecordNewRequest( 
			patientCode: map['PatientCode'],
			patientDatas: map['PatientDatas'] != null ? (map['PatientDatas'] as List).map((e)=>DataItemDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
			deviceCode: map['DeviceCode'],
			patientInfoExtList: map['PatientInfoExtList'] != null ? (map['PatientInfoExtList'] as List).map((e)=>PatientInfoExt.fromJson(e as Map<String,dynamic>)).toList() : null,
			token: map['Token'],
		);
	}

	Map<String, dynamic> toJson() {
		final map = super.toJson();
		if(patientCode != null)
			map['PatientCode'] = patientCode;
		if(patientDatas != null)
			map['PatientDatas'] = patientDatas;
		if(deviceCode != null)
			map['DeviceCode'] = deviceCode;
		if(patientInfoExtList != null)
			map['PatientInfoExtList'] = patientInfoExtList;
		return map;
	}
}

class CreateReferralRecordNewRequest extends TokenRequest{
	String? recordCode;
	String? referralOrganizationCode;
	String? referralUserCode;
	String? subjectMatter;

	CreateReferralRecordNewRequest({
		this.recordCode,
		this.referralOrganizationCode,
		this.referralUserCode,
		this.subjectMatter,
		String? token,
	}) : super(
			token: token,
		);

	factory CreateReferralRecordNewRequest.fromJson(Map<String, dynamic> map) {
		return CreateReferralRecordNewRequest( 
			recordCode: map['RecordCode'],
			referralOrganizationCode: map['ReferralOrganizationCode'],
			referralUserCode: map['ReferralUserCode'],
			subjectMatter: map['SubjectMatter'],
			token: map['Token'],
		);
	}

	Map<String, dynamic> toJson() {
		final map = super.toJson();
		if(recordCode != null)
			map['RecordCode'] = recordCode;
		if(referralOrganizationCode != null)
			map['ReferralOrganizationCode'] = referralOrganizationCode;
		if(referralUserCode != null)
			map['ReferralUserCode'] = referralUserCode;
		if(subjectMatter != null)
			map['SubjectMatter'] = subjectMatter;
		return map;
	}
}

class WithdrawReferralForRecordListRequest extends TokenRequest{
	String? recordCode;

	WithdrawReferralForRecordListRequest({
		this.recordCode,
		String? token,
	}) : super(
			token: token,
		);

	factory WithdrawReferralForRecordListRequest.fromJson(Map<String, dynamic> map) {
		return WithdrawReferralForRecordListRequest( 
			recordCode: map['RecordCode'],
			token: map['Token'],
		);
	}

	Map<String, dynamic> toJson() {
		final map = super.toJson();
		if(recordCode != null)
			map['RecordCode'] = recordCode;
		return map;
	}
}

enum RecordReferralStatusEnum {
	ReferralIn,
	Processed,
	Withdrawn,
}

class ReferralData extends BaseDTO{
	String? patientName;
	String? code;
	String? recordCode;
	String? referralOutUserCode;
	String? referralOutOrganizationCode;
	String? referralInUserCode;
	String? referralInOrganizationCode;
	RecordReferralStatusEnum referralStatus;
	DateTime? referralTime;
	String? subjectMatter;

	ReferralData({
		this.patientName,
		this.code,
		this.recordCode,
		this.referralOutUserCode,
		this.referralOutOrganizationCode,
		this.referralInUserCode,
		this.referralInOrganizationCode,
		this.referralStatus = RecordReferralStatusEnum.ReferralIn,
		this.referralTime,
		this.subjectMatter,
		DateTime? createTime,
		DateTime? updateTime,
	}) : super(
			createTime: createTime,
			updateTime: updateTime,
		);

	factory ReferralData.fromJson(Map<String, dynamic> map) {
		return ReferralData( 
			patientName: map['PatientName'],
			code: map['Code'],
			recordCode: map['RecordCode'],
			referralOutUserCode: map['ReferralOutUserCode'],
			referralOutOrganizationCode: map['ReferralOutOrganizationCode'],
			referralInUserCode: map['ReferralInUserCode'],
			referralInOrganizationCode: map['ReferralInOrganizationCode'],
			referralStatus: RecordReferralStatusEnum.values.firstWhere((e) => e.index == map['ReferralStatus']),
			referralTime: map['ReferralTime'] != null ? DateTime.parse(map['ReferralTime']) : null,
			subjectMatter: map['SubjectMatter'],
			createTime: map['CreateTime'] != null ? DateTime.parse(map['CreateTime']) : null,
			updateTime: map['UpdateTime'] != null ? DateTime.parse(map['UpdateTime']) : null,
		);
	}

	Map<String, dynamic> toJson() {
		final map = super.toJson();
		if(patientName != null)
			map['PatientName'] = patientName;
		if(code != null)
			map['Code'] = code;
		if(recordCode != null)
			map['RecordCode'] = recordCode;
		if(referralOutUserCode != null)
			map['ReferralOutUserCode'] = referralOutUserCode;
		if(referralOutOrganizationCode != null)
			map['ReferralOutOrganizationCode'] = referralOutOrganizationCode;
		if(referralInUserCode != null)
			map['ReferralInUserCode'] = referralInUserCode;
		if(referralInOrganizationCode != null)
			map['ReferralInOrganizationCode'] = referralInOrganizationCode;
		map['ReferralStatus'] = referralStatus.index;
		if(referralTime != null)
			map['ReferralTime'] = JsonRpcUtils.dateFormat(referralTime!);
		if(subjectMatter != null)
			map['SubjectMatter'] = subjectMatter;
		return map;
	}
}

class ReferralHistoryDetail extends ReferralData{
	String? referralOutOrganizationName;
	String? referralOutUserName;
	String? referralInOrganizationName;
	String? referralInUserName;

	ReferralHistoryDetail({
		this.referralOutOrganizationName,
		this.referralOutUserName,
		this.referralInOrganizationName,
		this.referralInUserName,
		String? patientName,
		String? code,
		String? recordCode,
		String? referralOutUserCode,
		String? referralOutOrganizationCode,
		String? referralInUserCode,
		String? referralInOrganizationCode,
		RecordReferralStatusEnum referralStatus = RecordReferralStatusEnum.ReferralIn,
		DateTime? referralTime,
		String? subjectMatter,
		DateTime? createTime,
		DateTime? updateTime,
	}) : super(
			patientName: patientName,
			code: code,
			recordCode: recordCode,
			referralOutUserCode: referralOutUserCode,
			referralOutOrganizationCode: referralOutOrganizationCode,
			referralInUserCode: referralInUserCode,
			referralInOrganizationCode: referralInOrganizationCode,
			referralStatus: referralStatus,
			referralTime: referralTime,
			subjectMatter: subjectMatter,
			createTime: createTime,
			updateTime: updateTime,
		);

	factory ReferralHistoryDetail.fromJson(Map<String, dynamic> map) {
		return ReferralHistoryDetail( 
			referralOutOrganizationName: map['ReferralOutOrganizationName'],
			referralOutUserName: map['ReferralOutUserName'],
			referralInOrganizationName: map['ReferralInOrganizationName'],
			referralInUserName: map['ReferralInUserName'],
			patientName: map['PatientName'],
			code: map['Code'],
			recordCode: map['RecordCode'],
			referralOutUserCode: map['ReferralOutUserCode'],
			referralOutOrganizationCode: map['ReferralOutOrganizationCode'],
			referralInUserCode: map['ReferralInUserCode'],
			referralInOrganizationCode: map['ReferralInOrganizationCode'],
			referralStatus: RecordReferralStatusEnum.values.firstWhere((e) => e.index == map['ReferralStatus']),
			referralTime: map['ReferralTime'] != null ? DateTime.parse(map['ReferralTime']) : null,
			subjectMatter: map['SubjectMatter'],
			createTime: map['CreateTime'] != null ? DateTime.parse(map['CreateTime']) : null,
			updateTime: map['UpdateTime'] != null ? DateTime.parse(map['UpdateTime']) : null,
		);
	}

	Map<String, dynamic> toJson() {
		final map = super.toJson();
		if(referralOutOrganizationName != null)
			map['ReferralOutOrganizationName'] = referralOutOrganizationName;
		if(referralOutUserName != null)
			map['ReferralOutUserName'] = referralOutUserName;
		if(referralInOrganizationName != null)
			map['ReferralInOrganizationName'] = referralInOrganizationName;
		if(referralInUserName != null)
			map['ReferralInUserName'] = referralInUserName;
		return map;
	}
}

class FindReferralHistoryRequest extends TokenRequest{
	String? recordCode;
	String? languageCode;

	FindReferralHistoryRequest({
		this.recordCode,
		this.languageCode,
		String? token,
	}) : super(
			token: token,
		);

	factory FindReferralHistoryRequest.fromJson(Map<String, dynamic> map) {
		return FindReferralHistoryRequest( 
			recordCode: map['RecordCode'],
			languageCode: map['LanguageCode'],
			token: map['Token'],
		);
	}

	Map<String, dynamic> toJson() {
		final map = super.toJson();
		if(recordCode != null)
			map['RecordCode'] = recordCode;
		if(languageCode != null)
			map['LanguageCode'] = languageCode;
		return map;
	}
}