package com.cosmodas.pedidos;

/*
 * 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.
 */

import com.cosmodas.FacadeCosmos.ConsultoresFacadeLocal;
import com.cosmodas.FacadeCosmos.ProcesoPedidosFacadeLocal;
import com.cosmodas.FacadeCosmos.ProductosFacadeLocal;
import com.cosmodas.FacadeCosmos.RutaRepartoFacadeLocal;
import com.cosmodas.FacadeCosmos.SucursalesFacadeLocal;
import com.cosmodas.EntCosmos.DetalleProcesoPedido;
import com.cosmodas.EntCosmos.ProcesoPedidos;
import com.cosmodas.EntCosmos.Sucursales;
import com.cosmodas.EntCosmos.WcUsuarios;
import com.cosmodas.EntCosmos.proKardex;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.AttributeSet;
import javax.print.attribute.HashAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.standard.ColorSupported;
import javax.print.attribute.standard.PrinterName;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;

import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.apache.commons.io.FileUtils;

/**
 * @author informatica
 */
@ManagedBean
@ViewScoped
public class bpedidos implements Serializable {

    @EJB
    private ProcesoPedidosFacadeLocal ppfl;
    @EJB
    SucursalesFacadeLocal daoSucursalLo;
    @EJB
    ConsultoresFacadeLocal consultoresFacadeLocal;
    @EJB
    ProductosFacadeLocal productosFacadeLocal;
    @EJB
    RutaRepartoFacadeLocal rrfl;

    private List<ProcesoPedidos> listaPedidos;
    private List<ProcesoPedidos> listaPedidosSupervisoras;
    private List<ProcesoPedidos> pedidosCreditos;
    private List<ProcesoPedidos> pedidosDespacho;
    private List<ProcesoPedidos> pedidosCreditosRep;
    private List<ProcesoPedidos> pedidosDespachoRep;
    private String archiNuevoPdf;
    private List<proKardex> listKardex;
    private ProcesoPedidos procSelecKar;
    private ProcesoPedidos IncioPreparcionSele;
    private ProcesoPedidos despachoPreparcionSele;
    private Date fechaInicioBusqueda;
    private Date fechafinBusqueda;
    private JasperPrint jasperPrint;
    private String alarmaCreditos;
    private String filtoReporteDespacho;
    private List<ProcesoPedidos> territorios;
    private String alarmaDespacho;
    private String terriorioSelect;

    private ExternalContext exc;
    @Inject
    private Sucursales sucursal;
    @Inject
    private WcUsuarios usuario;

    @PostConstruct
    public void init() {

        Calendar cal1 = Calendar.getInstance();
        cal1.add(Calendar.MONTH, -4);
        cal1.set(Calendar.DATE, 1);
        this.exc = FacesContext.getCurrentInstance().getExternalContext();
        this.usuario = (WcUsuarios) exc.getSessionMap().get("usuario");
        this.sucursal = (Sucursales) exc.getSessionMap().get("sucursal");

        this.filtoReporteDespacho = "";
        this.fechaInicioBusqueda = cal1.getTime();
        this.fechafinBusqueda = new Date();
        this.listaPedidos = ppfl.reportePedidosDespacho();
        this.pedidosCreditos = ppfl.pedidosCreditos();
        this.pedidosDespacho = ppfl.pedidoDespacho();

        if (true) {
            this.listaPedidosSupervisoras = new ArrayList<>();
            this.pedidosCreditosRep = new ArrayList<>();
            this.pedidosDespachoRep = new ArrayList<>();
        } else {
//            this.listaPedidosSupervisoras = ppfl.pedidosPorTerritorios(bLog.getUsersAndPass().getTerritorio());
//            this.pedidosCreditosRep = ppfl.pedidosCreditosRep(bLog.getUsersAndPass().getTerritorio());
//            this.pedidosDespachoRep = ppfl.pedidoDespachoRep(bLog.getUsersAndPass().getTerritorio());
        }

    }

