/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.arrebol.taxiservicios.beans.stocktaking.invoice;

import com.arrebol.taxiservicios.beans.Datatable;
import com.arrebol.taxiservicios.beans.TaxiGenericBean;
import com.arrebol.taxiservicios.controller.admin.GenericValidationController;
import com.arrebol.taxiservicios.controller.stocktaking.CheckStocktakingController;
import com.arrebol.taxiservicios.controller.util.DateWrapper;
import com.arrebol.taxiservicios.model.catalog.Product;
import com.arrebol.taxiservicios.model.core.User;
import com.arrebol.taxiservicios.model.enums.CheckStatus;
import com.arrebol.taxiservicios.model.stocktaking.CheckStocktaking;
import com.arrebol.taxiservicios.model.stocktaking.CheckStocktakingDetail;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import java.awt.Font;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.primefaces.event.ReorderEvent;
import org.primefaces.event.RowEditEvent;

/**
 *
 * @author Oscar
 */
@Named
@ViewScoped
public class CheckStocktakingBean extends TaxiGenericBean implements Serializable, Datatable {
    
    public void fillDataTableBetweenDates() {
        try {
            if (getStartDate().after(getEndDate())) {
                showMessage(FacesMessage.SEVERITY_ERROR, getBundlePropertyFile().getString("generic.start.date"), getBundlePropertyFile().getString("generic.end.date.error"));
            } else {
                setCheckStocktaking(getController().findBetweenDates(getStartDate(), getEndDate(), getLoggedUser().getLocation().getId()));
            }
        } catch (Exception e) {
            logger.error("", e);
        }
    }
    
     public String editCheck(String outcome) {
        return outcome;
    }

    
    public void editRow(RowEditEvent event) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void onRowCancel(RowEditEvent event) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
    
