/*
 * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
 * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
 */
package com.arrebol.taxiservicios.beans.predio;

import com.arrebol.taxiservicios.beans.TaxiGenericBean;
import com.arrebol.taxiservicios.controller.cobranza.CobranzaController;
import com.arrebol.taxiservicios.controller.predio.AbonoLoteController;
import com.arrebol.taxiservicios.controller.predio.PredioController;
import com.arrebol.taxiservicios.controller.predio.PreventaController;
import com.arrebol.taxiservicios.model.core.ContactNumber;
import com.arrebol.taxiservicios.model.enums.GenericEnumType;
import com.arrebol.taxiservicios.model.enums.PersonType;
import com.arrebol.taxiservicios.model.enums.TipoAbono;
import com.arrebol.taxiservicios.model.predio.AbonoLoteView;
import com.arrebol.taxiservicios.model.predio.AbonoProyecto;
import com.arrebol.taxiservicios.model.predio.Lote;
import com.arrebol.taxiservicios.model.predio.Predio;
import com.arrebol.taxiservicios.model.view.PersonListView;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.net.URL;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.imageio.ImageIO;
import javax.inject.Named;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.xml.JRXmlLoader;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 *
 * @author Usuario
 */
@Named("pagosAProveedorBean")
@ViewScoped
public class PagosAProveedorBean extends TaxiGenericBean implements Serializable {

    private static final long serialVersionUID = -2400590341745672164L;
    final Logger logger = LogManager.getLogger(PagosAProveedorBean.class);
    private PreventaController controladorPreventa;
    private CobranzaController cobranzaController;
    private PredioController predioController;
    private AbonoLoteController abonoLoteController;

    private List<Predio> predios;
    private Predio selectedPredio;
    private Lote selectedLote;
    private List<PersonListView> personas;
    private String selectUser;
    private String folioLote;
    private List<AbonoProyecto> abonos;
    private AbonoProyecto selectAbono;
    private Double pagoDado;
    private Date startDate;
    private Date endDate;
    private Date today;
    private Double pagoPersonalizado;
    private Double procentaje;
    private Double totalAbono;
    private List<AbonoLoteView> listAbonoLoteView;
    private Boolean activeButton;

    private JasperPrint print;
    private boolean active2;

    @PostConstruct
    public void init() {
        logger.info("init PagosAProveedorBean");
        try {
            LocalDate fechaLocalHoy = LocalDate.now();
            LocalDate fechaLocalMenosUmMes = fechaLocalHoy.minusMonths(1);
            setToday(new Date());
            setStartDate(Date.from(fechaLocalMenosUmMes.atStartOfDay(ZoneId.systemDefault()).toInstant()));
            setEndDate(Date.from(fechaLocalHoy.atStartOfDay(ZoneId.systemDefault()).toInstant()));
            loadBundlePropertyFile();
            setControladorPreventa(new PreventaController());
            setPredioController(new PredioController());
            setPersonas(getControladorPreventa().findListOfPersonsByType(PersonType.PROVIDER, getLoggedUser().getLocation()));
            setPagoPersonalizado(0D);
            setTotalAbono(0D);
            setProcentaje(100D);
            setActive2(true);
            setActiveButton(false);
        } catch (Exception e) {
            logger.error("CobranzaBean init", e);
        }
    }

    public void calcular() {
        setCobranzaController(new CobranzaController());
        Double abonoLote = getCobranzaController().sumAbonoLote(getSelectedPredio().getId(), startDate, endDate);
        Double abonoLoteDetalle = getCobranzaController().sumAbonoLoteDetalle(getSelectedPredio().getId(), startDate, endDate);

        setPagoPersonalizado(abonoLote + abonoLoteDetalle);
        setTotalAbono(getPagoPersonalizado() * (getProcentaje() / 100));
        setActiveButton(true);
    }
    