    public List<ProcesoPedidos> getListaPedidosSupervisoras() {
        return listaPedidosSupervisoras;
    }

    public void setListaPedidosSupervisoras(List<ProcesoPedidos> listaPedidosSupervisoras) {
        this.listaPedidosSupervisoras = listaPedidosSupervisoras;
    }

    public String getTerriorioSelect() {
        return terriorioSelect;
    }

    public void setTerriorioSelect(String terriorioSelect) {
        this.terriorioSelect = terriorioSelect;
    }

    public List<ProcesoPedidos> getTerritorios() {
        return territorios;
    }

    public void setTerritorios(List<ProcesoPedidos> territorios) {
        this.territorios = territorios;
    }

    public String getFiltoReporteDespacho() {
        return filtoReporteDespacho;
    }

    public void setFiltoReporteDespacho(String filtoReporteDespacho) {
        this.filtoReporteDespacho = filtoReporteDespacho;
    }

    public List<ProcesoPedidos> getPedidosCreditosRep() {
        return pedidosCreditosRep;
    }

    public void setPedidosCreditosRep(List<ProcesoPedidos> pedidosCreditosRep) {
        this.pedidosCreditosRep = pedidosCreditosRep;
    }

    public List<ProcesoPedidos> getPedidosDespachoRep() {
        return pedidosDespachoRep;
    }

    public void setPedidosDespachoRep(List<ProcesoPedidos> pedidosDespachoRep) {
        this.pedidosDespachoRep = pedidosDespachoRep;
    }

    public String getAlarmaCreditos() {
        return alarmaObtenerCreditos();
    }

    public void setAlarmaCreditos(String alarmaCreditos) {
        this.alarmaCreditos = alarmaCreditos;
    }

    public String getAlarmaDespacho() {
        return alarmaObtenerDespacho();
    }

    public void setAlarmaDespacho(String alarmaDespacho) {
        this.alarmaDespacho = alarmaDespacho;
    }

    public ProcesoPedidos getIncioPreparcionSele() {
        return IncioPreparcionSele;
    }

    public void setIncioPreparcionSele(ProcesoPedidos IncioPreparcionSele) {
        this.IncioPreparcionSele = IncioPreparcionSele;
    }

    public ProcesoPedidos getDespachoPreparcionSele() {
        return despachoPreparcionSele;
    }

    public void setDespachoPreparcionSele(ProcesoPedidos despachoPreparcionSele) {
        despachoPreparcionSele.setDespachadoB(Boolean.TRUE);
        despachoPreparcionSele.setDespachado(new Date());
        ppfl.editaProcesob(despachoPreparcionSele);
        this.despachoPreparcionSele = despachoPreparcionSele;
    }

    public List<ProcesoPedidos> getPedidosCreditos() {
        return pedidosCreditos;
    }

    public void setPedidosCreditos(List<ProcesoPedidos> pedidosCreditos) {
        this.pedidosCreditos = pedidosCreditos;
    }

    public List<ProcesoPedidos> getPedidosDespacho() {
        return pedidosDespacho;
    }

    public void setPedidosDespacho(List<ProcesoPedidos> pedidosDespacho) {
        this.pedidosDespacho = pedidosDespacho;
    }

    public Date getFechaInicioBusqueda() {
        return fechaInicioBusqueda;
    }

    public void setFechaInicioBusqueda(Date fechaInicioBusqueda) {
        this.fechaInicioBusqueda = fechaInicioBusqueda;
    }

    public Date getFechafinBusqueda() {
        return fechafinBusqueda;
    }

    public void setFechafinBusqueda(Date fechafinBusqueda) {
        this.fechafinBusqueda = fechafinBusqueda;
    }

    public ProcesoPedidos getProcSelecKar() {
        return procSelecKar;
    }

    public void setProcSelecKar(ProcesoPedidos procSelecKar) {
        this.procSelecKar = procSelecKar;
    }

