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

import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
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.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.armas.parametros.TiposArmasExplosivosController;
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.controller.pgeneral.gene.ParametersController;
import com.fp.frontend.helper.MessageHelper;
import com.fp.frontend.utility.MsgControlArmas;
import com.fp.frontend.utility.MsgGeneral;
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.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.param.TarmTipoArmaExplosivo;
import com.fp.persistence.parmas.soli.TarmArmas;
import com.fp.persistence.parmas.soli.TarmSolicitud;
import com.fp.persistence.parmas.soli.TarmSolicitudArmas;
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.TgeneCanton;
import com.fp.persistence.pgeneral.gene.TgeneCatalogDetail;
import com.fp.persistence.pgeneral.gene.TgeneCity;
import com.fp.persistence.pgeneral.gene.TgeneParameters;
import com.fp.persistence.pgeneral.gene.TgeneParroquia;
import com.fp.persistence.pgeneral.gene.TgeneProvince;
import com.fp.persistence.pgeneral.safe.TsafeUserDetail;

@SuppressWarnings("serial")
@ManagedBean
@ViewScoped
public class AutorizacionDevolucionController extends AbstractController<TarmSolicitudTramite> {

    TarmSolicitudTramite solicitudTramite;
    Boolean actualizada = false;
    /**
     *
     */
    private static final long serialVersionUID = 1L;

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

    @ManagedProperty(value = "#{armasController}")
    private ArmasController armasController;

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

    TgeneProvince provincia;
    TgeneCanton canton;
    TgeneCity ciudad;
    TgeneParroquia parroquia;
    String direccion;

    TcustPersonDetail detallesPersona;
    TcustPersonDetail usuario;
    TarmCentroControl centroControl;
    TcustPersonAddress direccionPersona;
    String nombreInstitucion;
    private Boolean btnEnviar;
    /**
     * Atributo que se recupera del flujo
     */
    private String csolicitud;

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

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

    /**
     * Metodo para recuperar la variable del flujo
     */
    public void startQuery() {
        try {
            this.pasteBpmScreenParameters();
            csolicitud = super.getMfilters().get("csolicitud");//1
            super.getMfilters().clear();
        } catch (Exception e) {
            MessageHelper.setMessageError(e);
        }
    }

    private void init() {
        try {
            recperpage = 15; // Cambiar al # reg a mirar.
            lrecord = new ArrayList<>();
            beanalias = "AUTORIZACIONDEVOLUCIONCONTROLLER";
            solicitudTramite = TarmSolicitudTramiteController.findPorCSolicitud(csolicitud);
            btnEnviar = Boolean.FALSE;
        } catch (Exception e) {
            MessageHelper.setMessageError(e);
        }
    }

