import {Mongo} from "meteor/mongo";
import {Meteor} from "meteor/meteor";
import { check } from 'meteor/check';
import { Roles } from 'meteor/alanning:roles';
//import SimpleSchema from "simpl-schema";
import {AssetTypes} from "./asset-types";
import {AssetAssignments} from "/imports/api/asset-assignments";
import {AssetAssignmentHistory} from "/imports/api/asset-assignment-history";

// console.log("Setting Up Assets...")

export const Assets = new Mongo.Collection('assets');

/*
const AssetsSchema = new SimpleSchema({
	assetTypeId: {
		type: String,
		label: "Asset Type ID",
		optional: false,
		trim: true,
	},
	assetId: {
		type: String,
		label: "Asset ID",
		optional: false,
		trim: true,
		index: 1,
		unique: true
	},
	serial: {
		type: String,
		label: "Serial",
		optional: true,
		trim: false,
		index: 1,
		unique: false
	},
	assigneeId: {  //Should be undefined or non-existent if not assigned.
		type: String,
		label: "Assignee ID",
		optional: true,
	},
	assigneeType: {  // 0: Student, 1: Staff, Should be undefined or non-existent if not assigned.
		type: SimpleSchema.Integer,
		label: "Assignee Type",
		optional: true,
		min: 0,
		max: 1,
		exclusiveMin: false,
		exclusiveMax: false,
	},
	assignmentDate: {
		type: Date,
		label: "Assignment Date",
		optional: true,
	}
});
Assets.attachSchema(AssetsSchema);
 */

if (Meteor.isServer) {
	// Drop any old indexes we no longer will use.  Create indexes we need.
	//try {Assets._dropIndex("serial")} catch(e) {}
	Assets.createIndex({assetId: 1}, {name: "AssetID", unique: true});
	Assets.createIndex({serial: 1}, {name: "Serial", unique: false});

	// This code only runs on the server
	Meteor.publish('assets', function() {
		return Assets.find({});
	});
}
Meteor.methods({
	'assets.add'(assetTypeId, assetId, serial) {
		check(assetTypeId, String);
		check(assetId, String);
		check(serial, String);
		
		// Convert the asset ID's to uppercase for storage to make searching easier.
		assetId = assetId.toUpperCase();

		if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
			let assetType = AssetTypes.findOne({assetTypeId});
			
			if(Assets.findOne({assetId})) {
				//return {error: true, errorType: 'duplicateAssetId'}
				throw new Meteor.Error("duplicateAssetId", "Cannot use the same asset ID twice.")
			}
			else if(serial) {
				Assets.insert({assetTypeId, assetId, serial});
			}
			else {
				Assets.insert({assetTypeId, assetId});
			}
		}
		else throw new Meteor.Error("User Permission Error");
	},
	'assets.update'(_id, assetId, serial) {
		check(_id, String);
		check(assetId, String);
		if(serial) check(serial, String);

		if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
			//TODO: Need to first verify there are no checked out assets to the staff member.
			Assets.update({_id}, {$set: {assetId, serial}});
		}
		else throw new Meteor.Error("User Permission Error");
	},
	'assets.remove'(_id) {
		check(_id, String);

		if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
			//TODO: Ensure we have not assigned this asset???  Not sure if we should require unassigning first.
			Assets.remove({_id});
		}
		else throw new Meteor.Error("User Permission Error");
	},
	/**
	 * Assigns the asset to the assignee.  The assignee should either be a Student or Staff member.
	 * @param assetId The Asset ID (eg: 'Z1Q') of the asset (asset.assetId).
	 * @param assigneeType One of: 'Student', 'Staff'
	 * @param assigneeId The Mongo ID of the Student or Staff (person._id).
	 * @param date The date/time of the action.  Will be set to the current date/time if not provided.
	 */
	'assets.assign'(assetId, assigneeType, assigneeId, date) {
		check(assigneeId, String);
		check(assigneeType, String);
		check(assetId, String);
		if(date) check(date, Date);
		
		if(!date) date = new Date();

		if(assigneeType !== 'Student' && assigneeType !== 'Staff') {
			// Should never happen.
			console.error("Error: Received incorrect assignee type in adding an assignment.");
			console.error(assigneeType);
			throw new Meteor.Error("Error: Received incorrect assignee type in adding an assignment.");
		}
		else if(Roles.userIsInRole(Meteor.userId(), "laptop-management", {anyScope:true})) {
			let asset = Assets.findOne({assetId});
			
			if(asset) {
				if(asset.assigneeId) {
					//TODO: Should we unassign and re-assign????
					console.error("Asset is already assigned!  " + assetId);
					throw new Meteor.Error("Asset is already assigned.", "Cannot assign an asset that has already been assigned.");
				}
				else {
					Assets.update({assetId}, {$set: {assigneeType, assigneeId, assignmentDate: date}});
				}
			}
			else {
				console.error("Could not find the asset: " + assetId)
			}
		}
		else throw new Meteor.Error("User Permission Error");
	},
	/**
	 * Removes an assignment for the asset.
	 * TODO: Should create a historical record.
	 * @param assetId The Asset ID (eg: 'Z1Q') of the asset (asset.assetId).
	 * @param date The date/time of the action.  Will be set to the current date/time if not provided.
	 */
	'assets.unassign'(assetId, date) {
		check(assetId, String);
		if(date) check(date, Date);
		
		if(!date) date = new Date();

		if(Roles.userIsInRole(Meteor.userId(), "laptop-management", {anyScope:true})) {
			let asset = Assets.findOne({assetId});
			
			if(asset) {
				try {
					AssetAssignmentHistory.insert({assetId, assigneeType: asset.assigneeType, assigneeId: asset.assigneeId, startDate: asset.assignmentDate, endDate: date});
				} catch (e) {
					console.error(e);
				}
				Assets.update({assetId}, {$unset: {assigneeType, assigneeId, assignmentDate}});
			}
			else {
				console.error("Could not find the asset: " + assetId);
				throw new Meteor.Error("Could not find the asset: " + assetId);
			}
		}
		else throw new Meteor.Error("User Permission Error");
	},
	/**
	 * A fix to remove the AssetAssignment collection and merge it with the Asset collection.
	 */
	'assets.fixAssetAssignments'() {
		// Removed this since it should no longer be relevant.
		
		// let assignmentDate = new Date();
		// //This function just removes the need for the asset-assignments collection and merges it with assets.
		// if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
		// 	let assets = Assets.find({}).fetch();
		// 	let assetAssignments = AssetAssignments.find({}).fetch();
		//	
		// 	let assetMap = assets.reduce((map, obj) => {
		// 		map[obj.assetId] = obj;
		// 		return map;
		// 	}, {});
		//	
		// 	console.log(assetMap);
		// 	console.log("");
		//	
		// 	for(let next of assetAssignments) {
		// 		console.log(next);
		// 		let asset = assetMap[next.assetId];
		// 		console.log("Updating " + asset.assetId + " to be assigned to " + next.assigneeType + ": " + next.assigneeId);
		// 		let c = Assets.update({assetId: asset.assetId}, {$set: {assigneeType: next.assigneeType, assigneeId: next.assigneeId, assignmentDate}});
		// 		console.log("Updated " + c + " Assets");
		// 		console.log(Assets.findOne({assetId: asset.assetId}));
		// 	}
		// }
	}
});

// console.log("Assets setup.")