import {Mongo} from "meteor/mongo";
import {Meteor} from "meteor/meteor";
import { Roles } from 'meteor/alanning:roles';
import {check} from "meteor/check";
import {Sites} from "/imports/api/sites";
import {parse} from "csv-parse";

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

export const Staff = new Mongo.Collection('staff');

if (Meteor.isServer) {
	// This code only runs on the server
	Meteor.publish('staff', function(siteId) {
		if(siteId) check(siteId, String);
		return siteId ? Staff.find({siteId}) : Staff.find({});
	});
}
Meteor.methods({
	'staff.add'(id, firstName, lastName, email, siteId) {
		if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
			Staff.insert({id, firstName, lastName, email, siteId});
		}
	},
	'staff.update'(_id, id, firstName, lastName, email, siteId) {
		if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
			Staff.update({_id}, {$set: {id, firstName, lastName, email, siteId}});
		}
	},
	'staff.remove'(_id) {
		if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
			//TODO: Need to first verify there are no checked out assets to the staff member.
		}
	},
	/**
	 * Assumes that the ID field is a unique ID that never changes for staff.
	 * This must be true in order for duplicate staff to be avoided.
	 * Will automatically update staff data, including the site he/she is associated with.
	 *
	 * Expects the CSV string to contain comma delimited data in the form:
	 * ID, email, first name, last name
	 *
	 * The query in Aeries is: `LIST STF ID FN LN EM PSC`.
	 * A more complete Aeries query: `LIST STF ID FN LN EM BY FN IF PSC = 5`
	 * Note that you will want to run this query for each school, and the district.  The example above sets the school to #5 (PSC).
	 * Run the query in Aeries as a `Report`, select TXT, and upload here.
	 *
	 * Aeries adds a header per 'page' of data (I think 35 entries per page).
	 * Example:
	 * Anderson Valley Jr/Sr High School,6/11/2022
	 * 2021-2022,Page 1
	 * StuEmail,Student ID,First Name,Last Name,Grade,First Name Alias,Last Name Alias
	 * @type: Currently only supports 'CSV' or 'Aeries Text Report'
	 */
	'staff.loadCsv'(csv, type, siteId) {
		if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
			check(csv, String);
			check(siteId, String);

			let site = Sites.findOne({_id: siteId});

			if(site) {
				let cleanCsv;
				let lines = csv.split(/\r?\n/);
				let pageHeader = type === 'Aeries Text Report' ? lines[0] : null;  // Skip the repeating header lines for an Aeries text report.
				let skip = type === 'CSV' ? 1 : 0;  // Skip the first line of a CSV file (headers).

				// Remove headers from the CSV.
				for(const line of lines) {
					if (skip > 0) skip--;
					else if (pageHeader && line === pageHeader) {
						skip = 2;
					} else {
						if(!cleanCsv) cleanCsv = "";
						else cleanCsv += '\r\n';
						cleanCsv += line;
					}
				}

				//console.log(cleanCsv);

				// Note: This doesn't work because some values are quoted and contain commas as a value character.
				// Parse the CSV (now without any headers).
				// lines = cleanCsv.split(/\r\n/);
				// for(const line of lines) {
				// 	let values = line.split(/\s*,\s*/);
				//
				// 	if(values.length >= 5) {
				// 		let id = values[0];
				// 		let email = values[1];
				// 		let firstName = values[2];
				// 		let lastName = values[3];
				// 		let grade = parseInt(values[4], 10);
				// 		let firstNameAlias = "";
				// 		let active = true;
				//
				// 		if(values.length > 5) firstNameAlias = values[5];
				//		
				// 		let student = {siteId, email, id, firstName, lastName, grade, firstNameAlias, active};
				//		
				// 		// console.log(student);
				// 		// Update or insert in the db.
				// 		console.log("Upserting: " + student);
				// 		Students.upsert({id}, {$set: student});
				// 	}
				// }

				const bound = Meteor.bindEnvironment((callback) => {callback();});

				parse(cleanCsv, {}, function(err, records) {
					bound(() => {
						if(err) console.error(err);
						else {
							let foundIds = new Set();
							let duplicates = [];
							console.log("Found " + records.length + " records.");

							for(const values of records) {
								let id = values[0];
								let email = values[1];
								let firstName = values[2];
								let lastName = values[3];
								let grade = parseInt(values[4], 10);
								let firstNameAlias = "";
								let active = true;

								if(values.length > 5) firstNameAlias = values[5];

								let staff = {siteId, email, id, firstName, lastName, active};

								// Track the staff ID's and record duplicates.  This is used to ensure our counts are accurate later.
								if(foundIds.has(staff.id)) {
									duplicates.push(staff.id);
								}
								else {
									foundIds.add(staff.id);
								}

								//console.log(staff);
								try {
									Staff.upsert({id: staff.id}, {$set: staff});
								}
								catch(err) {
									console.error(err);
								}
							}

							console.log(duplicates.length + " records were duplicates:");
							console.log(duplicates);
						}
					});
				})
			}
			else {
				console.log("Failed to find the site with the ID: " + siteId);
			}
		}
	}
});

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