package sklep.przyklady_hibernate;

import java.math.BigDecimal;
import java.util.Scanner;

import jakarta.persistence.*;

import sklep.model.Product;

public class Zapis_Update {

	public static void main(String[] args) {
        try(EntityManagerFactory emf = Persistence.createEntityManagerFactory("sklep");
            EntityManager em = emf.createEntityManager()) {
			
        	Scanner sc = new Scanner(System.in);
			System.out.println("Rozpoczynam transakcję");
			EntityTransaction transakcja = em.getTransaction();
			transakcja.begin();
			
			System.out.println("Aby zakończyć, podaj liczbę 0");
			while(true) {
				System.out.print("\nPodaj id produktu: ");
				int id = sc.nextInt();
				sc.nextLine();
				if(id == 0) break;
			
				Product product = em.find(Product.class, id);
				if(product == null) {
					System.out.println("Nie ma produktu o id " + id);
					continue;
				}
				System.out.println("Odczytany produkt: " + product);
				System.out.println(product.getProductName() + " za cenę " + product.getPrice() + ", opis: " + product.getDescription());

				// Umożliwiamy wprowadzenie zmian i te zmiany są nakładane za pomocą setterów bezpośrednio na obiekcie encji.
				System.out.println("Podaj zmianę ceny: ");	
				BigDecimal zmiana = sc.nextBigDecimal();
				sc.nextLine();
				if(zmiana.compareTo(BigDecimal.ZERO) != 0) {
					product.setPrice(product.getPrice().add(zmiana));
				}
				System.out.println("Podaj nową nazwę (enter, aby nie zmieniać): ");
				String nazwa = sc.nextLine();
				if(!nazwa.isEmpty()) {
					product.setProductName(nazwa);
				}
				System.out.println("Podaj nowy opis (enter, aby nie zmieniać): ");
				String opis = sc.nextLine();
				if(!opis.isEmpty()) {
					product.setDescription(opis);
				}
				
				// Operacja flush wymusza wykonanie poleceń DML (INSERT, UPDATE, DELETE) na bazie, ale nie zatwierdza transakcji
				// Nie ma obowiązku wykonywać flush. Gdy na końcu zrobimy commit, to Hibernate i tak zflushuje dane...
				System.out.println("Czy zrobić teraz flush? [T/N] ");
				String taknie = sc.nextLine().trim().toUpperCase();
				switch(taknie) {
					case "T", "Y" -> {
						em.flush();
						System.out.println("Zrobione");
					}
				}
			}
			
			// Do tej pory zmiany zostały dokonane w obiektach znajdujących się w pamięci.
			// Aby zapisać zmiany w bazie danych, należy zatwierdzić transakcję (i tylko tyle).
			// To zapisze wszystkie "obiekty zarządzane" przez EntityManagera.

			System.out.println("Czy zapisać zmiany? [T/N] ");
			String taknie = sc.nextLine().trim().toUpperCase();
			switch(taknie) {
				case "T", "Y" -> {
					transakcja.commit();
					System.out.println("Zmiany zatwierdzone");
				}
				case "N" -> {
					transakcja.rollback();
					System.out.println("Zmiany wycofane");
				}
				// w pozostałych przypadkach nie ma ani commit, ani rollback → zmiany nie zostaną zapisane
			}
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
}