    public void cargarAbonos(){
        try {
            setCobranzaController(new CobranzaController());
            setListAbonoLoteView(getCobranzaController().fillAbonoLoteAndSubAbonoByPredioAndDatesOrderByfolio(getSelectedPredio(), TipoAbono.ABONO, getStartDate(), getEndDate()));
        } catch (Exception e) {
        }
    }

    public void calcularTotalAbono() {
        setTotalAbono(getPagoPersonalizado() * (getProcentaje() / 100));

    }

    public void updatePredio() {

        setPredios(getPredioController().fillPredioByProveedor(getSelectUser()));
    }

    public void fillAbonoProyectoByPredio() {

        setAbonos(getPredioController().fillAbonoProyectoByPredio(getSelectedPredio()));
    }

    public void payAbonoPerzonalizado() {

        try {
            AbonoProyecto temp = new AbonoProyecto();

            temp.setFechaAPagar(new Date());

            temp.setSaldoAnterior(getTotalAbono());
            temp.setSaldoNuevo(getTotalAbono());
            temp.setPago(getTotalAbono());
            temp.setCantidadPagada(getTotalAbono());
            temp.setTipoAbono(TipoAbono.ABONO);
            temp.setEstatusActivo(GenericEnumType.ENABLED);
            temp.setPagoEstatus(GenericEnumType.ENABLED);
            temp.setPredio(getSelectedPredio());
            temp.setFechaFin(getEndDate());
            temp.setFechaInicio(getStartDate());
            temp.setLastUpdatedBy(getLoggedUser());
            temp.setLastUpdatedOn(temp.getFechaAPagar());
            temp.setPorcentaje(getProcentaje());
            temp.setTotalCalculado(getPagoPersonalizado());
            
            //se validan los folios asiciados los abonos lote y abono lote detalleentre las fechas seleccinadas 
            setCobranzaController(new CobranzaController());
            List<AbonoLoteView> findFolios = getCobranzaController().fillAbonoLoteAndSubAbonoByPredioAndDatesOrderByfolio(getSelectedPredio(), TipoAbono.ABONO, getStartDate(), getEndDate());
            String folios=null;
            if (!findFolios.isEmpty()) {
                try {
                    folios = findFolios.get(0).getFolio();
                } catch (Exception e) {                   
                }                
                 if (findFolios.size() > 1) {
                     try {                   
                        folios += ", " + findFolios.get(findFolios.size() - 1).getFolio();                    
                    } catch (Exception e) {                    
                    }
                 }                
            }        
            temp.setFolios(folios);
            
            setSelectAbono(temp);
            getPredioController().addAbonoProyecto(getSelectAbono(), getLoggedUser(), true);
            showMessage(FacesMessage.SEVERITY_INFO, "Pagado", "Abono pagado correctamente ");
            generarReposteAbonos();
            setActive2(false);
        } catch (Exception e) {
            logger.error("payAbono: " + e);
            showMessage(FacesMessage.SEVERITY_FATAL, "Error", "Error al pagar");
        }

        setPagoPersonalizado(0D);
        setTotalAbono(0D);
        setProcentaje(100D);

    }

