package sklep.baza;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import sklep.exn.BladBazyDanych;
import sklep.model.Towar;

public class Baza implements AutoCloseable {
	public static final String PLIK_SQLITE = "sklep.db";
	public static final String url = "jdbc:sqlite:" + PLIK_SQLITE;
	public static final String driver = "org.sqlite.JDBC";
	private static final BigDecimal STO = new BigDecimal(100);

	private Connection connection;

	private Baza(Connection jdbcConnection) {
		connection = jdbcConnection;
	}
	
	public void close() {
		if(connection != null) {
			try {
				connection.close();
			} catch (SQLException e) {
				System.err.println(e);
			}
		}
	}

	public static Baza nowaBaza() throws BladBazyDanych {
		Connection connection;
		try {
			Class.forName(driver);
			connection = DriverManager.getConnection(Baza.url);
		} catch (Exception e) {
			throw new BladBazyDanych("Nie udalo sie polaczyc", e);
		}
		if (connection == null) {
			throw new BladBazyDanych("Nie udalo sie polaczyc - NULL");
		}
		return new Baza(connection);
	}

	public static Baza nowaBaza(Connection jdbcConnection) throws BladBazyDanych {
		return new Baza(jdbcConnection);
	}
	
	public Towar wezTowar(String nazwa) throws BladBazyDanych {
		try(PreparedStatement stmt = connection.prepareStatement(
				"SELECT nazwa, cena, vat FROM towary WHERE nazwa = ?")) {
		
			stmt.setString(1, nazwa);
			
			try(ResultSet rs = stmt.executeQuery()) {
				if(rs.next()) {
					String prawdziwaNazwa = rs.getString(1);
					int cena = rs.getInt(2);
					int vat = rs.getInt(3);
					
					return new Towar(prawdziwaNazwa,
							BigDecimal.valueOf(100 * cena, 2),  // new BigDecimal(cena).setScale(2)
							BigDecimal.valueOf(vat, 2));
				} else {
					return null;
				}
			}

		} catch (SQLException e) {
			throw new BladBazyDanych("Blad w wezTowar", e);
		}
	}
	
	public void zapiszTowar(Towar towar) throws BladBazyDanych {

		try {
			PreparedStatement stmt = connection
					.prepareStatement("UPDATE towary SET cena=?, vat=? WHERE nazwa=?");
			stmt.setInt(1, towar.getCenaNetto().intValue());
			stmt.setInt(2, towar.getVat().multiply(STO).intValue());
			stmt.setString(3, towar.getNazwa());
			int rows = 0;
			try {
				rows = stmt.executeUpdate();
			} finally {
				stmt.close();
			}
			
			if (rows < 1) {
				PreparedStatement stmt2 = connection
						.prepareStatement("INSERT INTO towary (nazwa, cena, vat) VALUES (?, ?, ?)");
				stmt2.setString(1, towar.getNazwa());
				stmt2.setInt(2, towar.getCenaNetto().intValue());
				stmt2.setInt(3, towar.getVat().multiply(STO).intValue());
				try {
					stmt2.executeUpdate();
				} finally {
					stmt2.close();
				}
			}
		} catch (SQLException e) {
			throw new BladBazyDanych("zapiszTowar", e);
		}
		
	}

	public void zmienWszystkieCeny(BigDecimal zmiana) throws BladBazyDanych {
		try(PreparedStatement stmt = connection.prepareStatement(
				"UPDATE towary SET cena = cena * (1 + ?)")) {
			stmt.setDouble(1, zmiana.doubleValue());
			stmt.executeUpdate();
		} catch(SQLException e) {
			throw new BladBazyDanych("zmienWszystkieCeny", e);
		}
	}

		public void zmienCene(String nazwa, BigDecimal zmiana) throws BladBazyDanych {
		try(PreparedStatement stmt = connection.prepareStatement(
				"UPDATE towary SET cena = cena * (1 + ?) WHERE nazwa = ?")) {
			stmt.setDouble(1, zmiana.doubleValue());
			stmt.setString(2, nazwa);
			stmt.executeUpdate();
		} catch(SQLException e) {
			throw new BladBazyDanych("zmienCene", e);
		}
	}

	public String znajdzMagazynZTowarem(String aNazwaTowaru, int aIle)
			throws BladBazyDanych {
		try(PreparedStatement stmt = connection
					.prepareStatement("SELECT magazyn FROM stany WHERE towar = ? AND stan >= ?")) {
			stmt.setString(1, aNazwaTowaru);
			stmt.setInt(2, aIle);

			try(ResultSet rs = stmt.executeQuery()) {
				if (rs.next()) {
					return rs.getString(1);
				} else
					return null;
			}
		} catch (SQLException e) {
			throw new BladBazyDanych();
		}
	}

	public void zmienStanMagazynu(String aNazwaMagazynu, String aNazwaTowaru,
			int aZmiana) throws BladBazyDanych {

		try(PreparedStatement stmt = connection.prepareStatement(
				"UPDATE stany SET stan = stan + ? WHERE magazyn = ? AND towar = ?")) {
			
			stmt.setInt(1, aZmiana);
			stmt.setString(2, aNazwaMagazynu);
			stmt.setString(3, aNazwaTowaru);
			stmt.executeUpdate();
			
		} catch(SQLException e) {
			System.out.println(e);
			throw new BladBazyDanych("zmienStanMagazynu", e);
		}
	}
}