    public void imprimir() {
        Document document = new Document(PageSize.LETTER);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            PdfWriter.getInstance(document, baos);
            List<CheckStocktakingDetail> results = new ArrayList<>();
            results = getController().printDetailsFromCheckStocktakingID(new CheckStocktaking(selectedCheckStocktaking.getId()));
            document.open();
            
            DateFormat formatter = new SimpleDateFormat("dd/MM/yy");

            Paragraph printDate = new Paragraph("Fecha de impresión: " + formatter.format(new Date()), FontFactory.getFont("arial", 10, Font.BOLD, BaseColor.DARK_GRAY));
            printDate.setAlignment(Element.ALIGN_RIGHT);
            document.add(printDate);
            
            Paragraph title = new Paragraph("Cotejar inventario", FontFactory.getFont("arial", 18, Font.BOLD, BaseColor.DARK_GRAY));
            title.setAlignment(Element.ALIGN_CENTER);
            document.add(title);
            
            document.add(new Paragraph("Comentarios: ", FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
            document.add(new Paragraph(selectedCheckStocktaking.getDescription(), FontFactory.getFont("arial", 8, Font.PLAIN, BaseColor.BLACK)));

            document.add(Chunk.NEWLINE);
            
            PdfPTable table = new PdfPTable(6);
            table.setTotalWidth(new float[]{60, 80, 100, 60, 60, 100});

            table.setLockedWidth(true);
            PdfPCell cell = new PdfPCell(new Paragraph("Lista de productos a cotejar",
                    FontFactory.getFont("arial", 10, Font.BOLD, BaseColor.WHITE)));

            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setBackgroundColor(BaseColor.BLUE);
            cell.setColspan(6);
            table.addCell(cell);
            
            cell = new PdfPCell(new Paragraph("Código",
                    FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setColspan(1);
            table.addCell(cell);
            
            cell = new PdfPCell(new Paragraph("Marca",
                    FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setColspan(1);
            table.addCell(cell);
            
            cell = new PdfPCell(new Paragraph("Producto",
                    FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setColspan(1);
            table.addCell(cell);
            
            cell = new PdfPCell(new Paragraph("Inventario sistema",
                    FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setColspan(1);
            table.addCell(cell);
            
            cell = new PdfPCell(new Paragraph("Inventario físico",
                    FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setColspan(1);
            table.addCell(cell);
            
            cell = new PdfPCell(new Paragraph("Comentarios",
                    FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setColspan(1);
            table.addCell(cell);
            
            for (CheckStocktakingDetail tmp : results) {
                cell = new PdfPCell(new Paragraph(tmp.getProduct().getCode(),
                        FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
                cell.setHorizontalAlignment(Element.ALIGN_LEFT);
                cell.setColspan(1);
                table.addCell(cell);
                
                cell = new PdfPCell(new Paragraph(tmp.getProduct().getBrand().getName(),
                        FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
                cell.setHorizontalAlignment(Element.ALIGN_LEFT);
                cell.setColspan(1);
                table.addCell(cell);
                
                cell = new PdfPCell(new Paragraph(tmp.getProduct().getName(),
                        FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
                cell.setHorizontalAlignment(Element.ALIGN_LEFT);
                cell.setColspan(1);
                table.addCell(cell);
                
                cell = new PdfPCell(new Paragraph(tmp.getLastStocktaking() + "",
                        FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
                cell.setHorizontalAlignment(Element.ALIGN_LEFT);
                cell.setColspan(1);
                table.addCell(cell);
                
                cell = new PdfPCell(new Paragraph("",
                        FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
                cell.setHorizontalAlignment(Element.ALIGN_LEFT);
                cell.setColspan(1);
                table.addCell(cell);
                
                cell = new PdfPCell(new Paragraph("",
                        FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
                cell.setHorizontalAlignment(Element.ALIGN_LEFT);
                cell.setColspan(1);
                table.addCell(cell);
            }
            
            document.add(table);
            
            
        } catch (Exception e) {
        System.out.print("Error 1: " + e.getMessage());
        }
        
        document.close();
        FacesContext context = FacesContext.getCurrentInstance();
        Object response = context.getExternalContext().getResponse();
        if (response instanceof HttpServletResponse) {
            HttpServletResponse hrs = (HttpServletResponse) response;
            hrs.setContentType("application/pdf");
            hrs.setHeader("Content-disposition", "attachment");
            hrs.setContentLength(baos.size());
            try {
                ServletOutputStream out = hrs.getOutputStream();
                baos.writeTo(out);
                out.flush();

            } catch (IOException e) {
                System.out.print("Error 2: " + e.getMessage());
            }
            context.responseComplete();
        }
        
    }

    public void imprimirFinal() {
        Document document = new Document(PageSize.LETTER);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            PdfWriter.getInstance(document, baos);
            List<CheckStocktakingDetail> results = new ArrayList<>();
            results = getController().findDetailsFromCheckStocktakingID(new CheckStocktaking(selectedCheckStocktaking.getId()));
            document.open();
            
            DateFormat formatter = new SimpleDateFormat("dd/MM/yy");

            Paragraph printDate = new Paragraph("Fecha de cotejo: " + formatter.format(selectedCheckStocktaking.getCreatedOn()), FontFactory.getFont("arial", 10, Font.BOLD, BaseColor.DARK_GRAY));
            printDate.setAlignment(Element.ALIGN_RIGHT);
            document.add(printDate);
            
            Paragraph title = new Paragraph("Cotejar inventario", FontFactory.getFont("arial", 18, Font.BOLD, BaseColor.DARK_GRAY));
            title.setAlignment(Element.ALIGN_CENTER);
            document.add(title);
            
            document.add(new Paragraph("Comentarios: ", FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
            document.add(new Paragraph(selectedCheckStocktaking.getDescription(), FontFactory.getFont("arial", 8, Font.PLAIN, BaseColor.BLACK)));

            document.add(Chunk.NEWLINE);
            
            PdfPTable table = new PdfPTable(8);
            table.setTotalWidth(new float[]{60, 80, 100, 60, 60, 60, 60, 100});

            table.setLockedWidth(true);
            PdfPCell cell = new PdfPCell(new Paragraph("Lista de productos a cotejar",
                    FontFactory.getFont("arial", 10, Font.BOLD, BaseColor.WHITE)));

            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setBackgroundColor(BaseColor.BLUE);
            cell.setColspan(8);
            table.addCell(cell);
            
            cell = new PdfPCell(new Paragraph("Código",
                    FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setColspan(1);
            table.addCell(cell);
            
            cell = new PdfPCell(new Paragraph("Marca",
                    FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setColspan(1);
            table.addCell(cell);
            
            cell = new PdfPCell(new Paragraph("Producto",
                    FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setColspan(1);
            table.addCell(cell);
            
            cell = new PdfPCell(new Paragraph("Inventario sistema",
                    FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setColspan(1);
            table.addCell(cell);
            
            cell = new PdfPCell(new Paragraph("Inventario físico",
                    FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setColspan(1);
            table.addCell(cell);
            
            cell = new PdfPCell(new Paragraph("Diferencia",
                    FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setColspan(1);
            table.addCell(cell);
            
            cell = new PdfPCell(new Paragraph("Costo",
                    FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setColspan(1);
            table.addCell(cell);
            
            cell = new PdfPCell(new Paragraph("Comentarios",
                    FontFactory.getFont("arial", 8, Font.BOLD, BaseColor.BLACK)));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setColspan(1);
            table.addCell(cell);
            
            for (CheckStocktakingDetail tmp : results) {
                cell = new PdfPCell(new Paragraph(tmp.getProduct().getCode(),
                        FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
                cell.setHorizontalAlignment(Element.ALIGN_LEFT);
                cell.setColspan(1);
                table.addCell(cell);
                
                cell = new PdfPCell(new Paragraph(tmp.getProduct().getBrand().getName(),
                        FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
                cell.setHorizontalAlignment(Element.ALIGN_LEFT);
                cell.setColspan(1);
                table.addCell(cell);
                
                cell = new PdfPCell(new Paragraph(tmp.getProduct().getName(),
                        FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
                cell.setHorizontalAlignment(Element.ALIGN_LEFT);
                cell.setColspan(1);
                table.addCell(cell);
                
                cell = new PdfPCell(new Paragraph(tmp.getLastStocktaking() + "",
                        FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
                cell.setHorizontalAlignment(Element.ALIGN_LEFT);
                cell.setColspan(1);
                table.addCell(cell);
                
                cell = new PdfPCell(new Paragraph(tmp.getNewStocktaking() + "",
                        FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
                cell.setHorizontalAlignment(Element.ALIGN_LEFT);
                cell.setColspan(1);
                table.addCell(cell);
                
                cell = new PdfPCell(new Paragraph((tmp.getNewStocktaking() - tmp.getLastStocktaking()) + "",
                        FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
                cell.setHorizontalAlignment(Element.ALIGN_LEFT);
                cell.setColspan(1);
                table.addCell(cell);
                
                cell = new PdfPCell(new Paragraph((Math.abs(tmp.getNewStocktaking() - tmp.getLastStocktaking()) * tmp.getAmount()) + "",
                        FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
                cell.setHorizontalAlignment(Element.ALIGN_LEFT);
                cell.setColspan(1);
                table.addCell(cell);
                
                cell = new PdfPCell(new Paragraph(tmp.getDescription(),
                        FontFactory.getFont("arial", 6, Font.PLAIN, BaseColor.BLACK)));
                cell.setHorizontalAlignment(Element.ALIGN_LEFT);
                cell.setColspan(1);
                table.addCell(cell);
            }
            
            document.add(table);
            
            document.add(Chunk.NEWLINE);
            document.add(Chunk.NEWLINE);
            document.add(Chunk.NEWLINE);
            document.add(Chunk.NEWLINE);

            document.add(new Paragraph("                  __________________________                 __________________________"));
            document.add(new Paragraph("                                    Firma revisor                                          Firma ejecutor"));
            document.add(new Paragraph("                                          "+selectedCheckStocktaking.getRevisor().getFirstName() + " " + selectedCheckStocktaking.getRevisor().getLastName()+"                                        " + selectedCheckStocktaking.getEjecutor().getFirstName() + " " + selectedCheckStocktaking.getEjecutor().getLastName()));
            
            
        } catch (Exception e) {
        System.out.print("Error 1: " + e.getMessage());
        }
        
        document.close();
        FacesContext context = FacesContext.getCurrentInstance();
        Object response = context.getExternalContext().getResponse();
        if (response instanceof HttpServletResponse) {
            HttpServletResponse hrs = (HttpServletResponse) response;
            hrs.setContentType("application/pdf");
            hrs.setHeader("Content-disposition", "attachment");
            hrs.setContentLength(baos.size());
            try {
                ServletOutputStream out = hrs.getOutputStream();
                baos.writeTo(out);
                out.flush();

            } catch (IOException e) {
                System.out.print("Error 2: " + e.getMessage());
            }
            context.responseComplete();
        }
        
    }
    
    @Override
    public void addRow() {
        
        if(getGenericController().existCheckStocktakingPending(getLoggedUser().getLocation().getId()))
        {
            showMessage(FacesMessage.SEVERITY_WARN,
                        "Cotejar inventario",
                        "No puedes crear un nuevo Cotejar inventario porque aun existe uno pendiente");
            return;
        }
        CheckStocktaking obj = new CheckStocktaking();
        obj.setActive(Boolean.TRUE);
        obj.setCheckStatus(CheckStatus.PENDING);
        obj.setCreatedBy(getLoggedUser());
        obj.setCreatedOn(new Date());
        obj.setId(UUID.randomUUID().toString());
        obj.setLocation(getLoggedUser().getLocation());
        obj.setDescription(comments);
        obj.setRevisor(getLoggedUser().getPerson());
        obj.setEjecutor(getLoggedUser().getPerson());

        if(getController().save(obj, fillProducts(obj)))
        {
            showMessage(FacesMessage.SEVERITY_INFO,
                        "Cotejar inventario",
                        "Se creó exitosamente");
            
            fillDataTableBetweenDates();
        }
        else
        {
            showMessage(FacesMessage.SEVERITY_ERROR,
                        "Cotejar inventario",
                        "Ocurrió un problema, no se guardo el cambio");
        }
        
    }

    @Override
    public void onRowReorder(ReorderEvent event) {
        showMessage(FacesMessage.SEVERITY_INFO, "Registro Movido", "De columna: " + (event.getFromIndex() + 1) + " a columna: " + (event.getToIndex() + 1));
    }
    
    @Override
    public void deleteRow() {    
        if(getController().deleteById(selectedCheckStocktaking.getId(), getLoggedUser()))
        {

            showMessage(FacesMessage.SEVERITY_INFO,
                    "Cotejar inventario",
                    "Se eliminó correctamente");
            
        }
        fillDataTableBetweenDates();
    }
    
    @PostConstruct
    public void init() {
        logger.info("init");
        try {
            loadBundlePropertyFile();
            initOneWeekBeforeToCurrdate();
            setController(new CheckStocktakingController());
            setGenericController(new GenericValidationController());

            setCheckStocktaking(getController().findBetweenDates(getStartDate(), getEndDate(), getLoggedUser().getLocation().getId()));
            setProducts(getController().fillProducts());

            logger.info("Return CheckStocktaking loaded");
        } catch (Exception e) {
            logger.error("init", e);
        }
    }
    
    private List<CheckStocktakingDetail> fillProducts(CheckStocktaking uuid) {
        List<CheckStocktakingDetail> lista = new ArrayList<>();

        if(getLoggedUser().getLocation().getId().equalsIgnoreCase("4d0859be-e31a-4acb-a690-2a5c2cb027a7"))
            {
                getProducts().forEach((Product prdct) -> {
                    lista.add(
                            new CheckStocktakingDetail(
                                    UUID.randomUUID().toString(), "",
                                    uuid, prdct, prdct.getQuantity(), 0, true, getLoggedUser(), new Date(), prdct.getAmount())
                    );
                });
            }
            else
            {
                getProducts().forEach((Product prdct) -> {
                    lista.add(
                            new CheckStocktakingDetail(
                                    UUID.randomUUID().toString(), "",
                                    uuid, prdct, prdct.getQuantity2(), 0, true, getLoggedUser(), new Date(), prdct.getAmount2())
                    );
                });
            }
        

        return lista;
    }
    
    private void initOneWeekBeforeToCurrdate() {
        try {
            Calendar start = Calendar.getInstance();

            start.set(Calendar.WEEK_OF_YEAR, start.get(Calendar.WEEK_OF_YEAR) - 1);
            start.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

            setStartDate(start.getTime());
            Calendar end = Calendar.getInstance();
            
            end.setTime(DateWrapper.getTodayMXTime());
            end.add(Calendar.HOUR_OF_DAY, 24);
            
             setEndDate(end.getTime());
        } catch (Exception e) {

        }
    }
    
    final Logger logger = LogManager.getLogger(CheckStocktakingBean.class);
    CheckStocktakingController controller;
    private Date startDate;
    private Date endDate;
    private List<CheckStocktaking> checkStocktaking;
    private List<Product> products;
    private String comments;
    private CheckStocktaking selectedCheckStocktaking;
    private GenericValidationController genericController;
    private String commentsBitacora;

    public String getCommentsBitacora() {
        return commentsBitacora;
    }

    public void setCommentsBitacora(String commentsBitacora) {
        this.commentsBitacora = commentsBitacora;
    }

    public List<Product> getProducts() {
        return products;
    }

    public void setProducts(List<Product> products) {
        this.products = products;
    }

    public GenericValidationController getGenericController() {
        return genericController;
    }

    public void setGenericController(GenericValidationController genericController) {
        this.genericController = genericController;
    }

    public Date getStartDate() {
        return startDate;
    }

    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }

    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    public String getComments() {
        return comments;
    }

    public void setComments(String comments) {
        this.comments = comments;
    }

    public CheckStocktakingController getController() {
        return controller;
    }

    public void setController(CheckStocktakingController controller) {
        this.controller = controller;
    }

    public List<CheckStocktaking> getCheckStocktaking() {
        return checkStocktaking;
    }

    public void setCheckStocktaking(List<CheckStocktaking> checkStocktaking) {
        this.checkStocktaking = checkStocktaking;
    }

    public CheckStocktaking getSelectedCheckStocktaking() {
        return selectedCheckStocktaking;
    }

    public void setSelectedCheckStocktaking(CheckStocktaking selectedCheckStocktaking) {
        this.selectedCheckStocktaking = selectedCheckStocktaking;
    }

}