    @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);

            Filter fCSolicitud = new Filter("pk.csolicitud", csolicitud);
            dto.addFiltro(fCSolicitud);

            //Aplicandole filtros a las armas
            tarmSolicitudArmasController.setCsolicitud(csolicitud);
            tarmSolicitudArmasController.setPorDevolucion("Y");
            tarmSolicitudArmasController.getMfilters().clear();
            tarmSolicitudArmasController.query();

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

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

            Response resp = this.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.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 la direccion del cliente
                    String tipoDireccion = "";
                    if (solicitud != null) {
                        detallesPersona = PersonDetailController.find(String.valueOf(solicitud.getPersoncode().toString()));

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

                        if (solicitud != null) {
                            //personAddressController.findPersonaPorDireccionTipoCatalogo(String.valueOf(solicitud.getPersoncode()), tipoDireccion);
                            String codigoMail = codigoParameter("CODIGO.MAIL");//3
                            this.direccionPersona = personAddressController.findByPersonCode(solicitud.getPersoncode().toString(), codigoMail);

                            provincia = personAddressController.getLprovinces() == null || personAddressController.getLprovinces().isEmpty() ? null : personAddressController.getLprovinces().get(0);
                            canton = personAddressController.getLcantones() == null || personAddressController.getLcantones().isEmpty() ? null : personAddressController.getLcantones().get(0);
                            ciudad = personAddressController.getLcities() == null || personAddressController.getLcities().isEmpty() ? null : personAddressController.getLcities().get(0);
                            parroquia = personAddressController.getLparroquias() == null || personAddressController.getLparroquias().isEmpty() ? null : personAddressController.getLparroquias().get(0);
                            direccion = personAddressController.getRecord().getAddress();
                        }
                    }

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

                    //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);
        }
    }

    public String codigoParameter(String codigo) {
        TgeneParameters parameter = ParametersController.find(codigo, "1");
        return parameter.getTextvalue();
    }

    @Override
    public void save() {
        try {
            record.setEstadotramite("APB");
            update();

            //Modificando la direccion de las armas con del cliente y el estado del arma
            this.armasController.getLrecord().clear();
            this.armasController.setLrecord(this.tarmSolicitudArmasController.getlArmas());
            for (TarmArmas arma : this.armasController.getLrecord()) {
                if (provincia != null) {
                    arma.setProvincecode(provincia.getPk().getProvincecode());
                }

                if (canton != null) {
                    arma.setCantoncode(canton.getPk().getCantoncode());
                }

                if (ciudad != null) {
                    arma.setCitycode(ciudad.getPk().getCitycode());
                }

                if (parroquia != null) {
                    arma.setParroquiacode(parroquia.getPk().getParroquiacode());
                }

                arma.setDireccion(direccion);
                arma.setEstado("DEV");

                this.armasController.update(arma);
            }

            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);

            //Modificando el estado y direccion de las armas
            this.armasController.setLrecord(this.tarmSolicitudArmasController.getlArmas());

            DtoSave dtosaveArmas = this.armasController.getDtoSave(true);
            msave.put(this.armasController.getBeanalias(), dtosaveArmas);

            request.setSaveTables(msave);
            Response resp = callerhelper.executeSave(request);

            if (resp.getResponseCode().compareTo(Response.RESPONSE_OK) == 0) {
                this.postCommit(resp);
                MessageHelper.setMessageInfo(resp);
                this.actualizada = true;
                btnEnviar = Boolean.TRUE;
            } else {
                MessageHelper.setMessageError(resp);
            }

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

    /**
     * Metodo que envia un mail de notificaci&oacute;n
     */
    public void enviarNotificacion() {
        try {
            if (direccionPersona == null || direccionPersona.getAddress() == null) {
                MessageHelper.setMessageError(MsgControlArmas.getProperty("msg_error_notienedireccioncorreo"));
                return;
            }
            SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");

            String asunto = MsgControlArmas.getProperty("lbl_asuntoNotificarFecha");
            SimpleDateFormat format = new SimpleDateFormat(MsgGeneral.getProperty("dateformat"));
            String textoFecha = " " + format.format(new Date()) + " ";
            if (solicitudTramite.getFentregaarmas() != null) {
                textoFecha = sdf.format(solicitudTramite.getFentregaarmas());
            }

            String cuerpo = MessageFormat.format(MsgControlArmas.getProperty("cuerpo.mensaje.envio.correo"), detallesPersona.getName(),
                    solicitudTramite.getNumerotramite().toString(), textoFecha, usuario.getName(), this.nombreInstitucion);

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

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

        try {
            Request request = callerhelper.getRequest();
            // limpiar request para finalizar la tarea.
            super.cleanRequest(request);
            request.modifiedData().put("csolicitud", csolicitud);
            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);
                btnEnviar = Boolean.FALSE;
                RequestContext.getCurrentInstance().execute("Maia.refreshusertasks()");
            } else {
                MessageHelper.setMessageError(resp);
            }
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
        }
    }

    /**
     * Obtiene los detalles de las armas segun el catalogo
     *
     * @param catalogo
     * @param catalogoCode
     * @return
     */
    public String aspectoArmaCatalogo(String catalogo, String catalogoCode) {
        if (catalogo != null && catalogoCode != null && !catalogo.isEmpty() && !catalogoCode.isEmpty()) {
            return CatalogDetailController.findxCodigoCodcatalogo(catalogo, catalogoCode).getDescription();
        }
        return null;
    }

    /**
     * Devuelve una descripcion de catalogo segun un tipo de aspecto
     *
     * @param arma
     * @param tipoAspecto
     * @return
     */
    public String aspectoArmaExplosivoCatalogo(TarmArmas arma, String tipoAspecto) {
        String aspecto = "";

        try {
            TarmTipoArmaExplosivo explosivo = TiposArmasExplosivosController.findarma(arma.getCtipoarmaexplosivo());
            if (explosivo != null) {
                if (tipoAspecto.equalsIgnoreCase("clase") && explosivo.getClase() != null && !explosivo.getClase().isEmpty()
                        && explosivo.getClasecodigo() != null && !explosivo.getClasecodigo().isEmpty()) {
                    aspecto = CatalogDetailController.findxCodigoCodcatalogo(explosivo.getClase(), explosivo.getClasecodigo()).getDescription();

                } else if (tipoAspecto.equalsIgnoreCase("tipo") && explosivo.getTipoarmaexplosivo() != null && !explosivo.getTipoarmaexplosivo().isEmpty()
                        && explosivo.getTipoarmaexplosivocodigo() != null && !explosivo.getTipoarmaexplosivocodigo().isEmpty()) {
                    aspecto = CatalogDetailController.findxCodigoCodcatalogo(explosivo.getTipoarmaexplosivo(), explosivo.getTipoarmaexplosivocodigo()).getDescription();

                } else if (tipoAspecto.equalsIgnoreCase("calibre") && explosivo.getCalibre() != null && !explosivo.getCalibre().isEmpty()
                        && explosivo.getCalibrecodigo() != null && !explosivo.getCalibrecodigo().isEmpty()) {
                    aspecto = CatalogDetailController.findxCodigoCodcatalogo(explosivo.getCalibre(), explosivo.getCalibrecodigo()).getDescription();
                }
            }

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

        return aspecto;
    }

    public String aspectoExplosivoArma(TarmSolicitudArmas solicitudArma, String aspecto) {
        String descripcionAspecto = "";
        try {
            TarmArmas arma = ArmasController.findPorCodigo(solicitudArma.getPk().getCarma());

            if (arma != null) {
                return this.aspectoArmaExplosivoCatalogo(arma, aspecto);
            }

        } catch (Exception e) {
            MessageHelper.setMessageWarn(e.getMessage());
        }

        return descripcionAspecto;
    }

    public TarmSolicitudArmasController getTarmSolicitudArmasController() {
        return tarmSolicitudArmasController;
    }

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

    public Boolean getActualizada() {
        return actualizada;
    }

    public void setActualizada(Boolean actualizada) {
        this.actualizada = actualizada;
    }

    public TarmSolicitudTramite getSolicitudTramite() {
        return solicitudTramite;
    }

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

    public ArmasController getArmasController() {
        return armasController;
    }

    public void setArmasController(ArmasController armasController) {
        this.armasController = armasController;
    }

    public PersonAddressController getPersonAddressController() {
        return personAddressController;
    }

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

    public TgeneProvince getProvincia() {
        return provincia;
    }

    public void setProvincia(TgeneProvince provincia) {
        this.provincia = provincia;
    }

    public TgeneCanton getCanton() {
        return canton;
    }

    public void setCanton(TgeneCanton canton) {
        this.canton = canton;
    }

    public TgeneCity getCiudad() {
        return ciudad;
    }

    public void setCiudad(TgeneCity ciudad) {
        this.ciudad = ciudad;
    }

    public TgeneParroquia getParroquia() {
        return parroquia;
    }

    public void setParroquia(TgeneParroquia parroquia) {
        this.parroquia = parroquia;
    }

    public String getDireccion() {
        return direccion;
    }

    public void setDireccion(String direccion) {
        this.direccion = direccion;
    }

    public Boolean getBtnEnviar() {
        return btnEnviar;
    }

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

}