    public List<ProcesoPedidos> getListaPedidos() {
        return listaPedidos;
    }

    public void setListaPedidos(List<ProcesoPedidos> listaPedidos) {
        this.listaPedidos = listaPedidos;
    }

    public String getArchiNuevoPdf() {
        return archiNuevoPdf;
    }

    public void setArchiNuevoPdf(String archiNuevoPdf) {
        this.archiNuevoPdf = archiNuevoPdf;
    }

    public List<proKardex> getListKardex() {
        return listKardex;
    }

    public void setListKardex(List<proKardex> listKardex) {
        this.listKardex = listKardex;
    }

    public void openPDF(ProcesoPedidos p) throws IOException, JRException {

        CreaPDF(p);

        System.out.println(p.getConsultorCodigo());
        ServletContext ctx = (ServletContext) FacesContext.getCurrentInstance()
                .getExternalContext().getContext();
        String realPath = ctx.getRealPath("/");

        System.out.println("direccion = " + realPath);

        File source = new File("/opt/pedidos/" + p.getIdpp() + ".pdf");
        File dest = new File(realPath + "/apps/pdf/" + p.getIdpp() + ".pdf");
        archiNuevoPdf = "./pdf/" + p.getIdpp() + ".pdf";
        FileUtils.copyFile(source, dest, false);

        ppfl.editaImpresion(p.getIdpp());
    }

    public bpedidos() {

    }

    public void actualizaTabla() {

        if (filtoReporteDespacho.isEmpty() || filtoReporteDespacho.equals("todos")) {
            this.listaPedidos = ppfl.reportePedidosDespacho();
        } else if (filtoReporteDespacho.equals("fact")) {
            this.listaPedidos = ppfl.reportePedidosDespachoFact();
        } else if (filtoReporteDespacho.equals("prep")) {
            this.listaPedidos = ppfl.reportePedidosDespachoPrep();
        }

        this.pedidosCreditos = ppfl.pedidosCreditos();
        this.pedidosDespacho = ppfl.pedidoDespacho();

    }

    public void actualizaTablaSup() {
        try {
            if (filtoReporteDespacho.isEmpty() || filtoReporteDespacho.equals("todos")) {
                // this.listaPedidosSupervisoras = ppfl.pedidosPorTerritorios(bLog.getUsersAndPass().getTerritorio());
            } else if (filtoReporteDespacho.equals("fact")) {
                //  this.listaPedidosSupervisoras = ppfl.pedidosPorTerritoriosFact(bLog.getUsersAndPass().getTerritorio());
            } else if (filtoReporteDespacho.equals("prep")) {
                //  this.listaPedidosSupervisoras = ppfl.pedidosPorTerritoriosPrep(bLog.getUsersAndPass().getTerritorio());
            }
        } catch (Exception e) {
            this.listaPedidosSupervisoras = new ArrayList<>();
        }
    }

    public void actualizaTablaReparto() {
        this.pedidosCreditosRep = ppfl.pedidosCreditosRep(terriorioSelect);
        this.pedidosDespachoRep = ppfl.pedidoDespachoRep(terriorioSelect);

    }

    public long diferenciasFecha(Date date1, String unidad) {
        TimeUnit timeUnit = TimeUnit.SECONDS;
        if (unidad.equalsIgnoreCase("min")) {
            timeUnit = TimeUnit.MINUTES;
        }

        long diffInMillies = new Date().getTime() - date1.getTime();
        return timeUnit.convert(diffInMillies, TimeUnit.MILLISECONDS);
    }

    public String validaPorcesosFactura(boolean i) {
        String rs = "PREPARACION";

        if (i) {
            rs = "FACTURADO";
        }
        return rs;

    }

    public String validaPorcesosFacturaColor(boolean i) {
        String rs = "red";

        if (i) {
            rs = "green";
        }
        return rs;

    }

