package controler.facture;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.Date;
import java.sql.Time;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import language.Language;
import view.vueFacture.VueFacture;
import view.vueGestionArticle.VueGestionAjouterArticle;
import view.vueGestionArticle.VueGestionModifierArticle;
import view.vuePopup.PopupFacturePaiement.paiement;

import commander.Commander;

import controler.Message;
import database.crud.ArticleCrud;
import database.crud.ChambreCrud;
import database.crud.EncaissementCrud;
import database.crud.FactureCrud;
import database.crud.ModePaiementCrud;
import database.crud.TaxeCrud;
import database.crud.denormalised.ViewEncaissementCrud;
import database.crud.denormalised.ViewFactureCrud;
import database.crud.denormalised.ViewVenteCrud;
import database.crud.reservation.ReservationCrud;
import database.crud.vente.VenteArticleCrud;
import database.crud.vente.VenteCrud;
import database.dataset.Article;
import database.dataset.Chambre;
import database.dataset.Encaissement;
import database.dataset.Facture;
import database.dataset.Modedepaiement;
import database.dataset.Reservation;
import database.dataset.Taxe;
import database.dataset.Vente;
import database.dataset.Vente_article;

public class ControlerFacture {
	public static final Message reveil = new Message(){
		public void trigger(Object caster) throws Exception {
			if (!(caster instanceof VueFacture))
				return;
			VueFacture vue = (VueFacture)caster;
				Connection connection = Commander.getInstance().getConnectionBD();
				
			if(vue.getFacture_id() == 0)
			{
				vue.setEnabled(false);
			}
			else
			{
				vue.setEnabled(true);
			}
		}
	};
	

	public static final Message selectioner = new Message(){
		public void trigger(Object caster) throws Exception {
			if (!(caster instanceof VueFacture))
				return;
			//VueFacture vue = (VueFacture)caster;

			Language lang = Commander.getInstance().getLanguage();
			Commander.getInstance().getVuePrincipale().setSelectedTab(lang.getPrincipaleRecherche(), lang.getRechercheClient());
		}
	};
	

	public static final Message annuler = new Message(){
		public void trigger(Object caster) throws Exception {
			if (!(caster instanceof VueFacture))
				return;
			VueFacture vue = (VueFacture)caster;
			Connection connection = Commander.getInstance().getConnectionBD();
			
			vue.setEnabled(false);
			
			Language lang = Commander.getInstance().getLanguage();
			Commander.getInstance().getVuePrincipale().setModifiedTab(lang.getPrincipaleReception(), lang.getReceptionFacture(),false);
		}
	};
	
	
	public static final Message checkin = new Message(){
		public void trigger(Object caster) throws Exception {
			if (!(caster instanceof VueFacture))
				return;
			VueFacture vue = (VueFacture)caster;
			Connection connection = Commander.getInstance().getConnectionBD();
			ReservationCrud reservationCrud = new ReservationCrud(connection);
			
			for(int i =0;i<vue.getSize_ReservationId();i++){
				if(vue.getCheckBoxValueAtTableReservation(i)){
					reservationCrud.updateCheckInCheckOut(vue.get_ReservationIdItem(i), 3);
				}
			}
		}
	};
	

	public static final Message checkout = new Message(){
		public void trigger(Object caster) throws Exception {
			if (!(caster instanceof VueFacture))
				return;
			VueFacture vue = (VueFacture)caster;
			Connection connection = Commander.getInstance().getConnectionBD();
			ReservationCrud reservationCrud = new ReservationCrud(connection);
			
			for(int i =0;i<vue.getSize_ReservationId();i++){
				if(vue.getCheckBoxValueAtTableReservation(i)){
					reservationCrud.updateCheckInCheckOut(vue.get_ReservationIdItem(i), 3);
				}
			}
		}
	};
	

	public static final Message imprimer = new Message(){
		public void trigger(Object caster) throws Exception {
			if (!(caster instanceof VueFacture))
				return;
			VueFacture vue = (VueFacture)caster;

				Connection connection = Commander.getInstance().getConnectionBD();


		}
	};
	

