package controller.console.enseignant;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Scanner;

import view.console.enseignant.Session_Creation;

import model.Enseignant;
import model.Module;
import model.Promotion;
import model.QCM;
import model.Session;
import model.list.HandlerModules;
import model.list.HandlerPromotions;
import model.list.HandlerSessions;

public class Session_CreationControle {
	private Scanner sc;
	private final DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
	
	private Date dateDebut;
	private Date dateFin;
	private int repetition;
	private Enseignant createur;
	private Promotion promotion;
	private Module module;
	private QCM qcm;
	
	private ArrayList<Promotion> lProm;
	private ArrayList<Module> lMod;
	private ArrayList<QCM> lQCM;
	
	private class InvalidDate extends Exception {
		private static final long serialVersionUID = 1L;
		private Date date;
		public InvalidDate(Date d) {
			super();
			this.date = d;
		}
		public Date getDate() {
			return this.date;
		}
	}
	
	private class DefaultInput extends Exception {
		private static final long serialVersionUID = 1L;
	}
	
	public Session_CreationControle(ArrayList<Promotion> lProm, ArrayList<Module> lMod, ArrayList<QCM> lQCM, Enseignant e_connected) {
		this.createur = e_connected;
		this.lProm = lProm;
		this.lMod = lMod;
		this.lQCM = lQCM;
		sc = new Scanner(System.in);
		
		Session_Creation.trigger();
		this.askDateDebut();
		this.askDateFin();
		this.askRepetition();
		this.askPromotion();
		this.askModule();
		this.askQCM();
	}
	
	private void askDateDebut() {
		String input;
		boolean done = false;
		while (!done) {
			try {
				Session_Creation.askDateDebut();
				input = sc.nextLine();
				this.dateDebut = this.dateFormat.parse(input);
				done = true;
			} catch (ParseException e) {
				Session_Creation.failDate();
			}
		}
	}
	
	private void askDateFin() {
		String input;
		boolean done = false;
		while (!done) {
			try {
				Session_Creation.askDateFin();
				input = sc.nextLine();
				this.dateFin = this.dateFormat.parse(input);
				if (this.dateFin.before(new Date())) {
					throw new InvalidDate(new Date());
				} else if (this.dateFin.before(this.dateDebut)) {
					throw new InvalidDate(this.dateDebut);
				}
				done = true;
			} catch (ParseException e) {
				Session_Creation.failDate();
			} catch (InvalidDate e) {
				Session_Creation.failDate(e.getDate(), true);
			}
		}
	}
	
	private void askRepetition() {
		String input;
		boolean done = false;
		while (!done) {
			try {
				Session_Creation.askRepetition();
				input = sc.nextLine();
				if (input.equals("")) {
					throw new DefaultInput();
				}
				this.repetition = Integer.parseInt(input);
				if (this.repetition < 1) {
					throw new NumberFormatException();
				} else {
					done = true;
				}
			} catch (NumberFormatException e) {
				Session_Creation.fail(1, Integer.MAX_VALUE);
			} catch (DefaultInput e) {
				this.repetition = 1;
				done = true;
			}
		}
	}
	
	private void askPromotion() {
		String str_input;
		int input;
		boolean done = false;

		while (!done) {
			Session_Creation.showPromotions(lProm);
			str_input = sc.nextLine();
			try {
				input = Integer.parseInt(str_input);
				if ((input < 1) || (input > this.lProm.size())) {
					Session_Creation.fail(1, this.lProm.size());
				} else {
					this.promotion = this.lProm.get(input-1);
					done = true;
				}
			} catch (NumberFormatException e) {
				this.promotion = HandlerPromotions.getPromotion(str_input, this.lProm);
				if (this.promotion == null) {
					Session_Creation.failPromotion();
				}
			}
		}
	}
	
	private void askModule() {
		String str_input;
		int input;
		boolean done = false;

		while (!done) {
			Session_Creation.showModules(lMod);
			str_input = sc.nextLine();
			try {
				input = Integer.parseInt(str_input);
				if ((input < 1) || (input > this.lMod.size())) {
					Session_Creation.fail(1, this.lMod.size());
				} else {
					this.module = this.lMod.get(input-1);
					done = true;
				}
			} catch (NumberFormatException e) {
				this.module = HandlerModules.getModule(str_input, this.lMod);
				if (this.module == null) {
					Session_Creation.failModule();
				}
			}
		}
	}
	
	private void askQCM() {
		String str_input;
		int input;
		boolean done = false;

		while (!done) {
			Session_Creation.showQCM(lQCM);
			str_input = sc.nextLine();
			try {
				input = Integer.parseInt(str_input);
				if ((input < 1) || (input > this.lQCM.size())) {
					Session_Creation.fail(1, this.lQCM.size());
				} else {
					this.qcm = this.lQCM.get(input-1);
					done = true;
				}
			} catch (NumberFormatException e) {
				Session_Creation.fail(1, this.lQCM.size());
			}
		}
	}
	
	public void addToDatabase(HandlerSessions hSess) {
		Session s = new Session(this.dateDebut, this.dateFin, this.repetition, this.createur, this.promotion, this.module, this.qcm);
		hSess.getListe().add(s);
		Session_Creation.addSession(s);
	}
}