    public long diferenciasFechaTerminado(Date sellado, String unidad, boolean facturado, Date tiempoFactura) {

        if (facturado) {

            TimeUnit timeUnit = TimeUnit.SECONDS;
            if (unidad.equalsIgnoreCase("min")) {
                timeUnit = TimeUnit.MINUTES;
            }

            long diffInMillies = tiempoFactura.getTime() - sellado.getTime();
            return timeUnit.convert(diffInMillies, TimeUnit.MILLISECONDS);

        } else {
            TimeUnit timeUnit = TimeUnit.SECONDS;
            if (unidad.equalsIgnoreCase("min")) {
                timeUnit = TimeUnit.MINUTES;
            }

            long diffInMillies = new Date().getTime() - sellado.getTime();
            return timeUnit.convert(diffInMillies, TimeUnit.MILLISECONDS);
        }

    }

    public void busquedaKardex() {

        this.listKardex = daoSucursalLo.findCallKardex(procSelecKar.getConsultorCodigo().getConsultorCodigo(), fechaInicioBusqueda, fechafinBusqueda);
        System.out.println("");

    }

    public String validaEstado(int input) {

        String rs = "No Revisado";

        switch (input) {

            case 0:
                rs = "No Revisado";
                break;
            case 1:
                rs = "DENEGADO";
                break;
            case 2:
                rs = "CREDITO";
                break;
            case 3:
                rs = "CONTADO";
                break;
            default:
                break;

        }

        return rs;
    }

    public void aprobar(String inp, String reparto) throws JRException, IOException, PrintException {
        ProcesoPedidos pprs = new ProcesoPedidos();
        //    ProcesoPedidos pout = ppfl.busquedaUltimoPedido();
        pprs = getProcSelecKar();

        switch (inp) {
            case "den":
                pprs.setAprobado(1);
                break;
            case "cre":
                pprs.setAprobado(2);
                pprs.setUsuarioSello(usuario.getUsuarioCodigo());
                if (!reparto.equals("reparto")) {
                    pprs.setNumeracionDiaria(creaTicketPDF(pprs));
                }

                break;
            case "con":
                pprs.setAprobado(3);
                pprs.setUsuarioSello(usuario.getUsuarioCodigo());
                if (!reparto.equals("reparto")) {
                    pprs.setNumeracionDiaria(creaTicketPDF(pprs));
                }

                break;
            default:
                break;
        }

        ppfl.editaProceso(pprs);
        listKardex = new ArrayList<>();
        // if (!reparto.equals("reparto")) {
        CreaPDF(pprs);
        //   }

    }

    public void fillReport(ProcesoPedidos p) throws JRException {
        List<CuerpoPedido> dcp = new ArrayList<>();
        for (DetalleProcesoPedido cp : p.getDetalleProcesoPedidoList()) {

            CuerpoPedido dpp = new CuerpoPedido();

            dpp.setCantidad(Integer.valueOf(cp.getDetallePedidoCantidad().toString()));
            dpp.setProductoCodigo(cp.getDetalleProcesoPedidoPK().getProductoCodigo());
            dpp.setProductoPrecioConDescuento(cp.getDetallePedidoConDescuento().doubleValue());
            dpp.setProductoPrecioSinDescuento(cp.getDetallePedidoConDescuento().doubleValue());
            dpp.setProdutoOferta(cp.getDetallePedidoOfertaDes());
            dpp.setProductoNombre(productosFacadeLocal.find(cp.getDetalleProcesoPedidoPK().getProductoCodigo()).getProductoNombre());
            dcp.add(dpp);
        }

        JRBeanCollectionDataSource beanCollectionDataSource = new JRBeanCollectionDataSource(dcp);
        String reportPath = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/reportes/pedidosConsultor.jasper");
        Map parametros = new HashMap();
        parametros.put("totalConDescuesto", p.getTotalConDescuento().toString());
        parametros.put("totalSinDescuesto", p.getTotalSinDescuento().toString());
        parametros.put("consultor_nombre", consultoresFacadeLocal.ObtenerNombreCompleto(p.getConsultorCodigo().getConsultorCodigo()));
        parametros.put("consultor_codigo", p.getConsultorCodigo().getConsultorCodigo());
        parametros.put("territorio", p.getTerritorio());
        parametros.put("observaciones", p.getObservacion());
        parametros.put("tipoPedido", validaEstado(p.getAprobado()));
        parametros.put("noped", p.getNumeracionDiaria().toString());
        jasperPrint = JasperFillManager.fillReport(reportPath, parametros, beanCollectionDataSource);
    }

