package com.fp.frontend.controller.armas.solicitud;

import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

import org.primefaces.context.RequestContext;

import com.fp.dto.Request;
import com.fp.dto.Response;
import com.fp.dto.query.DtoQuery;
import com.fp.dto.save.DtoSave;
import com.fp.frontend.controller.AbstractController;
import com.fp.frontend.controller.ReportController;
import com.fp.frontend.controller.alfresco.AlfrescoController;
import com.fp.frontend.controller.armas.parametros.CentroControlArmasController;
import com.fp.frontend.controller.pcustomer.PersonDetailController;
import com.fp.frontend.controller.pgeneral.gene.CatalogDetailController;
import com.fp.frontend.helper.MessageHelper;
import com.fp.frontend.utility.MsgControlArmas;
import com.fp.persistence.parmas.ins.TarmPlanificacionInspeccion;
import com.fp.persistence.parmas.ins.TarmPlanificacionTramite;
import com.fp.persistence.parmas.param.TarmCentroControl;
import com.fp.persistence.parmas.soli.TarmInspeccion;
import com.fp.persistence.parmas.soli.TarmInspeccionArchivo;
import com.fp.persistence.parmas.soli.TarmSolicitudTramite;
import com.fp.persistence.pcustomer.gene.TcustPersonDetail;
import com.fp.persistence.pgeneral.gene.TgeneCatalogDetail;
import com.fp.persistence.pgeneral.safe.TsafeUserDetail;

@SuppressWarnings("serial")
@ManagedBean
@ViewScoped
public class AprobacionPlanInspeccionController extends AbstractController<TarmPlanificacionInspeccion> {

    //Codigo de planificacion(Variable de flujo)
    private Long cplanificacion;

    private TarmCentroControl centroControl;
    String jefeCentroControl;
    private String nombreCentroControl;
    private Boolean reporteGenerado = false;
    private String opcion = "";
    private String observaciones = "";
    private Boolean reporteHabilitado = false;
    private String gradoFuncionario = "";
    private TcustPersonDetail usuario;
    private String xpathflujo = "";

    private List<TarmPlanificacionTramite> listainsepcion;

    private Boolean btnFlujo = false;

    @ManagedProperty(value = "#{planificacionTramiteController}")
    private PlanificacionTramiteController planificacionTramiteController;

    @ManagedProperty(value = "#{reportController}")
    private ReportController reportController;

    @ManagedProperty(value = "#{alfrescoController}")
    private AlfrescoController alfrescoController;

    public AprobacionPlanInspeccionController() throws Exception {
        super(TarmPlanificacionInspeccion.class);
    }

