package sklep.rest;

import java.math.BigDecimal;
import java.util.List;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

import sklep.db.DBConnection;
import sklep.db.DBException;
import sklep.db.ProductDAO;
import sklep.db.RecordNotFound;
import sklep.model.Product;
import sklep.photo.PhotoUtil;

// W tej wersji dane rekordów są udostępniane i pobierane w formacie JSON. Tylko zdjęcia są w formacie JPEG.
// Adnotacje Produces i Consumes na pozimie klasy stają się domyślnym ustawieniem dla wszystkich metod,
// ale metoda może to "nadpisac" (np. getPhoto)
// Inaczej niż w Springu, tutaj można napisać Consumes na poziomie klasy, ale będzie to dotyczyć
// tylko tych metod, które odbierają jakieś dane (POST i PUT, a nie GET).
// Produces dotyczy tylko tych metod, które coś zwracają, ale nie metod typu void.

@Path("/products.json")
@Produces("application/json")
@Consumes("application/json")
public class RProductsJSON {

	@GET
	public List<Product> readAll() throws DBException {
		try(DBConnection db = DBConnection.open()) {
			ProductDAO productDAO = db.productDAO();
			return productDAO.readAll();
		}
	}
	
	@GET
	@Path("/{id}")
	public Product readOne(@PathParam("id") int productId) throws DBException, RecordNotFound {
		try(DBConnection db = DBConnection.open()) {
			ProductDAO productDAO = db.productDAO();
			return productDAO.findById(productId);
		}
	}
	
	@GET
	@Path("/{id}/price")
	public BigDecimal getPrice(@PathParam("id") int productId) throws DBException, RecordNotFound {
		try(DBConnection db = DBConnection.open()) {
			ProductDAO productDAO = db.productDAO();
			Product product = productDAO.findById(productId);
			return product.getPrice();
		}
	}
	
	@PUT
	@Path("/{id}/price")
	public void setPrice(@PathParam("id") int productId, BigDecimal newPrice) throws DBException, RecordNotFound {
		try(DBConnection db = DBConnection.open()) {
			ProductDAO productDAO = db.productDAO();
			Product product = productDAO.findById(productId);
			product.setPrice(newPrice);
			productDAO.update(product);
			db.commit();
		}
	}
	
	@POST
	public Product addProduct(Product product) throws DBException {
		try(DBConnection db = DBConnection.open()) {
			ProductDAO productDAO = db.productDAO();
			if(product.getProductId() != null) {
				throw new IllegalArgumentException("Nowy produkt nie może mieć ustawionego ID");
			}
			productDAO.insertNew(product);
			db.commit();
			return product;
		}
	}
	
	@DELETE
	@Path("/{id}")
	public void removeProduct(@PathParam("id") int productId) throws DBException, RecordNotFound {
		try(DBConnection db = DBConnection.open()) {
			ProductDAO productDAO = db.productDAO();
			if(productDAO.delete(productId)) {
				db.commit();
			} else {
				throw new RecordNotFound("Nie ma produktu nr " + productId);
			}
		}
	}
	
	@GET
	@Path("/{id}/photo")
	@Produces("image/jpeg")
	public byte[] getPhoto(@PathParam("id") int productId) throws DBException, RecordNotFound {
		return PhotoUtil.readBytes(productId);
	}

}