    public void fillReportSalas(ProcesoPedidos p) throws JRException {

        List<CuerpoPedido> dcp = new ArrayList<>();
        for (DetalleProcesoPedido cp : p.getDetalleProcesoPedidoList()) {

            CuerpoPedido dpp = new CuerpoPedido();

            dpp.setCantidad(Integer.valueOf(cp.getDetallePedidoCantidad().toString()));
            dpp.setProductoCodigo(cp.getDetalleProcesoPedidoPK().getProductoCodigo());
            dpp.setProductoPrecioConDescuento(cp.getDetallePedidoConDescuento().doubleValue());
            dpp.setProductoPrecioSinDescuento(cp.getDetallePedidoConDescuento().doubleValue());
            dpp.setProdutoOferta(cp.getDetallePedidoOfertaDes());
            dpp.setProductoNombre(productosFacadeLocal.find(cp.getDetalleProcesoPedidoPK().getProductoCodigo()).getProductoNombre());
            dcp.add(dpp);
        }

        JRBeanCollectionDataSource beanCollectionDataSource = new JRBeanCollectionDataSource(dcp);
        String reportPath = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/reportes/pedidosConsultorSalas.jasper");
        Map parametros = new HashMap();
        parametros.put("totalConDescuesto", p.getTotalConDescuento().toString());
        parametros.put("totalSinDescuesto", p.getTotalSinDescuento().toString());
        parametros.put("consultor_nombre", consultoresFacadeLocal.ObtenerNombreCompleto(p.getConsultorCodigo().getConsultorCodigo()));
        parametros.put("consultor_codigo", p.getConsultorCodigo().getConsultorCodigo());
        parametros.put("territorio", p.getTerritorio());
        parametros.put("rutaReparto", p.getRutaReparto());
        parametros.put("observaciones", p.getObservacion());
        parametros.put("repartoUbicacion", rrfl.busquedaRuta(p.getCodigoReparto()).getDireccion());
        jasperPrint = JasperFillManager.fillReport(reportPath, parametros, beanCollectionDataSource);
    }

    public void CreaPDF(ProcesoPedidos p) throws JRException, IOException {

        if (p.getRepartoB()) {
            fillReportSalas(p);
        } else {
            fillReport(p);
        }

        JasperExportManager.exportReportToPdfFile(jasperPrint, "/opt/pedidos/" + p.getIdpp() + ".pdf");
        HttpServletResponse httpServletResponse
                = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
    }

    public String obtenerNombre(String codigo) {
        String rs = consultoresFacadeLocal.ObtenerNombreCompleto(codigo);
        ;
        return rs;
    }

    public String convCreditos(boolean i) {
        String rs = "CONTADO";
        if (i) {
            rs = "CREDITO";
        }
        return rs;
    }

    public String convActivo(boolean i) {
        String rs = "INACTIVO";
        if (i) {
            rs = "ACTIVO";
        }
        return rs;
    }

    public String convAbierto(boolean i) {
        String rs = "CERRADO";
        if (i) {
            rs = "ABIERTO";
        }
        return rs;
    }

    public String alarmaObtenerCreditos() {

        boolean pedidoss = false;
        String ruta = null;

        for (ProcesoPedidos p : getPedidosCreditos()) {

            if (p.getAprobado() < 1) {
                pedidoss = true;
            }

        }
        if (pedidoss) {
            ruta = "./../sonidos/alarma.mp3";
        }
        return ruta;
    }