    public void generarReposteAbonos() throws IOException {
        //Crear reporte PDF
        //String filePathImagenEmpresa = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/resources/jasper-reports/crov-inmobiliaria-logo.jpg");
        URL url;

        if (getSelectedPredio().getLocation().getLogo() != null) {
            url = new URL("https://crov-inmobiliaria.s3.us-east-2.amazonaws.com/" + getSelectedLote().getManzana().getPredio().getLocation().getLogo());

        } else {
            url = new URL("https://crov-inmobiliaria.s3.us-east-2.amazonaws.com/crov-inmobiliaria-logo.png");
        }

        java.awt.Image imagenEmpresa = ImageIO.read(url);
        setCobranzaController(new CobranzaController());

        List<AbonoLoteView> abonosAndSub = getCobranzaController().fillAbonoLoteAndSubAbonoByPredioAndDatesOrderByfolio(selectedPredio, TipoAbono.ABONO, getSelectAbono().getFechaInicio(), getSelectAbono().getFechaFin());

        // Corrección del saldo nuevo y el saldo anterior con base en la cantidad pagada 
        Map<String, Object> parameters = new HashMap<String, Object>();
        JRBeanCollectionDataSource abonosLote = new JRBeanCollectionDataSource(abonosAndSub);
        parameters.put("abonosLote", abonosLote);
        parameters.put("imagenEmpresa", imagenEmpresa);
        parameters.put("nombreEmpresa", getLoggedUser().getLocation().getBusinessName() != null ? getLoggedUser().getLocation().getBusinessName() : "");
        parameters.put("rfcEmpresa", getLoggedUser().getLocation().getRfc() != null ? getLoggedUser().getLocation().getRfc() : "");
        parameters.put("correoEmpresa", getLoggedUser().getLocation().getMail() != null ? getLoggedUser().getLocation().getMail() : "");
        parameters.put("telefonoEmpresa", getLoggedUser().getLocation().getPhone() != null ? getLoggedUser().getLocation().getPhone() : "");
        parameters.put("regimenEmpresa", getLoggedUser().getLocation().getTaxRegime() != null ? getLoggedUser().getLocation().getTaxRegime().getNombre() : "");
        parameters.put("direccionEmpresa", getLoggedUser().getLocation().getAddress() != null ? getLoggedUser().getLocation().getAddress() : "");
        //datos de persona

        parameters.put("nombreCliente", getSelectedPredio().getPropetiario().getFirstName() + " " + getSelectedPredio().getPropetiario().getSecondName() + " " + getSelectedPredio().getPropetiario().getLastName() + " " + getSelectedPredio().getPropetiario().getMiddleName());
        setAbonoLoteController(new AbonoLoteController());
        ContactNumber contactNumber = getAbonoLoteController().finPhoneByClient(getSelectedPredio().getPropetiario().getId());
        parameters.put("contactNumber", contactNumber != null ? contactNumber.getPhone() : "");

        //Datos predio, manzana, lote
        parameters.put("fecha", new Date());
        parameters.put("nombreProyecto", getSelectedPredio().getNombreProyecto());
        parameters.put("totalAbonos", getSelectAbono().getPago());
        parameters.put("totalAbonoCompleto", getSelectAbono().getTotalCalculado());
        parameters.put("porcentaje", getSelectAbono().getPorcentaje());

        parameters.put("fechaInicial", getSelectAbono().getFechaInicio());
        parameters.put("fechaFinal", getSelectAbono().getFechaFin());
        //se extraen la cantidad de pagos
        setCobranzaController(new CobranzaController());

        try {
            String filePath = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/resources/jasper-reports/reportePagoPropietarioLote.jrxml");
            File file = new File(filePath);
            JasperDesign jasperDesign = JRXmlLoader.load(file);
            JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
            JasperPrint printt = JasperFillManager.fillReport(jasperReport, parameters, new JREmptyDataSource());
            JasperExportManager.exportReportToPdfFile(printt, "pagos.pdf");
            setPrint(printt);
        } catch (JRException e) {
            logger.error("Error al generar el reporte de compra : " + e);
            showMessage(FacesMessage.SEVERITY_FATAL, "Error", "Error al generar el reporte de compra.");
        }
    }

    public void descargarArchivo() throws IOException {
        try {
            HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
            response.addHeader("content-disposition", "attachment;filename = archivo.pdf");
            ServletOutputStream stream = response.getOutputStream();
            JasperExportManager.exportReportToPdfStream(getPrint(), stream);
            FacesContext.getCurrentInstance().responseComplete();
            setPagoPersonalizado(0D);
            setTotalAbono(0D);
            setProcentaje(100D);
            setActive2(true);
        } catch (IOException | JRException e) {
            logger.error("Error al descargar el reporte de compra : " + e);
        }
    }

