package sklep.rest;

import java.net.URI;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

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

// W tej wersji pokazuję, że odpowiedzi na zapytania mogą być zwracane w postaci obiektów klasy Response
// - daje nam to pełną kontrolę nad odpowiedzią (nagłówki, ciasteczka, ...)
// i pozwala dynamicznie podejmować decyzje np. co do formatu danych - czego nie da się w pełni opisać w adnotacjach.

@Path("/products.r")
public class RProductsResponse {
	@GET
	@Produces({"application/json", "application/xml", "text/plain"})
	public Response readAll() {
		try(DBConnection db = DBConnection.open()) {
			ProductDAO productDAO = db.productDAO();
			ProductList lista = new ProductList(productDAO.readAll());
			return Response.ok(lista).build();
		} catch (DBException e) {
			return Response.serverError()
					.type("text/plain")
					.entity("Starszny błąd: " + e)
					.build();
		}
	}
	
	@GET
	@Produces({"application/json", "application/xml", "text/plain"})
	@Path("/{id}")
	public Response readOne(@PathParam("id") int productId) {
		try(DBConnection db = DBConnection.open()) {
			ProductDAO productDAO = db.productDAO();
			Product product = productDAO.findById(productId);
			return Response.ok()
					.entity(product)
					.build();
		} catch (DBException e) {
			return Response.serverError()
					.type("text/plain")
					.entity("Starszny błąd: " + e)
					.build();
		} catch (RecordNotFound e) {
			String html = "<html><body><h1>Nie znaleziono</h1><p style='color:red'>" + e.getMessage()	+ "</p></body></html>";
			return Response.status(404)
					.type("text/html")
					.entity(html)
					.build();
		}
	}
	
	@POST
	@Consumes({"application/json", "application/xml"})
	public Response addProduct(Product product, @Context UriInfo uriInfo) 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();
			URI location = uriInfo.getBaseUriBuilder() // bazowy adres aplikacji
					.path(RProductsResponse.class) // krok obejmujący katalog produktów /products
					.path("/{id}") // krok obejmujcy id produktu, np. /2
					.build(product.getProductId()); // podstawienie ID tego konkretnego produktu w miejsce {}
			return Response.created(location).build();
		}
	}
	
	@DELETE
	@Path("/{id}")
	public Response removeProduct(@PathParam("id") int productId) {
		try(DBConnection db = DBConnection.open()) {
			ProductDAO productDAO = db.productDAO();
			if(productDAO.delete(productId)) {
				db.commit();
				return Response.noContent().build();
			} else {
				String html = "<html><body><h1>Nie znaleziono</h1><p style='color:red'>Nie ma produktu nr " + productId + "</p></body></html>";
				return Response.status(404)
						.type("text/html")
						.entity(html)
						.build();
			}
		} catch (DBException e) {
			throw new WebApplicationException("Straszny błąd");
		}
	}
	
	@GET
	@Path("/{id}/photo")
	@Produces("image/jpeg")
	public Response getPhoto(@PathParam("id") int productId) {
		try {
			byte[] bytes = PhotoUtil.readBytes(productId);
			return Response.ok(bytes).build();
		} catch (DBException | RecordNotFound e) {
			return Response.status(404).build();
		}
	}

}
