import {Mongo} from "meteor/mongo";
import {Meteor} from "meteor/meteor";
import {check} from "meteor/check";
import {Assets} from "/imports/api/assets";
import {Students} from "/imports/api/students";
import {Staff} from "/imports/api/staff";
import {AssetTypes} from "/imports/api/asset-types";

export const AssetAssignmentHistory = new Mongo.Collection('assetAssignmentHistory');

/*
Maintains a historical record of asset assignments.
assetKey: The MongoID of the asset.  AssetID's could be reused, so this prevents that eventuality from messing up historical records.
assetId: The asset's assigned ID (not a MongoID).
serial: The asset's serial number (part of the device, or defined by the manufacturer).  In some cases this may be a partial serial.  It is not a unique identifier, but should be mostly unique.  This might be undefined if a serial was never provided for the original asset.
assetTypeName: The name of the asset type, or "UNK" if one could not be found (shouldn't happen).  This is stored because these records could be kept longer than the assets in the system.
assigneeType: One of 'Student' or 'Staff'.
assigneeId: The MongoID of the student or staff the asset was assigned to.
startDate: The date/time of the assignment.
endDate: The date/time of the unassignment.
comment: A text block detailing the reason for the unassignment of the device.  Eg: 'Broke Screen' or 'End of year' or 'Not charging' or 'Needs replacement'.
startCondition: One of the condition options: [New, Like New, Good, Okay, Damaged] (see assets.unassign for details).
endCondition: One of the condition options: [New, Like New, Good, Okay, Damaged] (see assets.unassign for details).
startConditionDetails: An optional text block for details on the condition.
endConditionDetails: An optional text block for details on the condition.
 */


if (Meteor.isServer) {
	Meteor.methods({
		/**
		 * Collects historical data on asset assignments.
		 * @param params An object with a single attribute.  The attribute must be one of: email, deviceId, assetId, serial, staffId, or studentId.  It will find all Assignment data for the given attribute value.
		 * @returns {any} Array of Asset Assignment History objects.
		 */
		'AssetAssignmentHistory.get'(params) {
			if(Roles.userIsInRole(Meteor.userId(), "laptop-management", {anyScope:true})) {
				let query = {};

				if(params.studentId) check(params.studentId, String)
				if(params.staffId) check(params.staffId, String)
				if(params.assetId) check(params.assetId, String)
				if(params.serial) check(params.serial, String)
				if(params.deviceId) check(params.deviceId, String)
				if(params.email) check(params.email, String)

				if(params.email) {
					let person = Students.findOne({email: params.email})

					if(person) params.studentId = person._id;
					else {
						person = Staff.findOne({email: params.email})

						if(person) params.staffId = person._id;
						// else throw new Meteor.Error("Could not find a student or staff member with the given email.")
					}
				}

				if(params.serial) query.serial = params.serial;
				else if(params.assetId) query.assetId = params.assetId;
				else if(params.deviceId) query.deviceId = params.deviceId;
				else if(params.studentId) {
					query.assigneeId = params.studentId
					query.assigneeType = "Student"
				}
				else if(params.staffId) {
					query.assigneeId = params.staffId
					query.assigneeType = "Staff"
				}
				else {
					query = undefined;
				}
				
				if(query) {
					//Sort by the last time the record was updated from most to least recent.
					let result = AssetAssignmentHistory.find(query, {sort: {endDate: -1}}).fetch();
					let assets = [];
					
					// Get the current assignment for the device or person.
					if(query.assetId || query.deviceId || query.serial) {
						let asset = Assets.findOne(query)
						
						if(asset) assets = [asset]
					}
					else {
						// Find the assets assigned to the person.
						assets = Assets.find({assigneeId: params.studentId ? params.studentId : params.staffId}).fetch()
					}
					
					// Prepend a partial assignment history record to the list.  We want to show active assignments in the results.
					for(let asset of assets) {
						if(asset && asset.assigneeId) {
							let assetType = AssetTypes.findOne(asset.assetTypeId)
							let current = {
								_id: 0,
								assetKey: asset._id,
								assetId: asset.assetId,
								serial: asset.serial,
								assetTypeName: assetType.name,
								assigneeType: asset.assigneeType,
								assigneeId: asset.assigneeId,
								startDate: asset.assignmentDate,
								startCondition: asset.condition,
								startConditionDetails: asset.conditionDetails
							}

							result = [current, ...result]
						}
					}

					//Add some additional data to the records.
					for(let next of result) {
						// console.log(next)
						if(next.assetKey) {
							next.asset = Assets.findOne({_id: next.assetKey})
						}
						else if(next.assetId) {
							next.asset = Assets.findOne({assetId: next.assetId});
						}

						if(next.asset) {
							next.assetType = AssetTypes.findOne({_id: next.asset.assetType})
						}

						if(next.assigneeId) {
							next.assignee = next.asset.assigneeType === "Student" ? Students.findOne({_id: next.assigneeId}) : Staff.findOne({_id: next.assigneeId})
						}
					}

					return result;
				} else return null;
			}
			else return null;
		}
	});
}