    public void payAbono() {
        logger.info("init payAbono");

        try {

            getSelectAbono().setPagoEstatus(GenericEnumType.ENABLED);
            getSelectAbono().setCantidadPagada(getPagoDado());
            getPredioController().addAbonoProyecto(getSelectAbono(), getLoggedUser(), false);
            showMessage(FacesMessage.SEVERITY_INFO, "Pagado", "Abono pagado correctamente ");
        } catch (Exception e) {
            logger.error("payAbono: " + e);
            showMessage(FacesMessage.SEVERITY_FATAL, "Error", "Error al pagar");
        }

    }

    public PreventaController getControladorPreventa() {
        return controladorPreventa;
    }

    public void setControladorPreventa(PreventaController controladorPreventa) {
        this.controladorPreventa = controladorPreventa;
    }

    public List<Predio> getPredios() {
        return predios;
    }

    public void setPredios(List<Predio> predios) {
        this.predios = predios;
    }

    public List<PersonListView> getPersonas() {
        return personas;
    }

    public void setPersonas(List<PersonListView> personas) {
        this.personas = personas;
    }

    public String getSelectUser() {
        return selectUser;
    }

    public void setSelectUser(String selectUser) {
        this.selectUser = selectUser;
    }

    public String getFolioLote() {
        return folioLote;
    }

    public void setFolioLote(String folioLote) {
        this.folioLote = folioLote;
    }

    public Lote getSelectedLote() {
        return selectedLote;
    }

    public void setSelectedLote(Lote selectedLote) {
        this.selectedLote = selectedLote;
    }

    public List<AbonoProyecto> getAbonos() {
        return abonos;
    }

    public void setAbonos(List<AbonoProyecto> abonos) {
        this.abonos = abonos;
    }

    public AbonoProyecto getSelectAbono() {
        return selectAbono;
    }

    public void setSelectAbono(AbonoProyecto selectAbono) {
        this.selectAbono = selectAbono;
    }

    public CobranzaController getCobranzaController() {
        return cobranzaController;
    }

    public void setCobranzaController(CobranzaController cobranzaController) {
        this.cobranzaController = cobranzaController;
    }

    public Double getPagoDado() {
        return pagoDado;
    }

    public void setPagoDado(Double pagoDado) {
        this.pagoDado = pagoDado;
    }

    public PredioController getPredioController() {
        return predioController;
    }

    public void setPredioController(PredioController predioController) {
        this.predioController = predioController;
    }

    public Predio getSelectedPredio() {
        return selectedPredio;
    }

    public void setSelectedPredio(Predio selectedPredio) {
        this.selectedPredio = selectedPredio;
    }

    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 Date getToday() {
        return today;
    }

    public void setToday(Date today) {
        this.today = today;
    }

    public Double getPagoPersonalizado() {
        return pagoPersonalizado;
    }

    public void setPagoPersonalizado(Double pagoPersonalizado) {
        this.pagoPersonalizado = pagoPersonalizado;
    }

    public Double getProcentaje() {
        return procentaje;
    }

    public void setProcentaje(Double procentaje) {
        this.procentaje = procentaje;
    }

    public Double getTotalAbono() {
        return totalAbono;
    }

    public void setTotalAbono(Double totalAbono) {
        this.totalAbono = totalAbono;
    }

    public AbonoLoteController getAbonoLoteController() {
        return abonoLoteController;
    }

    public void setAbonoLoteController(AbonoLoteController abonoLoteController) {
        this.abonoLoteController = abonoLoteController;
    }

    public JasperPrint getPrint() {
        return print;
    }

    public void setPrint(JasperPrint print) {
        this.print = print;
    }

    public boolean isActive2() {
        return active2;
    }

    public void setActive2(boolean active2) {
        this.active2 = active2;
    }

    public List<AbonoLoteView> getListAbonoLoteView() {
        return listAbonoLoteView;
    }

    public void setListAbonoLoteView(List<AbonoLoteView> listAbonoLoteView) {
        this.listAbonoLoteView = listAbonoLoteView;
    }

    public Boolean getActiveButton() {
        return activeButton;
    }

    public void setActiveButton(Boolean activeButton) {
        this.activeButton = activeButton;
    }

}
