package storagesim;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;

import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import lib.SQLConnection;

public class BWLHelper {

	public static final String PATH = System.getProperty("user.home") + "/Desktop/Bestellungen/";

	public static void sys1(SQLConnection db, LocalDate date, int produkt_ID, float ZinsenProzent) {
		HashMap<String, String> ProduktInformationen = db.queryToMap("SELECT Name, Lieferzeit, Einkaufspreis, Verkaufspreis FROM t_artikel WHERE ID = '" + produkt_ID + "'").get(0);

		int lieferzeit = Integer.parseInt(ProduktInformationen.get("Lieferzeit"));
		ArrayList<HashMap<String, String>> stat = db.queryToMap("SELECT Menge FROM t_verkaufszahlen WHERE f_Artikel_ID = '" + produkt_ID + "' ORDER BY Woche DESC LIMIT 1");
		int statMenge = 1; 
		if (stat.size() > 0) {
			statMenge = Integer.parseInt(stat.get(0).get("Menge"));
		}
		LocalDate ankunft = date.plusDays(lieferzeit);
		
		int jahresBedarf = 48 * statMenge;
		int menge = gesamtMenge(db, produkt_ID);
		float bestellKosten = (float) (menge * Float.parseFloat(ProduktInformationen.get("Einkaufspreis")) + 8.3);
		float EinnahmenPMenge = Float.parseFloat(ProduktInformationen.get("Verkaufspreis"));
		float lagerWert = dWert(db) / Integer.parseInt(db.queryToMap("SELECT Woche FROM t_lagerstatistik ORDER BY Woche DESC LIMIT 1").get(0).get("Woche"));
		float lagerKostenSatz, lagerKosten, lagerHaltungsKostenSatz, StromPreisLager;
		int sicherheitsBestand, meldeBestand;

		ArrayList<HashMap<String, String>> elemente = db.queryToMap("SELECT f_Artikel_ID, Gekühlt FROM t_lager INNER JOIN t_artikel ON t_lager.f_Artikel_ID = t_artikel.ID");

		int gekuehlteProdukte = 0;
		int ungekuehlteProdukte = 0;

		for (HashMap<String, String> elem : elemente) {
			if (elem.get("Gekühlt").equals("1")) {
				gekuehlteProdukte++;
			} else {
				ungekuehlteProdukte++;
			}
		}

		StromPreisLager = gekuehlteProdukte * 85.68f + ungekuehlteProdukte * 1.71f;

		lagerKosten = 80 * 4 + 360 * 6 + StromPreisLager;

		lagerKostenSatz = lagerKosten / lagerWert * 100;

		lagerHaltungsKostenSatz = lagerKostenSatz + ZinsenProzent;

		int bestellMenge = (int) Math.sqrt((2 * jahresBedarf * bestellKosten) / (EinnahmenPMenge * lagerHaltungsKostenSatz));

		sicherheitsBestand = statMenge * lieferzeit;

		meldeBestand = statMenge * lieferzeit + sicherheitsBestand;

		if (menge <= meldeBestand) {
			System.out.printf("Es wurden %d %s nachbestellt.\n", bestellMenge, ProduktInformationen.get("Name"));
			db.execute("INSERT INTO t_bestellungen SET f_Artikel_ID = " + produkt_ID +
					", Menge = " + bestellMenge + 
					", Ankunftsdatum = ('" + ankunft.toString() + "')");
		}
	}

	public static void sys2(SQLConnection db, LocalDate date, int produkt_ID, int bestellIntervall, int maxMenge, int ZinsenProzent, boolean sBestand) {
		HashMap<String, String> ProduktInformationen = db.queryToMap("SELECT Name, Lieferzeit FROM t_artikel WHERE ID = '" + produkt_ID + "'").get(0);
		
		int lieferzeit = Integer.parseInt(ProduktInformationen.get("Lieferzeit"));
		LocalDate ankunft = date.plusDays(lieferzeit);

		LocalDate nächsteBestellung = date;
		ArrayList<HashMap<String, String>> artikel = db.queryToMap("SELECT Ankunft FROM t_lager WHERE f_Artikel_ID = '" + produkt_ID + "'");
		if (artikel.size() > 0) {
			nächsteBestellung = LocalDate.parse(artikel.get(0).get("Ankunft")).minusDays(lieferzeit).plusDays(bestellIntervall);
		}

		int pMenge = gesamtMenge(db, produkt_ID);

		if (pMenge < maxMenge) {
			if (sBestand == true) {
				int sicherheitsBestand, meldeBestand;

				int bestellMenge = maxMenge - pMenge;

				if ((bestellMenge + pMenge) > maxMenge) {
					bestellMenge = bestellMenge - ((bestellMenge + pMenge) - maxMenge);
				}
				
				ArrayList<HashMap<String ,String>> stat = db.queryToMap("SELECT Menge FROM t_verkaufszahlen WHERE f_Artikel_ID = '" + produkt_ID + "' ORDER BY Woche DESC LIMIT 1");
				int statMenge = 1; 
				if (stat.size() > 0) {
					statMenge = Integer.parseInt(stat.get(0).get("Menge"));
				}
				
				sicherheitsBestand = statMenge * lieferzeit;

				meldeBestand = statMenge * lieferzeit + sicherheitsBestand;

				if (pMenge <= meldeBestand) {
					System.out.printf("Es wurden %d %s nachbestellt.\n", bestellMenge, ProduktInformationen.get("Name"));
					
					db.execute("INSERT INTO t_bestellungen SET f_Artikel_ID = " + produkt_ID +
							", Menge = " + bestellMenge +
							", Ankunftsdatum = ('" + ankunft.toString() + "')");
				} else if (date.isEqual(nächsteBestellung) || date.isAfter(nächsteBestellung)) {
					System.out.printf("Es wurden %d %s nachbestellt.\n", bestellMenge, ProduktInformationen.get("Name"));
					
					db.execute("INSERT INTO t_bestellungen SET f_Artikel_ID = " + produkt_ID +
							", Menge = " + bestellMenge +
							", Ankunftsdatum = ('" + ankunft.toString() + "')");
				}
			} else {
				int bestellMenge = maxMenge - pMenge;

				if (date.isEqual(nächsteBestellung) || date.isAfter(nächsteBestellung)) {
					System.out.printf("Es wurden %d %s nachbestellt.\n", bestellMenge, ProduktInformationen.get("Name"));
					
					db.execute("INSERT INTO t_bestellungen SET f_Artikel_ID = " + produkt_ID +
							", Menge = " + bestellMenge + 
							", Ankunftsdatum = ('" + ankunft.toString() + "')");
				}
			}
		}
	}

