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

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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.query.Filter;
import com.fp.dto.save.DtoSave;
import com.fp.frontend.controller.AbstractController;
import com.fp.frontend.controller.armas.parametros.CentroControlArmasController;
import com.fp.frontend.controller.pcustomer.PersonAddressController;
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.general.mail.EnvioMail;
import com.fp.general.mail.dto.EnvioCorreoDTO;
import com.fp.general.mail.exception.EnvioMailException;
import com.fp.general.mail.factory.EnvioMailFactory;
import com.fp.persistence.parmas.param.TarmCentroControl;
import com.fp.persistence.parmas.soli.TarmSolicitud;
import com.fp.persistence.parmas.soli.TarmSolicitudTramite;
import com.fp.persistence.pcustomer.gene.TcustPersonAddress;
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 RegistrarNovedadController extends AbstractController<TarmSolicitudTramite> {

    TarmSolicitudTramite solicitudTramite;

    @ManagedProperty(value = "#{tarmSolicitudArmasController}")
    private TarmSolicitudArmasController tarmSolicitudArmasController;

    @ManagedProperty(value = "#{personAddressController}")
    private PersonAddressController personAddressController;

    TcustPersonDetail detallesPersona;
    TcustPersonAddress direccionPersona;
    TcustPersonDetail usuario;
    TarmCentroControl centroControl;
    String nombreInstitucion;
    String gradoFuncionario = "";
    private Boolean btnEnviar;
    private String csolicitud;

    public RegistrarNovedadController() throws Exception {
        super(TarmSolicitudTramite.class);
        // TODO Auto-generated constructor stub
    }

    @PostConstruct
    private void postconstruct() {
        csolicitud = FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("CSOLICITUD").toString();//"175";
        // Inicializa autoconsulta
        super.startQuery();
        this.init();
    }

    /**
     * Incializa el controlador, cuando se esta utilizando una pagina que utliza
     * el controlador.
     */
    private void init() {
        try {
            recperpage = 10; // Cambiar al # reg a mirar.
            lrecord = new ArrayList<>();
            beanalias = "REGISTRARNOVEDADCONTROLLER";
            solicitudTramite = TarmSolicitudTramiteController.findPorCSolicitud(csolicitud);
            btnEnviar = Boolean.FALSE;
            querydatabase();
        } catch (Exception e) {
            MessageHelper.setMessageError(e);
        }
    }

    /**
     * Crea una instancia de TgeneTransactionProcess y marca el registro como
     * nuevo.
     *
     * @throws Exception
     */
    @Override
    public void create() throws Exception {
        super.create();
    }

    @Override
    public void query() throws Exception {
        // TODO Auto-generated method stub
        MessageHelper.setMessageError("msg_notQuery");
        super.query();
    }

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

            //Quemando el personcode de la persona
            Filter filtro = new Filter("pk.csolicitud", csolicitud);
            dto.addFiltro(filtro);

            //Obteniendo el tramite
            TarmSolicitudTramite solicitudTramite = TarmSolicitudTramiteController.findPorCSolicitud(csolicitud);

            tarmSolicitudArmasController.setCsolicitud(csolicitud);
            tarmSolicitudArmasController.setPorDevolucion("N");
            tarmSolicitudArmasController.query();

            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<TarmSolicitudTramite>();
                MessageHelper.setMessageError(resp);
            } else {
                lrecord = (List<TarmSolicitudTramite>) resp.get(beanalias);
                if (lrecord != null && !lrecord.isEmpty()) {

                    record = lrecord.get(0);

                    //Numero de tramite
                    if (solicitudTramite != null) {
                        this.record.put("ntramite", solicitudTramite.getNumerotramite());
                    }

                    //Obteniendo la solicitud
                    TarmSolicitud solicitud = ValidacionTramiteLibreTransitoController.findPorSolicitudSimple(this.record.getPk().getCsolicitud());

                    //Obteniendo los datos y la direccion de la persona
                    if (solicitud != null) {
                        detallesPersona = PersonDetailController.find(String.valueOf(solicitud.getPersoncode().toString()));

                        String tipoDireccion = "";

                        switch (detallesPersona.getIdentificationcatalog()) {
                            case "CED":
                                tipoDireccion = "1";
                                break;
                            case "RUC":
                                tipoDireccion = "2";
                                break;
                            default:
                                tipoDireccion = "";
                                break;
                        }

                        personAddressController.findPersonaPorDireccionTipoCatalogo(String.valueOf(detallesPersona.getPk().getPersoncode()), tipoDireccion);
                        direccionPersona = personAddressController.getRecord();

                    }

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

                    //Obteniendo el grado
                    TgeneCatalogDetail grado = CatalogDetailController.findxCodigoCodcatalogo(usuario.getMilitarygrade(), usuario.getMilitarygradecode());
                    if (grado != null) {
                        gradoFuncionario = grado.getDescription() + " - ";
                    }

                    //Obteniendo el centro de control
                    centroControl = CentroControlArmasController.findPorCodigo(solicitud.getCcentrocontrol());
                    if (centroControl != null && centroControl.getNombreinstitucion() != null && !centroControl.getNombreinstitucion().isEmpty()
                            && centroControl.getNombreinstitucioncodigo() != null && !centroControl.getNombreinstitucioncodigo().isEmpty()) {

                        TgeneCatalogDetail catalogoInstitucion = CatalogDetailController.findxCodigoCodcatalogo(centroControl.getNombreinstitucion(), centroControl.getNombreinstitucioncodigo());
                        this.nombreInstitucion = catalogoInstitucion.getDescription();
                    }

                }
                super.postQuery(lrecord);
            }

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

    @Override
    public void save() {
        try {
            update();

            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);
                btnEnviar = true;
                TgeneCatalogDetail tipoDireccion = null;
                if (direccionPersona.getAddresstypecatalog() != null && !direccionPersona.getAddresstypecatalog().isEmpty()
                        && direccionPersona.getAddresstypecatalogcode() != null && !direccionPersona.getAddresstypecatalogcode().isEmpty()) {
                    tipoDireccion = CatalogDetailController.findxCodigoCodcatalogo(direccionPersona.getAddresstypecatalog(), direccionPersona.getAddresstypecatalogcode());
                }

                if (tipoDireccion != null && tipoDireccion.getDescription().equalsIgnoreCase("Mail")) {
                    enviarNotificacion();
                }
            } else {
                MessageHelper.setMessageError(resp);
            }

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

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

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

        try {
            Request request = callerhelper.getRequest();
            // limpiar request para finalizar la tarea.
            super.cleanRequest(request);
            //completa la tarea del flujo
            //complete la tarea del flujo pasa a Autorizar la devolucion
            request.modifiedData().put("csolicitud", csolicitud);
            request.modifiedData().put("TID", FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("TID"));
            request.modifiedData().put("BPMStatus", bpmDataStatus == null ? "D" : bpmDataStatus); // A,D,R
            request.modifiedData().put("BPMObs", record.getObservacionnovedad() == null ? "OK" : record.getObservacionnovedad());

            Map<String, Object> datosmail = new HashMap<String, Object>();
            datosmail.put("razons", detallesPersona.getName());
            datosmail.put("sol", solicitudTramite.getNumerotramite());
            if (record.getObservacionnovedad() != null) {
                datosmail.put("observaciones", record.getObservacionnovedad());
            } else {
                datosmail.put("observaciones", "ok");
            }

            //grado funcionario de la persona logeada
            TsafeUserDetail userDetailObj = (TsafeUserDetail) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("TSAFEUSERDETAIL");
            TcustPersonDetail personDetailObj = PersonDetailController.find(userDetailObj.getPk().getPersoncode().toString());
            datosmail.put("grado", personDetailObj.getMilitarygrade());
            datosmail.put("funcionario", personDetailObj.getName());
            // Centro de control de armas
            datosmail.put("centrocontrol", centroControl.getModifiedData().get("desinstitucion"));
            request.modifiedData().put("datosmail", datosmail);

            Response resp = callerhelper.executeSave(request);

            if (resp.getResponseCode().compareTo(Response.RESPONSE_OK) == 0) {
                MessageHelper.setMessageInfo(resp);
                btnEnviar = Boolean.FALSE;
                FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("TID");
                FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("CSOLICITUD");
                RequestContext.getCurrentInstance().execute("Maia.refreshusertasks()");
            } else {
                MessageHelper.setMessageError(resp);
            }
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
        }
    }

    /**
     * Metodo que envia un mail de notificaci&oacute;n
     */
    public void enviarNotificacion() {
        try {
            String asunto = MsgControlArmas.getProperty("lbl_asuntoNotificarNovedad");
            String cuerpo = "";
            String cuerpo1 = MessageFormat.format(MsgControlArmas.getProperty("cuerpo.mensaje.envio.correo.novedad1"), detallesPersona.getName(),
                    solicitudTramite.getPk().getCtramite().toString());

            String cuerpo2 = "<br/><br/>";
            cuerpo2 = cuerpo2.concat("<table style='border: 1px solid gray;border-collapse: collapse;' >");

            cuerpo2 = cuerpo2.concat("<tr style='background-color: #d3d3d3'>");

            cuerpo2 = cuerpo2.concat("<td style='border: 1px solid #666666;font-weight: bold;padding: 2px 2px 2px 2px;text-align: center;'>");
            cuerpo2 = cuerpo2.concat("No.");
            cuerpo2 = cuerpo2.concat("</td>");

            cuerpo2 = cuerpo2.concat("<td style='border: 1px solid #666666;font-weight: bold;padding: 2px 2px 2px 2px;text-align: center;'>");
            cuerpo2 = cuerpo2.concat("Clase");
            cuerpo2 = cuerpo2.concat("</td>");

            cuerpo2 = cuerpo2.concat("<td style='border: 1px solid #666666;font-weight: bold;padding: 2px 2px 2px 2px;text-align: center;'>");
            cuerpo2 = cuerpo2.concat("Tipo");
            cuerpo2 = cuerpo2.concat("</td>");

            cuerpo2 = cuerpo2.concat("<td style='border: 1px solid #666666;font-weight: bold;padding: 2px 2px 2px 2px;text-align: center;'>");
            cuerpo2 = cuerpo2.concat("Marca");
            cuerpo2 = cuerpo2.concat("</td>");

            cuerpo2 = cuerpo2.concat("<td style='border: 1px solid #666666;font-weight: bold;padding: 2px 2px 2px 2px;text-align: center;'>");
            cuerpo2 = cuerpo2.concat("Modelo");
            cuerpo2 = cuerpo2.concat("</td>");

            cuerpo2 = cuerpo2.concat("<td style='border: 1px solid #666666;font-weight: bold;padding: 2px 2px 2px 2px;text-align: center;'>");
            cuerpo2 = cuerpo2.concat("Calibre");
            cuerpo2 = cuerpo2.concat("</td>");

            cuerpo2 = cuerpo2.concat("<td style='border: 1px solid #666666;font-weight: bold;padding: 2px 2px 2px 2px;text-align: center;'>");
            cuerpo2 = cuerpo2.concat("Serie");
            cuerpo2 = cuerpo2.concat("</td>");

            cuerpo2 = cuerpo2.concat("<td style='border: 1px solid #666666;font-weight: bold;padding: 2px 2px 2px 2px;text-align: center;'>");
            cuerpo2 = cuerpo2.concat("Estado");
            cuerpo2 = cuerpo2.concat("</td>");

            cuerpo2 = cuerpo2.concat("</tr>");

            for (int i = 0; i < tarmSolicitudArmasController.getLrecord().size(); i++) {
                cuerpo2 = cuerpo2.concat("<tr>");

                //No
                cuerpo2 = cuerpo2.concat("<td style='border: 1px solid #666666;padding: 2px 2px 2px 2px;text-align: center;'>");
                Integer no = i + 1;
                cuerpo2 = cuerpo2.concat(no.toString());
                cuerpo2 = cuerpo2.concat("</td>");

                //Clase
                cuerpo2 = cuerpo2.concat("<td style='border: 1px solid #666666;padding: 2px 2px 2px 2px;'>");
                if (tarmSolicitudArmasController.getLrecord().get(i).getModifiedData().get("clase") != null) {
                    cuerpo2 = cuerpo2.concat(tarmSolicitudArmasController.getLrecord().get(i).getModifiedData().get("clase").toString());
                } else {
                    cuerpo2 = cuerpo2.concat("");
                }
                cuerpo2 = cuerpo2.concat("</td>");

                //Tipo
                cuerpo2 = cuerpo2.concat("<td style='border: 1px solid #666666;padding: 2px 2px 2px 2px;'>");
                if (tarmSolicitudArmasController.getLrecord().get(i).getModifiedData().get("tipo") != null) {
                    cuerpo2 = cuerpo2.concat(tarmSolicitudArmasController.getLrecord().get(i).getModifiedData().get("tipo").toString());
                } else {
                    cuerpo2 = cuerpo2.concat("");
                }
                cuerpo2 = cuerpo2.concat("</td>");

                //Marca
                cuerpo2 = cuerpo2.concat("<td style='border: 1px solid #666666;padding: 2px 2px 2px 2px;'>");
                if (tarmSolicitudArmasController.getLrecord().get(i).getModifiedData().get("marca") != null) {
                    cuerpo2 = cuerpo2.concat(tarmSolicitudArmasController.getLrecord().get(i).getModifiedData().get("marca").toString());
                } else {
                    cuerpo2 = cuerpo2.concat("");
                }
                cuerpo2 = cuerpo2.concat("</td>");

                //Modelo
                cuerpo2 = cuerpo2.concat("<td style='border: 1px solid #666666;padding: 2px 2px 2px 2px;'>");
                if (tarmSolicitudArmasController.getLrecord().get(i).getModifiedData().get("modelo") != null) {
                    cuerpo2 = cuerpo2.concat(tarmSolicitudArmasController.getLrecord().get(i).getModifiedData().get("modelo").toString());
                } else {
                    cuerpo2 = cuerpo2.concat("");
                }
                cuerpo2 = cuerpo2.concat("</td>");

                //Calibre
                cuerpo2 = cuerpo2.concat("<td style='border: 1px solid #666666;padding: 2px 2px 2px 2px;'>");
                if (tarmSolicitudArmasController.getLrecord().get(i).getModifiedData().get("calibre") != null) {
                    cuerpo2 = cuerpo2.concat(tarmSolicitudArmasController.getLrecord().get(i).getModifiedData().get("calibre").toString());
                } else {
                    cuerpo2 = cuerpo2.concat("");
                }
                cuerpo2 = cuerpo2.concat("</td>");

                //Serie
                cuerpo2 = cuerpo2.concat("<td style='border: 1px solid #666666;padding: 2px 2px 2px 2px;'>");
                if (tarmSolicitudArmasController.getLrecord().get(i).getModifiedData().get("seriecanon") != null) {
                    cuerpo2 = cuerpo2.concat(tarmSolicitudArmasController.getLrecord().get(i).getModifiedData().get("seriecanon").toString());
                } else {
                    cuerpo2 = cuerpo2.concat(" ");
                }
                cuerpo2 = cuerpo2.concat("</td>");

                //Estado
                cuerpo2 = cuerpo2.concat("<td style='border: 1px solid #666666;padding: 2px 2px 2px 2px;'>");
                if (tarmSolicitudArmasController.getLrecord().get(i).getModifiedData().get("estado") != null) {
                    cuerpo2 = cuerpo2.concat(tarmSolicitudArmasController.getLrecord().get(i).getModifiedData().get("estado").toString());
                } else {
                    cuerpo2 = cuerpo2.concat(" ");
                }
                cuerpo2 = cuerpo2.concat("</td>");

                cuerpo2 = cuerpo2.concat("</tr>");

            }

            cuerpo2 = cuerpo2.concat("</table><br/>");
            cuerpo2 = cuerpo2.concat("Observaciones:<br/>");

            String cuerpo3 = MessageFormat.format(MsgControlArmas.getProperty("cuerpo.mensaje.envio.correo.novedad2"), this.record.getObservacionnovedad(),
                    gradoFuncionario + usuario.getName(), this.nombreInstitucion);

            cuerpo = cuerpo1 + cuerpo2 + cuerpo3;

            EnvioCorreoDTO envioCorreo = new EnvioCorreoDTO();
            envioCorreo.setCorreoDesde(MsgControlArmas.getProperty("correoDesde"));
            envioCorreo.setCorreoPara(new String[]{direccionPersona.getAddress()});
            //envioCorreo.setCorreoPara(new String[]{"ogarcia@bupartech.com"});
            envioCorreo.setAsunto(asunto);
            envioCorreo.setMensajeHTML(cuerpo);
            EnvioMail envioMail = EnvioMailFactory.getInstancia();
            envioMail.envioMail(envioCorreo);
        } catch (EnvioMailException e) {
            MessageHelper.setMessageError(new Throwable("Se produjo un error al enviar el correo"));
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
        }
    }

    public TarmSolicitudTramite getSolicitudTramite() {
        return solicitudTramite;
    }

    public void setSolicitudTramite(TarmSolicitudTramite solicitudTramite) {
        this.solicitudTramite = solicitudTramite;
    }

    public TarmSolicitudArmasController getTarmSolicitudArmasController() {
        return tarmSolicitudArmasController;
    }

    public void setTarmSolicitudArmasController(
            TarmSolicitudArmasController tarmSolicitudArmasController) {
        this.tarmSolicitudArmasController = tarmSolicitudArmasController;
    }

    public PersonAddressController getPersonAddressController() {
        return personAddressController;
    }

    public void setPersonAddressController(
            PersonAddressController personAddressController) {
        this.personAddressController = personAddressController;
    }

    public TcustPersonDetail getDetallesPersona() {
        return detallesPersona;
    }

    public void setDetallesPersona(TcustPersonDetail detallesPersona) {
        this.detallesPersona = detallesPersona;
    }

    public TcustPersonAddress getDireccionPersona() {
        return direccionPersona;
    }

    public void setDireccionPersona(TcustPersonAddress direccionPersona) {
        this.direccionPersona = direccionPersona;
    }

    public TcustPersonDetail getUsuario() {
        return usuario;
    }

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

    public TarmCentroControl getCentroControl() {
        return centroControl;
    }

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

    public String getNombreInstitucion() {
        return nombreInstitucion;
    }

    public void setNombreInstitucion(String nombreInstitucion) {
        this.nombreInstitucion = nombreInstitucion;
    }

    public Boolean getBtnEnviar() {
        return btnEnviar;
    }

    public void setBtnEnviar(Boolean btnEnviar) {
        this.btnEnviar = btnEnviar;
    }

}
