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

import 'package:fis_jsonrpc/utils.dart';

class CreatePatientRequest extends TokenRequest{
	List<DataItemDTO>? patientData;
	List<String>? assignmentUserCodes;

	CreatePatientRequest({
		this.patientData,
		this.assignmentUserCodes,
		String? token,
	}) : super(
			token: token,
		);

	factory CreatePatientRequest.fromJson(Map<String, dynamic> map) {
		return CreatePatientRequest( 
			patientData: map['PatientData'] != null ? (map['PatientData'] as List).map((e)=>DataItemDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
			assignmentUserCodes: map['AssignmentUserCodes']?.cast<String>().toList(),
			token: map['Token'],
		);
	}

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

class CreatePatientByUnregisteredRequest extends TokenRequest{
	String? unregisteredPatientCode;
	String? patientName;

	CreatePatientByUnregisteredRequest({
		this.unregisteredPatientCode,
		this.patientName,
		String? token,
	}) : super(
			token: token,
		);

	factory CreatePatientByUnregisteredRequest.fromJson(Map<String, dynamic> map) {
		return CreatePatientByUnregisteredRequest( 
			unregisteredPatientCode: map['UnregisteredPatientCode'],
			patientName: map['PatientName'],
			token: map['Token'],
		);
	}

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

class UpdatePatientRequest extends TokenRequest{
	String? code;
	List<DataItemDTO>? patientData;
	List<String>? assignmentUserCodes;

	UpdatePatientRequest({
		this.code,
		this.patientData,
		this.assignmentUserCodes,
		String? token,
	}) : super(
			token: token,
		);

	factory UpdatePatientRequest.fromJson(Map<String, dynamic> map) {
		return UpdatePatientRequest( 
			code: map['Code'],
			patientData: map['PatientData'] != null ? (map['PatientData'] as List).map((e)=>DataItemDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
			assignmentUserCodes: map['AssignmentUserCodes']?.cast<String>().toList(),
			token: map['Token'],
		);
	}

	Map<String, dynamic> toJson() {
		final map = super.toJson();
		if (code != null)
			map['Code'] = code;
		if (patientData != null)
			map['PatientData'] = patientData;
		if (assignmentUserCodes != null)
			map['AssignmentUserCodes'] = assignmentUserCodes;
		return map;
	}
}

class PatientInfoBaseDTO extends BaseDTO{
	String? patientCode;
	String? name;
	String? phone;
	String? identityCard;
	String? insuranceCode;
	String? age;
	int gender;
	bool isValid;
	String? organizationCode;
	String? rootOrganizationCode;
	List<String>? assignmentUserCodes;
	List<DataItemDTO>? patientData;
	int unReadRecordCount;
	String? headImgUrl;
	String? patientType;
	bool isReferral;
	List<String>? devicePatientIDs;
	bool isFromDicom;

	PatientInfoBaseDTO({
		this.patientCode,
		this.name,
		this.phone,
		this.identityCard,
		this.insuranceCode,
		this.age,
		this.gender = 0,
		this.isValid = false,
		this.organizationCode,
		this.rootOrganizationCode,
		this.assignmentUserCodes,
		this.patientData,
		this.unReadRecordCount = 0,
		this.headImgUrl,
		this.patientType,
		this.isReferral = false,
		this.devicePatientIDs,
		this.isFromDicom = false,
		DateTime? createTime,
		DateTime? updateTime,
	}) : super(
			createTime: createTime,
			updateTime: updateTime,
		);

	factory PatientInfoBaseDTO.fromJson(Map<String, dynamic> map) {
		return PatientInfoBaseDTO( 
			patientCode: map['PatientCode'],
			name: map['Name'],
			phone: map['Phone'],
			identityCard: map['IdentityCard'],
			insuranceCode: map['InsuranceCode'],
			age: map['Age'],
			gender: map['Gender'],
			isValid: map['IsValid'],
			organizationCode: map['OrganizationCode'],
			rootOrganizationCode: map['RootOrganizationCode'],
			assignmentUserCodes: map['AssignmentUserCodes']?.cast<String>().toList(),
			patientData: map['PatientData'] != null ? (map['PatientData'] as List).map((e)=>DataItemDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
			unReadRecordCount: map['UnReadRecordCount'],
			headImgUrl: map['HeadImgUrl'],
			patientType: map['PatientType'],
			isReferral: map['IsReferral'],
			devicePatientIDs: map['DevicePatientIDs']?.cast<String>().toList(),
			isFromDicom: map['IsFromDicom'],
			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 (patientCode != null)
			map['PatientCode'] = patientCode;
		if (name != null)
			map['Name'] = name;
		if (phone != null)
			map['Phone'] = phone;
		if (identityCard != null)
			map['IdentityCard'] = identityCard;
		if (insuranceCode != null)
			map['InsuranceCode'] = insuranceCode;
		if (age != null)
			map['Age'] = age;
		map['Gender'] = gender;
		map['IsValid'] = isValid;
		if (organizationCode != null)
			map['OrganizationCode'] = organizationCode;
		if (rootOrganizationCode != null)
			map['RootOrganizationCode'] = rootOrganizationCode;
		if (assignmentUserCodes != null)
			map['AssignmentUserCodes'] = assignmentUserCodes;
		if (patientData != null)
			map['PatientData'] = patientData;
		map['UnReadRecordCount'] = unReadRecordCount;
		if (headImgUrl != null)
			map['HeadImgUrl'] = headImgUrl;
		if (patientType != null)
			map['PatientType'] = patientType;
		map['IsReferral'] = isReferral;
		if (devicePatientIDs != null)
			map['DevicePatientIDs'] = devicePatientIDs;
		map['IsFromDicom'] = isFromDicom;
		return map;
	}
}

class PatientInfoDTO extends PatientInfoBaseDTO{
	String? creatorCode;
	String? deviceCode;
	List<String>? updateUsers;

	PatientInfoDTO({
		this.creatorCode,
		this.deviceCode,
		this.updateUsers,
		String? patientCode,
		String? name,
		String? phone,
		String? identityCard,
		String? insuranceCode,
		String? age,
		int gender = 0,
		bool isValid = false,
		String? organizationCode,
		String? rootOrganizationCode,
		List<String>? assignmentUserCodes,
		List<DataItemDTO>? patientData,
		int unReadRecordCount = 0,
		String? headImgUrl,
		String? patientType,
		bool isReferral = false,
		List<String>? devicePatientIDs,
		bool isFromDicom = false,
		DateTime? createTime,
		DateTime? updateTime,
	}) : super(
			patientCode: patientCode,
			name: name,
			phone: phone,
			identityCard: identityCard,
			insuranceCode: insuranceCode,
			age: age,
			gender: gender,
			isValid: isValid,
			organizationCode: organizationCode,
			rootOrganizationCode: rootOrganizationCode,
			assignmentUserCodes: assignmentUserCodes,
			patientData: patientData,
			unReadRecordCount: unReadRecordCount,
			headImgUrl: headImgUrl,
			patientType: patientType,
			isReferral: isReferral,
			devicePatientIDs: devicePatientIDs,
			isFromDicom: isFromDicom,
			createTime: createTime,
			updateTime: updateTime,
		);

	factory PatientInfoDTO.fromJson(Map<String, dynamic> map) {
		return PatientInfoDTO( 
			creatorCode: map['CreatorCode'],
			deviceCode: map['DeviceCode'],
			updateUsers: map['UpdateUsers']?.cast<String>().toList(),
			patientCode: map['PatientCode'],
			name: map['Name'],
			phone: map['Phone'],
			identityCard: map['IdentityCard'],
			insuranceCode: map['InsuranceCode'],
			age: map['Age'],
			gender: map['Gender'],
			isValid: map['IsValid'],
			organizationCode: map['OrganizationCode'],
			rootOrganizationCode: map['RootOrganizationCode'],
			assignmentUserCodes: map['AssignmentUserCodes']?.cast<String>().toList(),
			patientData: map['PatientData'] != null ? (map['PatientData'] as List).map((e)=>DataItemDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
			unReadRecordCount: map['UnReadRecordCount'],
			headImgUrl: map['HeadImgUrl'],
			patientType: map['PatientType'],
			isReferral: map['IsReferral'],
			devicePatientIDs: map['DevicePatientIDs']?.cast<String>().toList(),
			isFromDicom: map['IsFromDicom'],
			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 (creatorCode != null)
			map['CreatorCode'] = creatorCode;
		if (deviceCode != null)
			map['DeviceCode'] = deviceCode;
		if (updateUsers != null)
			map['UpdateUsers'] = updateUsers;
		return map;
	}
}

class CreatePatientsRequest extends TokenRequest{
	List<PatientInfoDTO>? patients;

	CreatePatientsRequest({
		this.patients,
		String? token,
	}) : super(
			token: token,
		);

	factory CreatePatientsRequest.fromJson(Map<String, dynamic> map) {
		return CreatePatientsRequest( 
			patients: map['Patients'] != null ? (map['Patients'] as List).map((e)=>PatientInfoDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
			token: map['Token'],
		);
	}

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

enum PatientValidStatusEnum {
	All,
	CheckOut,
	CheckIn,
}

class FindPatientsPageRequest extends PageRequest{
	String? keyWord;
	DateTime? startTime;
	DateTime? endTime;
	PatientValidStatusEnum isValid;
	List<String>? organizationCodes;
	List<String>? deviceCodes;
	String? patientCode;

	FindPatientsPageRequest({
		this.keyWord,
		this.startTime,
		this.endTime,
		this.isValid = PatientValidStatusEnum.All,
		this.organizationCodes,
		this.deviceCodes,
		this.patientCode,
		int pageIndex = 0,
		int pageSize = 0,
		String? token,
	}) : super(
			pageIndex: pageIndex,
			pageSize: pageSize,
			token: token,
		);

	factory FindPatientsPageRequest.fromJson(Map<String, dynamic> map) {
		return FindPatientsPageRequest( 
			keyWord: map['KeyWord'],
			startTime: map['StartTime'] != null ? DateTime.parse(map['StartTime']) : null,
			endTime: map['EndTime'] != null ? DateTime.parse(map['EndTime']) : null,
			isValid: PatientValidStatusEnum.values.firstWhere((e) => e.index == map['IsValid']),
			organizationCodes: map['OrganizationCodes']?.cast<String>().toList(),
			deviceCodes: map['DeviceCodes']?.cast<String>().toList(),
			patientCode: map['PatientCode'],
			pageIndex: map['PageIndex'],
			pageSize: map['PageSize'],
			token: map['Token'],
		);
	}

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

enum RecordStatusEnum {
	NotScanned,
	Uploaded,
	NotReport,
	Completed,
}

enum DiagnosisStatusEnum {
	NotRequired,
	Under,
	Completed,
}

enum DiagnosisReportStatusEnum {
	NotRequired,
	Reporting,
	Reported,
}

class DiagnosisInfoDTO {
	DiagnosisOrganEnum diagnosisOrgan;
	DiagnosisConclusionEnum conclusion;
	DiagnosisReportStatusEnum reportStatus;

	DiagnosisInfoDTO({
		this.diagnosisOrgan = DiagnosisOrganEnum.Null,
		this.conclusion = DiagnosisConclusionEnum.NotRequired,
		this.reportStatus = DiagnosisReportStatusEnum.NotRequired,
	});

	factory DiagnosisInfoDTO.fromJson(Map<String, dynamic> map) {
		return DiagnosisInfoDTO( 
			diagnosisOrgan: DiagnosisOrganEnum.values.firstWhere((e) => e.index == map['DiagnosisOrgan']),
			conclusion: DiagnosisConclusionEnum.values.firstWhere((e) => e.index == map['Conclusion']),
			reportStatus: DiagnosisReportStatusEnum.values.firstWhere((e) => e.index == map['ReportStatus']),
		);
	}

	Map<String, dynamic> toJson() {
		final map = Map<String, dynamic>();
		map['DiagnosisOrgan'] = diagnosisOrgan.index;
		map['Conclusion'] = conclusion.index;
		map['ReportStatus'] = reportStatus.index;
		return map;
	}
}

enum ReferralStatusEnum {
	Wait,
	Withdrawn,
	TimedOut,
	Accepted,
	Rejected,
}

class GetRecordsPageDTO {
	DateTime? createTime;
	String? deptName;
	String? creatorName;
	String? deviceName;
	String? displayName;
	String? reportNum;
	String? recordCode;
	RecordStatusEnum recordStatus;
	bool isRead;
	List<RemedicalInfoDTO>? remedicalList;
	DiagnosisStatusEnum diagnosisStatus;
	List<DiagnosisInfoDTO>? diagnosisInfos;
	bool isReferral;
	ReferralStatusEnum referralStatus;
	bool canCreateReport;
	String? deviceCode;
	bool isCollecting;
	bool canCollcetImg;
	String? customDoctor;
	String? customOrganzation;
	String? equipmentSN;

	GetRecordsPageDTO({
		this.createTime,
		this.deptName,
		this.creatorName,
		this.deviceName,
		this.displayName,
		this.reportNum,
		this.recordCode,
		this.recordStatus = RecordStatusEnum.NotScanned,
		this.isRead = false,
		this.remedicalList,
		this.diagnosisStatus = DiagnosisStatusEnum.NotRequired,
		this.diagnosisInfos,
		this.isReferral = false,
		this.referralStatus = ReferralStatusEnum.Wait,
		this.canCreateReport = false,
		this.deviceCode,
		this.isCollecting = false,
		this.canCollcetImg = false,
		this.customDoctor,
		this.customOrganzation,
		this.equipmentSN,
	});

	factory GetRecordsPageDTO.fromJson(Map<String, dynamic> map) {
		return GetRecordsPageDTO( 
			createTime: map['CreateTime'] != null ? DateTime.parse(map['CreateTime']) : null,
			deptName: map['DeptName'],
			creatorName: map['CreatorName'],
			deviceName: map['DeviceName'],
			displayName: map['DisplayName'],
			reportNum: map['ReportNum'],
			recordCode: map['RecordCode'],
			recordStatus: RecordStatusEnum.values.firstWhere((e) => e.index == map['RecordStatus']),
			isRead: map['IsRead'],
			remedicalList: map['RemedicalList'] != null ? (map['RemedicalList'] as List).map((e)=>RemedicalInfoDTO.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,
			isReferral: map['IsReferral'],
			referralStatus: ReferralStatusEnum.values.firstWhere((e) => e.index == map['ReferralStatus']),
			canCreateReport: map['CanCreateReport'],
			deviceCode: map['DeviceCode'],
			isCollecting: map['IsCollecting'],
			canCollcetImg: map['CanCollcetImg'],
			customDoctor: map['CustomDoctor'],
			customOrganzation: map['CustomOrganzation'],
			equipmentSN: map['EquipmentSN'],
		);
	}

	Map<String, dynamic> toJson() {
		final map = Map<String, dynamic>();
		if (createTime != null) {
			map['CreateTime'] = JsonRpcUtils.dateFormat(createTime!);
		}
		if (deptName != null) {
			map['DeptName'] = deptName;
		}
		if (creatorName != null) {
			map['CreatorName'] = creatorName;
		}
		if (deviceName != null) {
			map['DeviceName'] = deviceName;
		}
		if (displayName != null) {
			map['DisplayName'] = displayName;
		}
		if (reportNum != null) {
			map['ReportNum'] = reportNum;
		}
		if (recordCode != null) {
			map['RecordCode'] = recordCode;
		}
		map['RecordStatus'] = recordStatus.index;
		map['IsRead'] = isRead;
		if (remedicalList != null) {
			map['RemedicalList'] = remedicalList;
		}
		map['DiagnosisStatus'] = diagnosisStatus.index;
		if (diagnosisInfos != null) {
			map['DiagnosisInfos'] = diagnosisInfos;
		}
		map['IsReferral'] = isReferral;
		map['ReferralStatus'] = referralStatus.index;
		map['CanCreateReport'] = canCreateReport;
		if (deviceCode != null) {
			map['DeviceCode'] = deviceCode;
		}
		map['IsCollecting'] = isCollecting;
		map['CanCollcetImg'] = canCollcetImg;
		if (customDoctor != null) {
			map['CustomDoctor'] = customDoctor;
		}
		if (customOrganzation != null) {
			map['CustomOrganzation'] = customOrganzation;
		}
		if (equipmentSN != null) {
			map['EquipmentSN'] = equipmentSN;
		}
		return map;
	}
}

class ClientPatientInfoDTO extends ClientPatientInfoBaseDTO{
	String? creatorCode;
	String? creatorName;
	String? deviceCode;
	List<UserBaseDTO>? assignmentUserList;
	GetRecordsPageDTO? lastRecord;
	String? encryptFullName;

	ClientPatientInfoDTO({
		this.creatorCode,
		this.creatorName,
		this.deviceCode,
		this.assignmentUserList,
		this.lastRecord,
		this.encryptFullName,
		String? patientCode,
		bool isValid = false,
		List<DataItemDTO>? patientData,
		int unReadRecordCount = 0,
		bool isReferral = false,
		List<String>? devicePatientIDs,
		String? organizationCode,
		String? organizationName,
		DateTime? createTime,
		DateTime? updateTime,
	}) : super(
			patientCode: patientCode,
			isValid: isValid,
			patientData: patientData,
			unReadRecordCount: unReadRecordCount,
			isReferral: isReferral,
			devicePatientIDs: devicePatientIDs,
			organizationCode: organizationCode,
			organizationName: organizationName,
			createTime: createTime,
			updateTime: updateTime,
		);

	factory ClientPatientInfoDTO.fromJson(Map<String, dynamic> map) {
		return ClientPatientInfoDTO( 
			creatorCode: map['CreatorCode'],
			creatorName: map['CreatorName'],
			deviceCode: map['DeviceCode'],
			assignmentUserList: map['AssignmentUserList'] != null ? (map['AssignmentUserList'] as List).map((e)=>UserBaseDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
			lastRecord: map['LastRecord'] != null ? GetRecordsPageDTO.fromJson(map['LastRecord']) : null,
			encryptFullName: map['EncryptFullName'],
			patientCode: map['PatientCode'],
			isValid: map['IsValid'],
			patientData: map['PatientData'] != null ? (map['PatientData'] as List).map((e)=>DataItemDTO.fromJson(e as Map<String,dynamic>)).toList() : null,
			unReadRecordCount: map['UnReadRecordCount'],
			isReferral: map['IsReferral'],
			devicePatientIDs: map['DevicePatientIDs']?.cast<String>().toList(),
			organizationCode: map['OrganizationCode'],
			organizationName: map['OrganizationName'],
			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 (creatorCode != null)
			map['CreatorCode'] = creatorCode;
		if (creatorName != null)
			map['CreatorName'] = creatorName;
		if (deviceCode != null)
			map['DeviceCode'] = deviceCode;
		if (assignmentUserList != null)
			map['AssignmentUserList'] = assignmentUserList;
		if (lastRecord != null)
			map['LastRecord'] = lastRecord;
		if (encryptFullName != null)
			map['EncryptFullName'] = encryptFullName;
		return map;
	}
}

class FindPatientByCodeRequest extends TokenRequest{
	String? code;

	FindPatientByCodeRequest({
		this.code,
		String? token,
	}) : super(
			token: token,
		);

	factory FindPatientByCodeRequest.fromJson(Map<String, dynamic> map) {
		return FindPatientByCodeRequest( 
			code: map['Code'],
			token: map['Token'],
		);
	}

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

class FindValidPatientsByNameRequest extends TokenRequest{
	String? name;

	FindValidPatientsByNameRequest({
		this.name,
		String? token,
	}) : super(
			token: token,
		);

	factory FindValidPatientsByNameRequest.fromJson(Map<String, dynamic> map) {
		return FindValidPatientsByNameRequest( 
			name: map['Name'],
			token: map['Token'],
		);
	}

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

class SetValidPatientRequest extends TokenRequest{
	String? newPatientCode;
	String? oldPatientCode;
	bool isFinishExam;

	SetValidPatientRequest({
		this.newPatientCode,
		this.oldPatientCode,
		this.isFinishExam = false,
		String? token,
	}) : super(
			token: token,
		);

	factory SetValidPatientRequest.fromJson(Map<String, dynamic> map) {
		return SetValidPatientRequest( 
			newPatientCode: map['NewPatientCode'],
			oldPatientCode: map['OldPatientCode'],
			isFinishExam: map['IsFinishExam'],
			token: map['Token'],
		);
	}

	Map<String, dynamic> toJson() {
		final map = super.toJson();
		if (newPatientCode != null)
			map['NewPatientCode'] = newPatientCode;
		if (oldPatientCode != null)
			map['OldPatientCode'] = oldPatientCode;
		map['IsFinishExam'] = isFinishExam;
		return map;
	}
}

class RemovePatientsRequest extends TokenRequest{
	List<String>? patientCodes;

	RemovePatientsRequest({
		this.patientCodes,
		String? token,
	}) : super(
			token: token,
		);

	factory RemovePatientsRequest.fromJson(Map<String, dynamic> map) {
		return RemovePatientsRequest( 
			patientCodes: map['PatientCodes']?.cast<String>().toList(),
			token: map['Token'],
		);
	}

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