    @PostConstruct
    private void postconstruct() {
        try {
            this.startQuery();
            this.init();
            //super.query();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void startQuery() {
        try {
            this.pasteBpmScreenParameters();
            if (super.getMfilters().get("cplanificacion") != null) {
                cplanificacion = Long.parseLong(super.getMfilters().get("cplanificacion").toString());
            }
            super.getMfilters().clear();
        } catch (Exception e) {
            MessageHelper.setMessageError(e);
        }
    }

    private void init() {
        try {
            recperpage = 15;
            lrecord = new ArrayList<>();
            record = new TarmPlanificacionInspeccion();
            beanalias = "APROBACIONPLANINSPECCIONCONTROLLER";
            this.planificacionTramiteController = new PlanificacionTramiteController();
            this.planificacionTramiteController.setLrecord(new ArrayList<TarmPlanificacionTramite>());
            btnFlujo = false;

            //Cargando la planificacion por el codigo
            this.record = PlanificacionInspeccionController.findPorCodigo(this.cplanificacion);

            //   this.listainsepcion=PlanificacionTramiteController.findPorCodigoPlanificacion(this.cplanificacion);
            if (this.record != null && this.record.getPk() != null) {
                //Cargando las inspecciones
                this.planificacionTramiteController.setCplanificacion(this.record.getPk());
                this.planificacionTramiteController.setRecperpage(4000);
                //PlanificacionInspeccionController inspeccion = new PlanificacionInspeccionController();
                //inspeccion.getPresupuesto1();
                this.record.getPresupuesto().toString();
                this.planificacionTramiteController.querydatabaseAprobacion();

                Collections.sort(planificacionTramiteController.getLrecord(), new Comparator<TarmPlanificacionTramite>() {
                    public int compare(TarmPlanificacionTramite p1, TarmPlanificacionTramite p2) {
                        return new Long(p1.getMesnumero()).compareTo(p2.getMesnumero());
                    }
                });

                //Cargando el centro de control
                this.centroControl = CentroControlArmasController.findPorCodigo(this.record.getCcentrocontrol());
                this.nombreCentroControl = centroControl.getModifiedData().get("desnombreinstitucion") + "";

                //Obteniendo el jefe del centro de control
                this.jefeCentroControl = centroControl.getModifiedData().get("nombre") + "";//PersonDetailController.find(this.centroControl.getPersoncode().toString());            	

                //Obteniendo el grado del jefe del centro de control
                gradoFuncionario = centroControl.getModifiedData().get("desgrado") + "" + " - ";

                //Obteniendo los datos del usuario logueado
                TsafeUserDetail tsafeUserDetail = (TsafeUserDetail) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("TSAFEUSERDETAIL");
                this.usuario = PersonDetailController.find(tsafeUserDetail.getPk().getPersoncode().toString());

            }

        } catch (Exception e) {
            MessageHelper.setMessageError(e);
        }
    }

    private void initConsulta() {
        try {
            recperpage = 15;
            lrecord = new ArrayList<>();
            record = new TarmPlanificacionInspeccion();
            beanalias = "APROBACIONPLANINSPECCIONCONTROLLER";
        } catch (Exception e) {
            MessageHelper.setMessageError(e);
        }
    }

    @Override
    public void query() throws Exception {
        MessageHelper.setMessageError("msg_notQuery");
        super.query();
    }

    @Override
    public void create() throws Exception {
        super.create();
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void querydatabase() {
        try {
            DtoQuery dto = super.getDtoQuery(true);

            HashMap<String, DtoQuery> mtables = new HashMap<String, DtoQuery>();
            mtables.put(beanalias, dto); // permite adicionar mas de una tabla.

            Request request = callerhelper.getRequest();
            request.setQueryTables(mtables);

            Response resp = callerhelper.executeQuery(request);

            if (resp.getResponseCode().compareTo(Response.RESPONSE_OK) != 0) {
                lrecord = new ArrayList<TarmPlanificacionInspeccion>();
                MessageHelper.setMessageError(resp);
            } else {
                lrecord = (List<TarmPlanificacionInspeccion>) resp.get(beanalias);
//                if(!lrecord.isEmpty() ){
//                	record=lrecord.get(0);
//                }
                super.postQuery(lrecord);
            }

        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
        }
    }

    @Override
    public void save() {
        try {

            DtoSave dtosave = super.getDtoSave();
            dtosave.setReturnpk(true); // Para que el core devuelva el pk de los registros nuevos.
            HashMap<String, DtoSave> msave = new HashMap<String, DtoSave>();

            Request request = callerhelper.getRequest();
            msave.put(beanalias, dtosave); // adicionar metadata de mantenimiento para cada tabla.

            request.setSaveTables(msave);
            request.modifiedData().put("cplanificacion", this.record.getPk());
            bpmDataStatus = "A";
            if (this.opcion.equalsIgnoreCase("rechazar")) {
                bpmDataStatus = "D";
            }
            Response resp = callerhelper.executeSave(request);
            if (resp.getResponseCode().compareTo(Response.RESPONSE_OK) == 0) {
                this.postCommit(resp);
                this.planificacionTramiteController.postCommit(resp);
                MessageHelper.setMessageInfo(resp);
                this.reporteHabilitado = true;
                btnFlujo = true;
            } else {
                MessageHelper.setMessageError(resp);
                //this.planificacionSalvada=false;
            }
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
        }
    }

    /**
     * Metodo que persiste la planificacion con el xpath del pdf del reporte en
     * el alfresco
     */
    public void saveXpathReporte() {
        try {
            DtoSave dtosave = super.getDtoSave();
            dtosave.setReturnpk(true); // Para que el core devuelva el pk de los registros nuevos.
            HashMap<String, DtoSave> msave = new HashMap<String, DtoSave>();

            Request request = callerhelper.getRequest();
            msave.put(beanalias, dtosave); // adicionar metadata de mantenimiento para cada tabla.

            request.setSaveTables(msave);

            Response resp = callerhelper.executeSave(request);
            if (resp.getResponseCode().compareTo(Response.RESPONSE_OK) == 0) {
                this.postCommit(resp);
                MessageHelper.setMessageInfo(resp);
            } else {
                MessageHelper.setMessageError(resp);
            }
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
        }
    }

    /**
     * Metodo que aprueba el plan
     *
     * @throws Exception
     */
    public void aprobar() throws Exception {
        try {
            if (this.opcion.equalsIgnoreCase("Aprobar")) {
                this.record.setAprobada("Y");
                update();
                save();
            }
        } catch (Exception e) {
            MessageHelper.setMessageError(e);
        }
    }

    /**
     * Ejecuta un reporte de custodios
     *
     * @param name Nombre del reporte a generar.
     */
    public InputStream generateReport() {
        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
        String path = "armas/reports/planInspeccion";
        String filename = MsgControlArmas.getProperty("lbl_planInspeccionAnual");

        //Cargando la planificacion
        this.record = PlanificacionInspeccionController.findPorCodigo(cplanificacion);

        //Fija parametros del report.
        HashMap<String, Object> parameters = new HashMap<>();
        parameters.put("pathLogoIzquierda", "repo:/maia/1/image/comandoconjunto");
        parameters.put("pathLogoDerecha", "repo:/maia/1/image/selloarmas");

        //cplanificacion
        parameters.put("cplanificacion", this.record.getPk());

        //Fecha actual
        parameters.put("fechaActual", new java.sql.Date(Calendar.getInstance().getTimeInMillis()));

        //Codigo
        parameters.put("codigo", this.record.getCodigo());

        //Anno
        parameters.put("anno", this.record.getAnno().toString());

        //Codigo
        parameters.put("codigo", this.record.getCodigo());

        //Nombre del centro de control
        parameters.put("nombreCentro", this.nombreCentroControl);

        //Fecha actual
        parameters.put("fechaActual", Calendar.getInstance().getTime());

        //cplanificacion
        parameters.put("cplanificacion", this.record.getPk());

        //Fecha actual
        parameters.put("fechaActual", new java.sql.Date(Calendar.getInstance().getTimeInMillis()));

        //Fecha generacion
        parameters.put("fechaGeneracion", sdf.format(this.record.getFechageneracion()));

        //Anno
        parameters.put("anno", this.record.getAnno().toString());

        //Codigo
        parameters.put("codigo", this.record.getCodigo());

        //Fecha Inicio
        parameters.put("fechaInicio", sdf.format(this.record.getFechainicio()));

        //Fecha Fin
        parameters.put("fechaFin", sdf.format(this.record.getFechafin()));

        //Funcionario
        parameters.put("gradoNombreFuncionario", gradoFuncionario + this.jefeCentroControl);
        parameters.put("personcode", this.centroControl.getPersoncode());
        parameters.put("centroControl", "JEFE DEL " + this.nombreCentroControl);

        //presupuesto anual
        TgeneCatalogDetail obj = CatalogDetailController.findCatalogo("TIPOPLANIFICACION", this.record.getIdPlanificacion());
        parameters.put("ctiplanificacion", obj.getDescription());

        // presupuesto anual
        parameters.put("cpresupuestoanual", this.record.getPresupuesto());

        //Usuario
        parameters.put("usuario", this.usuario.getName());
        sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String fechaHora = sdf.format(Calendar.getInstance().getTime());
        parameters.put("fechaHora", fechaHora);

        String format = "pdf";

        InputStream pdf = null;
        try {
            //this.reportController.execute(path, parameters, format, filename, this.getLoginController());
            pdf = this.reportController.jaspertoInputstream(path, parameters, format, filename, this.getLoginController());

            //Generando el xpath
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            StringBuilder ruta = new StringBuilder("cm:Planificacion");
            ruta = ruta.append("/cm:A-").append(calendar.get(Calendar.YEAR));
            ruta = ruta.append("/cm:M-").append((calendar.get(Calendar.MONTH) + 1) <= 9 ? "0" + (calendar.get(Calendar.MONTH) + 1) : (calendar.get(Calendar.MONTH) + 1));
            ruta = ruta.append("/cm:" + "reportePlanInspeccion");
            xpathflujo = ruta.toString();
            this.record.setXpath(xpathflujo + "/cm:" + this.record.getCodigo() + ".pdf");

            //Subiendo el pdf al alfresco
            alfrescoController.uploadFile(pdf, this.record.getCodigo() + ".pdf", xpathflujo);

            update();
            saveXpathReporte();

            this.reporteGenerado = true;
        } catch (Exception ex) {
            MessageHelper.setMessageError(ex);
        }
        return pdf;
    }

    public void probarReporte() {
        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
        String path = "armas/reports/planInspeccion";
        String filename = MsgControlArmas.getProperty("lbl_planInspeccionAnual");

        //Cargando la planificacion
        this.record = PlanificacionInspeccionController.findPorCodigo(28L);

        //Fija parametros del report.
        HashMap<String, Object> parameters = new HashMap<>();
        parameters.put("pathLogoIzquierda", "repo:/maia/1/image/comandoconjunto");
        parameters.put("pathLogoDerecha", "repo:/maia/1/image/selloarmas");

        //cplanificacion
        parameters.put("cplanificacion", this.record.getPk());

        //Fecha actual
        parameters.put("fechaActual", new java.sql.Date(Calendar.getInstance().getTimeInMillis()));

        //Fecha generacion
        parameters.put("fechaGeneracion", sdf.format(this.record.getFechageneracion()));

        //Anno
        parameters.put("anno", this.record.getAnno().toString());

        //Codigo
        parameters.put("codigo", this.record.getCodigo());

        //Fecha Innicio
        parameters.put("fechaInicio", sdf.format(this.record.getFechainicio()));

        //Fecha Innicio
        parameters.put("fechaFin", sdf.format(this.record.getFechafin()));

        //Nombre del centro de control
        parameters.put("nombreCentro", this.nombreCentroControl);

        //Fecha actual
        parameters.put("fechaActual", Calendar.getInstance().getTime());

        //Funcionario
        parameters.put("gradoNombreFuncionario", gradoFuncionario + this.jefeCentroControl);
        parameters.put("personcode", this.centroControl.getPersoncode());
        parameters.put("centroControl", "JEFE DEL " + this.nombreCentroControl);

        //Usuario
        parameters.put("usuario", this.usuario.getName());
        sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String fechaHora = sdf.format(Calendar.getInstance().getTime());
        parameters.put("fechaHora", fechaHora);

        String format = "pdf";

        try {
            this.reportController.execute(path, parameters, format, filename, this.getLoginController());
            this.reporteGenerado = true;
        } catch (Exception ex) {
            MessageHelper.setMessageError(ex);
        }
    }

    public void habilitarFirma() {

    }

    /**
     * Metodo para finalizar la tarea del flujo
     */
    public void completarTarea() {

        try {
            if (!btnFlujo) {
                MessageHelper.setMessageInfo("GUARDE LOS CAMBIOS");
            }
            Request request = callerhelper.getRequest();
            // limpiar request para finalizar la tarea.
            super.cleanRequest(request);
            request.modifiedData().put("cplanificacion", this.cplanificacion);
            request.modifiedData().put("TID", tid);
            request.modifiedData().put("BPMStatus", bpmDataStatus == null ? "A" : bpmDataStatus); // A,D,R
            request.modifiedData().put("BPMObs", bpmDataComment == null ? "OK" : bpmDataComment);

            Response resp = callerhelper.executeSave(request);

            if (resp.getResponseCode().compareTo(Response.RESPONSE_OK) == 0) {
                MessageHelper.setMessageInfo(resp);
                btnFlujo = false;
                RequestContext.getCurrentInstance().execute("Maia.refreshusertasks()");
            } else {
                MessageHelper.setMessageError(resp);
            }
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
        }
    }

    /**
     * Metodo para finalizar la tarea del flujo
     */
    public void completarTareaReporte() {

        try {
            if (!reporteGenerado) {
                MessageHelper.setMessageError("GENERE EL REPORTE");
                return;
            }
            Request request = callerhelper.getRequest();
            // limpiar request para finalizar la tarea.
            super.cleanRequest(request);
            request.modifiedData().put("cplanificacion", this.cplanificacion);
            request.modifiedData().put("TID", tid);
            request.modifiedData().put("BPMStatus", bpmDataStatus == null ? "A" : bpmDataStatus); // A,D,R
            request.modifiedData().put("BPMObs", bpmDataComment == null ? "OK" : bpmDataComment);

            Response resp = callerhelper.executeSave(request);

            if (resp.getResponseCode().compareTo(Response.RESPONSE_OK) == 0) {
                MessageHelper.setMessageInfo(resp);
                reporteGenerado = false;
                RequestContext.getCurrentInstance().execute("Maia.refreshusertasks()");
            } else {
                MessageHelper.setMessageError(resp);
            }
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
        }
    }

    @Override
    public void postCommit(Response response) throws Exception {
        super.postCommitGeneric(response, beanalias);
    }

    /**
     *
     * @param codigoSolicitud
     * @return
     */
    public static List<TarmPlanificacionInspeccion> findPorAnno(String centro, String year) {
        try {
            AprobacionPlanInspeccionController cc = new AprobacionPlanInspeccionController();
            cc.initConsulta();
            cc.recperpage = 300;
            if (year != null) {
                cc.addFilter("anno", year);
            }
            cc.addFilter("ccentrocontrol", centro);
            cc.querydatabase();
            if ((cc.lrecord != null) && !cc.lrecord.isEmpty()) {
                return cc.lrecord;
//    	    if (cc.record != null) {
//    	    	return cc.lrecord;
            }
            return null;
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
            return null;
        }
    }

    public PlanificacionTramiteController getPlanificacionTramiteController() {
        return planificacionTramiteController;
    }

    public void setPlanificacionTramiteController(
            PlanificacionTramiteController planificacionTramiteController) {
        this.planificacionTramiteController = planificacionTramiteController;
    }

    public TarmCentroControl getCentroControl() {
        return centroControl;
    }

    public void setCentroControl(TarmCentroControl centroControl) {
        this.centroControl = centroControl;
    }

    public String getNombreCentroControl() {
        return nombreCentroControl;
    }

    public void setNombreCentroControl(String nombreCentroControl) {
        this.nombreCentroControl = nombreCentroControl;
    }

    public Long getCplanificacion() {
        return cplanificacion;
    }

    public void setCplanificacion(Long cplanificacion) {
        this.cplanificacion = cplanificacion;
    }

    public Boolean getReporteGenerado() {
        return reporteGenerado;
    }

    public void setReporteGenerado(Boolean reporteGenerado) {
        this.reporteGenerado = reporteGenerado;
    }

    public String getOpcion() {
        return opcion;
    }

    public void setOpcion(String opcion) {
        this.opcion = opcion;
    }

    public String getObservaciones() {
        return observaciones;
    }

    public void setObservaciones(String observaciones) {
        this.observaciones = observaciones;
    }

    public Boolean getReporteHabilitado() {
        return reporteHabilitado;
    }

    public void setReporteHabilitado(Boolean reporteHabilitado) {
        this.reporteHabilitado = reporteHabilitado;
    }

    public String getGradoFuncionario() {
        return gradoFuncionario;
    }

    public void setGradoFuncionario(String gradoFuncionario) {
        this.gradoFuncionario = gradoFuncionario;
    }

    public TcustPersonDetail getUsuario() {
        return usuario;
    }

    public void setUsuario(TcustPersonDetail usuario) {
        this.usuario = usuario;
    }

    public ReportController getReportController() {
        return reportController;
    }

    public void setReportController(ReportController reportController) {
        this.reportController = reportController;
    }

    public AlfrescoController getAlfrescoController() {
        return alfrescoController;
    }

    public void setAlfrescoController(AlfrescoController alfrescoController) {
        this.alfrescoController = alfrescoController;
    }

    public String getXpathflujo() {
        return xpathflujo;
    }

    public void setXpathflujo(String xpathflujo) {
        this.xpathflujo = xpathflujo;
    }

    public List<TarmPlanificacionTramite> getListaInsepcion() {
        return listainsepcion;
    }

    public void setListaInsepcion(List<TarmPlanificacionTramite> listainsepcion) {
        this.listainsepcion = listainsepcion;
    }
}