	public static void Bestellungen(SQLConnection db, LocalDate date, ArrayList<HashMap<String, String>> bestellungen, String Name) {
		// name of the excel files
		String templateFileName = StorageMap.class.getResource("/res/Template.xlsx").getFile();
		String outputFileName = PATH + "/Out_" + date.toString() + "_" + System.currentTimeMillis() % 1000 + ".xlsx";

		XSSFWorkbook wb;
		try {
			InputStream ExcelFileToRead = new FileInputStream(templateFileName);
			wb = new XSSFWorkbook(ExcelFileToRead);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return;
		} catch (IOException e) {
			e.printStackTrace();
			return;
		}

		XSSFSheet sheet = wb.getSheetAt(0);

		sheet.getRow(11).getCell(2).setCellValue(date.toString());
		sheet.getRow(13).getCell(2).setCellValue(Name);

		int offset = 5;

		for (int Reihe = 0; Reihe < 5; Reihe++) {
			if (Reihe >= bestellungen.size()) {
				sheet.getRow(Reihe + offset).getCell(1).setCellValue("");
				sheet.getRow(Reihe + offset).getCell(2).setCellValue("");
				sheet.getRow(Reihe + offset).getCell(3).setCellValue("");
				sheet.getRow(Reihe + offset).getCell(4).setCellValue("");
				sheet.getRow(Reihe + offset).getCell(5).setCellValue("");
				sheet.getRow(Reihe + offset).getCell(6).setCellValue("");
			} else {
				HashMap<String, String> produkt = bestellungen.get(0);

				String Hersteller = produkt.get("Marke");

				int ProduktID = Integer.parseInt(produkt.get("f_Artikel_ID"));
				String Beschreibung = produkt.get("Name");
				int Menge = Integer.parseInt(produkt.get("Menge"));
				float Stückpreis = Float.parseFloat(produkt.get("Einkaufspreis"));
				float Gesamtpreis = Stückpreis * Menge;

				sheet.getRow(Reihe + offset).getCell(1).setCellValue(ProduktID);
				sheet.getRow(Reihe + offset).getCell(2).setCellValue(Hersteller);
				sheet.getRow(Reihe + offset).getCell(3).setCellValue(Beschreibung);
				sheet.getRow(Reihe + offset).getCell(4).setCellValue(Menge);
				sheet.getRow(Reihe + offset).getCell(5).setCellValue(String.format("%.2f", Stückpreis));
				sheet.getRow(Reihe + offset).getCell(6).setCellValue(String.format("%.2f", Gesamtpreis));

				bestellungen.remove(produkt);
			}
		}

		try {
			File outputFile = new File(outputFileName);
			outputFile.getParentFile().mkdirs();
			outputFile.createNewFile();
			FileOutputStream fileOut = new FileOutputStream(outputFile);

			// write this workbook to an OutputStream.
			wb.write(fileOut);
			wb.close();
			fileOut.flush();
			fileOut.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void lagerStatistik(SQLConnection db, int Woche) {
		int eWoche = Woche + 48;
		
		db.execute("DELETE FROM t_lagerstatistik WHERE Woche = " + eWoche);
		db.execute("INSERT INTO t_lagerstatistik SET Woche = " + eWoche + ", Wert = " + gMenge(db));
	}

	public static float dWert(SQLConnection db) {
		float wert = 0;
		ArrayList<HashMap<String, String>> Wert = db.queryToMap("SELECT * FROM `t_lagerstatistik` ORDER BY `t_lagerstatistik`.`Woche` DESC LIMIT 48");
		for (HashMap<String, String> row : Wert) {
			wert += Float.parseFloat(row.get("Wert"));
		}
		return wert;
	}

	public static int gesamtMenge(SQLConnection db, int produkt_ID) {
		ArrayList<HashMap<String, String>> storage = db.queryToMap("SELECT Menge FROM t_lager WHERE f_Artikel_ID = " + produkt_ID);
		storage.addAll(db.queryToMap("SELECT Menge FROM t_bestellungen WHERE f_Artikel_ID = " + produkt_ID));
		
		int gesamt = 0;
		for (HashMap<String, String> row : storage) {
			gesamt += Integer.parseInt(row.get("Menge"));
		}
		return gesamt;
	}

	public static float gMenge(SQLConnection db) {
		float menge = 0;
		ArrayList<HashMap<String, String>> produkte = db.queryToMap(
				"SELECT Verkaufspreis, Menge FROM t_lager INNER JOIN t_artikel ON t_lager.f_Artikel_ID = t_artikel.ID");
		for (int i = 0; i < produkte.size(); i++) {
			menge = menge + (Float.parseFloat(produkte.get(i).get("Verkaufspreis")) * Integer.parseInt(produkte.get(i).get("Menge")));
		}
		return menge;
	}
}