    public String alarmaObtenerDespacho() {

        boolean pedidoss = false;
        String ruta = null;

        for (ProcesoPedidos p : getPedidosDespacho()) {

            if (!p.getInicioSacadoB()) {
                pedidoss = true;
            }

        }
        if (pedidoss) {
            ruta = "./../sonidos/alarma.mp3";
        }
        return ruta;
    }

    public String validaImpreso(Boolean b) {
        String rs = "";

        if (b) {
            rs = "green";
        }

        return rs;
    }

    public void inicioPrimerDia() {

    }

    public int Tickec(ProcesoPedidos p) throws JRException {
        List<ProcesoPedidos> listA = new ArrayList<>();
        listA.add(p);
        Integer corr = ppfl.obtenerCorrelativoDespacho(p.getAprobado());

        JRBeanCollectionDataSource beanCollectionDataSource = new JRBeanCollectionDataSource(listA);
        String reportPath = "/opt/reportesJasper/tickecNumero.jrxml";
        JasperReport jasperReport = JasperCompileManager.compileReport(reportPath);
        Map parametros = new HashMap();
        parametros.put("consultorCodigoA", p.getConsultorCodigo().getConsultorCodigo());
        parametros.put("correlativo", corr.toString());
        parametros.put("nombreConsultor", consultoresFacadeLocal.ObtenerNombreCompleto(p.getConsultorCodigo().getConsultorCodigo()));
        parametros.put("fechaHora", (new Date()).toString());
        parametros.put("territorio", p.getTerritorio());
        parametros.put("usuarioAproba", usuario.getNombreEmpleado());
        parametros.put("tipoPedido", validaEstado(p.getAprobado()));
        jasperPrint = JasperFillManager.fillReport(jasperReport, parametros, beanCollectionDataSource);

        return ppfl.obtenerCorrelativoDespacho(p.getAprobado());
    }

    public int creaTicketPDF(ProcesoPedidos p) throws JRException, IOException, PrintException {
        int rs = Tickec(p);
        JasperExportManager.exportReportToPdfFile(jasperPrint, "/opt/pedidos/ticket" + p.getIdpp() + ".pdf");
        HttpServletResponse httpServletResponse
                = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
        imprimirTicket("ticket" + p.getIdpp() + ".pdf");
        return rs;
    }

    public void imprimirTicket(String doc) throws PrintException, IOException {

        //Archivo que se desea imprimir
        FileInputStream inputStream = new FileInputStream("/opt/pedidos/" + doc);

        //Formato de Documento
        DocFlavor docFormat = DocFlavor.INPUT_STREAM.AUTOSENSE;
        //Lectura de Documento
        Doc document = new SimpleDoc(inputStream, docFormat, null);

        //Nombre de la impresora
        String printerName = "1ticket";

        //Inclusion del nombre de impresora y sus atributos
        AttributeSet attributeSet = new HashAttributeSet();
        attributeSet.add(new PrinterName(printerName, null));
        // attributeSet = new HashAttributeSet();
        //Soporte de color o no
        attributeSet.add(ColorSupported.NOT_SUPPORTED);

        //Busqueda de la impresora por el nombre asignado en attributeSet
        PrintService[] services = PrintServiceLookup.lookupPrintServices(docFormat, attributeSet);

        System.out.println("Imprimiendo en : " + services[0].getName());

        DocPrintJob printJob = services[0].createPrintJob();
        //Envio a la impresora
        printJob.print(document, new HashPrintRequestAttributeSet());

        inputStream.close();
    }

    public void actualzaOk() {

        System.out.println("DERECHOS DE MARLEN LAMUR");

    }

    public String obtenerRutaRepartoOp(String codigo) {
        String rs = "";
        try {
            if (codigo.length() == 4) {

                rs = rrfl.busquedaRuta(codigo).getDireccion();
            }
        } catch (Exception e) {
        }

        return rs;

    }

}