	public static final Message paiement = new Message(){
		public void trigger(Object caster) throws Exception {
			if (!(caster instanceof VueFacture))
				return;
			VueFacture vue = (VueFacture)caster;
			
			if(vue.getFacture_id() == 0)
				return;
			
			Connection connection = Commander.getInstance().getConnectionBD();
			
			Facture facture = new Facture(vue.getFacture_id(), 0, 0, null, 0, null, null, null);
			ViewVenteCrud viewVenteCrud = new ViewVenteCrud(connection);
			ViewEncaissementCrud viewencaissementCrud = new ViewEncaissementCrud(connection);
			EncaissementCrud encaissementCrud = new EncaissementCrud(connection); 
			
			Map<String, BigDecimal> totalMap = viewVenteCrud.getSumVenteFromFacture(facture.getFacture_p_id());
			
			BigDecimal total = BigDecimal.ZERO;
			BigDecimal present = viewencaissementCrud.getSumEncaissementFromFacture(facture.getFacture_p_id(),"");
			BigDecimal balance;
			
			for(BigDecimal money : totalMap.values())
			{
				total = total.add(money);
			}
			
			if(present == null)
			{
				balance = total;
				present = BigDecimal.ZERO;
			}
			else
			{
				balance = total.subtract(present);
			}
			
			ModePaiementCrud modepaiementCrud = new ModePaiementCrud(connection);
			List<Modedepaiement> modes = modepaiementCrud.readAll();
			String[] modePaiement = new String[modes.size()];
			for(int i = 0; i < modes.size(); i++)
				modePaiement[i] = modes.get(i).getModedepaiement_nom();

			paiement paie = vue.getMontantNewPaiement(present, balance, total, modePaiement);
			BigDecimal montantValue = new BigDecimal(paie.montant.substring(0,paie.montant.length()-1));
			int id_modedepaiement = modepaiementCrud.readByNom(paie.methodePaiement).getmodedepaiement_p_id();
			
			if(montantValue == BigDecimal.ZERO)
			{
				return;
			}
			if(id_modedepaiement == 0)
			{
				return;
			}
			
			Encaissement encaissement = new Encaissement(viewencaissementCrud.getNewSequenceId(), vue.getFacture_id(), id_modedepaiement, montantValue);
			encaissementCrud.create(encaissement);
		}
	};
	
	public static final Message enregistrer = new Message(){
		public void trigger(Object caster) throws Exception {
			if (!(caster instanceof VueFacture))
				return;
			VueFacture vue = (VueFacture)caster;
			Connection connection = Commander.getInstance().getConnectionBD();
			
			BigDecimal totalFacture = BigDecimal.ZERO,
					   total,
					   tps,
					   tvq;
			
			VenteArticleCrud venteArticleCrud = new VenteArticleCrud(connection);
			ArticleCrud articleCrud = new ArticleCrud(connection);
			ReservationCrud reservationCrud = new ReservationCrud(connection);
			VenteCrud venteCrud = new VenteCrud(connection);
			TaxeCrud taxeCrud = new TaxeCrud(connection);
			ChambreCrud chambreCrud = new ChambreCrud(connection); 
			
			Vente vente;
			Reservation reservation;
			Chambre chambre;
			Vente_article vente_article;
			List<Article> article = new ArrayList<Article>();
			
			for(int i=0;i<vue.getSize_ReservationVenteId();i++)
			{
				article = articleCrud.readAllLike(vue.getPromotionValueAtTableReservation(i), "", "", "", "");
				vente = new Vente(vue.get_ReservationVenteIdItem(i), new Time(System.currentTimeMillis()), new Date(System.currentTimeMillis()), vue.getPrixValueAtTableReservation(i), vue.getFacture_id(), article.get(0).getarticle_p_id());
				
				Taxe taxe = taxeCrud.readLast();
				tps = ((vue.getPrixValueAtTableReservation(i).multiply(taxe.getTaxe_tps())));
				tvq = ((vue.getPrixValueAtTableReservation(i).add(tps)).multiply(taxe.getTaxe_tvq()));
				total = (vue.getPrixValueAtTableReservation(i).add(tps)).add(tvq);
				totalFacture = totalFacture.add(total);
				
				vue.setTPSValueAtTableReservation(i, tps);
				vue.setTVQValueAtTableReservation(i, tvq);
				vue.setTotalValueAtTableReservation(i, total);
				
				venteCrud.update(vente);
				
				if(vue.get_ReservationIdItem(i) != 0)
				{
					reservation = reservationCrud.readById(vue.get_ReservationIdItem(i));
					chambre = chambreCrud.readByNumero(vue.getChambreValueAtTableReservation(i));
					
					reservation = new Reservation(vue.get_ReservationIdItem(i), chambre.getChambre_p_id(), vue.getDateDebutValueAtTableReservation(i), vue.getDateFinValueAtTableReservation(i), reservation.getReservation_commentaire(), reservation.getStatus_fk_id());
					reservationCrud.update(reservation);
				}
			}
			
			for(int i=0; i<vue.getSize_VenteId();i++)
			{
				article = articleCrud.readAllLike(vue.getArticleSelectedAtTableVente(i), "", "", "", "");
				vente_article = new Vente_article(vue.get_VenteIdItem(i), new Time(System.currentTimeMillis()), new Date(System.currentTimeMillis()), vue.getPrixValueAtTableVente(i), vue.getFacture_id(), article.get(0).getarticle_p_id(), vue.getNombreAtTableVente(i));
				venteArticleCrud.update(vente_article);
				
				Taxe taxe = taxeCrud.readLast();
				tps = ((vue.getPrixValueAtTableVente(i).multiply(new BigDecimal(vue.getNombreAtTableVente(i)))).multiply(taxe.getTaxe_tps()));
				tvq = ((vue.getPrixValueAtTableVente(i).multiply(new BigDecimal(vue.getNombreAtTableVente(i)))).add(tps)).multiply(taxe.getTaxe_tvq());
				total = ((vue.getPrixValueAtTableVente(i).multiply(new BigDecimal(vue.getNombreAtTableVente(i)))).add(tps)).add(tvq);
				totalFacture = totalFacture.add(total);
				
				vue.setTPSValueAtTableVente(i, tps);
				vue.setTVQValueAtTableVente(i, tvq);
				vue.setTotalValueAtTableVente(i, total);
				
			}
			
			vue.setTotal(totalFacture);
			
			Language lang = Commander.getInstance().getLanguage();
			Commander.getInstance().getVuePrincipale().setModifiedTab(lang.getPrincipaleReception(), lang.getReceptionFacture(),false);
		}
	};
	
