package Parsers;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

import Objects.Product;

public class ParserBase {
	private static final String USERNAME = "storeParser";
	private static final String PASSWORD = "Rd0.mw4YVY6LLosq";
	private static final String DATABASE = "StoreParser";
	private static final String URL = "jdbc:mysql://nordh.xyz:3306/";

	Connection conn;

	private void openDbConnection() {
		if (conn == null) {
			try {
				conn = DriverManager.getConnection(URL + DATABASE, USERNAME, PASSWORD);
			} catch (final SQLException e) {
				throw new RuntimeException(e.getMessage(), e);
			}
		}
	}

	private void closeDbConnection() {
		try {
			conn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void insertProduct(Product product) {
		openDbConnection();
		String sql = "INSERT INTO Product (storeName, productName, price, updated) VALUE (?,?,?,?) ON DUPLICATE KEY UPDATE price = ?, updated = ?";
		try (PreparedStatement stat = conn.prepareStatement(sql)) {
			stat.setString(1, product.getStore());
			stat.setString(2, product.getName());
			stat.setFloat(3, product.getPrice());
			stat.setString(4, product.getUpdatedDate());
			stat.setFloat(5, product.getPrice());
			stat.setString(6, product.getUpdatedDate());

			stat.execute();

			System.out.println("NEW BETTER PRICE " + product.getStore() + " modell " + product.getName());
			sendUpdatedPriceMail(product);

		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public void sendUpdatedPriceMail(Product product) {
		String to = "axelnordh@gmail.com";
		String from = "axelnordh@gmail.com";
		String host = "smtp.gmail.com";
		Properties properties = System.getProperties();

		properties.put("mail.smtp.host", host);
		String port = "465";
		properties.put("mail.smtp.port", port);
		properties.put("mail.smtp.ssl.enable", "true");
		properties.put("mail.smtp.auth", "true");

		properties.put("mail.smtp.starttls.enable", "true");
		properties.put("mail.smtp.socketFactory.port", port);
		properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
		properties.put("mail.smtp.ssl.checkserveridentity", "true");
		properties.put("mail.smtp.socketFactory.fallback", "false");

		Session session = Session.getInstance(properties, new javax.mail.Authenticator() {
			@Override protected PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication(from, "fprgcnbbhbwiwdmi");
			}
		});

		session.setDebug(true);
		try {
			MimeMessage message = new MimeMessage(session);

			message.setFrom(from);
			message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
			message.setSubject("Nytt bättre pris från " + product.getStore());
			message.setText(String.format("%s fick ett bättre pris från %s, nya priset är %s (%s)", product.getName(),
					product.getStore(), product.getPrice(), product.getUpdatedDate()));

			Transport transport = session.getTransport("smtps");
			transport.connect(host, Integer.valueOf(port), from, "fprgcnbbhbwiwdmi");
			transport.sendMessage(message, message.getAllRecipients());
			transport.close();
		} catch (MessagingException e) {
			e.printStackTrace();
		}
	}

	public float getStoredProductPrice(Product product) {
		openDbConnection();
		String sql = "SELECT price FROM Product WHERE productName = ? AND storeName = ?";

		float result = -1;

		try (PreparedStatement stat = conn.prepareStatement(sql)) {
			stat.setString(1, product.getName());
			stat.setString(2, product.getStore());

			ResultSet rs = stat.executeQuery();

			while (rs.next()) {
				result = rs.getFloat("price");
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}

	protected ChromeDriver getSeleniumDriver() {
		ChromeOptions options = new ChromeOptions();

		System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir") + "/src/main/resources/chromedriver.exe");
		System.setProperty("webdriver.chrome.silentOutput", "true");
		// Fixing 255 Error crashes
		options.addArguments("--no-sandbox");
		options.addArguments("--disable-dev-shm-usage");

		// Options to trick bot detection
		// Removing webdriver property
		options.addArguments("--disable-blink-features=AutomationControlled");
		options.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
		options.setExperimentalOption("useAutomationExtension", null);

		// Changing the user agent / browser fingerprint
		options.addArguments("window-size=1920,1080");
		options.addArguments(
				"user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36");

		// Other
		options.addArguments("disable-infobars");

		ChromeDriver driver = new ChromeDriver(options);
		driver.executeScript("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})");
		return driver;
	}

	protected void closeDriver(WebDriver driver) {
		driver.close();
	}

	public float formatPrice(String priceValueString) {
		return Float.valueOf(priceValueString.replaceAll("[^\\d.]", ""));
	}

}