	public static final Message creerVente = new Message(){
		public void trigger(Object caster) throws Exception {
			if (!(caster instanceof VueFacture))
				return;
			VueFacture vue = (VueFacture)caster;
			Connection connection = Commander.getInstance().getConnectionBD();
			
			VenteCrud venteCrud = new VenteCrud(connection);
			ArticleCrud articleCrud = new ArticleCrud(connection);
			VenteArticleCrud venteArticleCrud = new VenteArticleCrud(connection);
			
			Vente_article vente_article = new Vente_article(venteCrud.getNewSequenceId(), new Time(System.currentTimeMillis()), new Date(System.currentTimeMillis()), new BigDecimal(0), vue.getFacture_id(), 20, 0);
			
			List<Article> articleDepanneur = articleCrud.readByFk_categorie(3);
			List<Article> articleRestaurant = articleCrud.readByFk_categorie(4);
			List<Article> articleAdministration = articleCrud.readByFk_categorie(5);
			
			List<Article> article = new ArrayList<Article>();
			
			for(int i=0;i<articleDepanneur.size();i++)
			{
				if(articleDepanneur.get(i).isArticle_actif())
				{
					article.add(articleDepanneur.get(i));
				}				
			}
			
			for(int i=0;i<articleRestaurant.size();i++)
			{
				if(articleRestaurant.get(i).isArticle_actif())
				{
					article.add(articleRestaurant.get(i));
				}
			}
			
			for(int i=0;i<articleAdministration.size();i++)
			{
				if(articleAdministration.get(i).isArticle_actif())
				{
					article.add(articleAdministration.get(i));
				}
			}
			
			venteArticleCrud.create(vente_article);
			vue.addRowTableVenteWithArticle(new Date(System.currentTimeMillis()).toString(), article, 0);
			vue.add_VenteId(vente_article.getVente_p_id());

		}
	};
	
	public static final Message dataChanged = new Message(){
		public void trigger(Object caster) throws Exception {
			if (!(caster instanceof VueFacture))
				return;
			
			Language lang = Commander.getInstance().getLanguage();
			Commander.getInstance().getVuePrincipale().setModifiedTab(lang.getPrincipaleReception(), lang.getReceptionFacture(),true);	
		}
	};
}
