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

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
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.ViewScoped;

import org.primefaces.event.SelectEvent;

import com.fp.dto.Request;
import com.fp.dto.Response;
import com.fp.dto.query.DtoQuery;
import com.fp.dto.query.SubQuery;
import com.fp.dto.save.DtoSave;
import com.fp.frontend.controller.AbstractController;
import com.fp.frontend.controller.armas.lov.UnidadTipoLovController;
import com.fp.frontend.controller.pcustomer.lov.PersonLovController;
import com.fp.frontend.controller.pgeneral.gene.CatalogDetailController;
import com.fp.frontend.helper.MessageHelper;
import com.fp.persistence.parmas.param.TarmComercianteCupo;
import com.fp.persistence.parmas.param.TarmUnidadTipo;
import com.fp.persistence.pcustomer.gene.TcustPersonDetail;
import com.fp.persistence.pgeneral.gene.TgeneCatalogDetail;

/**
 * Clase controladora del bean TarmUnidTipo.
 *
 * @author C.P.
 * @version 2
 */
@SuppressWarnings("serial")
@ManagedBean
@ViewScoped
public class ComercianteCupoController extends AbstractController<TarmComercianteCupo> {

    private List<TgeneCatalogDetail> ltiposRegistro;

    private String descripcionClase;
    private String descripcionTipoArma;

    private String nombreComerciante;
    private String numeroDocumento;

    //variables para el popup
    private String nombreComercianteDialog;
    private String numeroDocumentoDialog;
    private String descripcionClaseDialog;
    private String descripcionTipoArmaDialog;
    private String descripcionUnidadMedida;
    private BigDecimal cupoAsignado;
    private Boolean regEditar;

    public ComercianteCupoController() throws Exception {
        super(TarmComercianteCupo.class);
    }

    @PostConstruct
    private void postconstruct() {
        this.init();
        // Inicializa autoconsulta
        super.startQuery();
    }

    /**
     * Incializa el controlador, cuando se esta utilizando una pagina que utliza
     * el controlador.
     */
    private void init() {
        try {
            this.recperpage = 15; // Cambiar al # reg a mirar.
            this.lrecord = new ArrayList<>();
            this.beanalias = "COMCUOP";
        } catch (Exception e) {
            MessageHelper.setMessageError(e);
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void querydatabase() {
        try {
            DtoQuery dto = super.getDtoQuery(true);
//			dto.setOrderby("t.description"); nombre identification desclasearma destipoarma desunidad destiporegistro

            SubQuery snombre = new SubQuery("TcustPersonDetail", "name", "nombre", "i.pk.personcode = t.personcodigo and  i.pk.dateto=(select max(dt.pk.dateto) from TcustPersonDetail dt where dt.pk.personcode=t.personcodigo)");
            SubQuery snumerodocumento = new SubQuery("TcustPersonDetail", "identification", "identification", "i.pk.personcode = t.personcodigo and  i.pk.dateto=(select max(dt.pk.dateto) from TcustPersonDetail dt where dt.pk.personcode=t.personcodigo)");
            SubQuery sclasearma = new SubQuery("TgeneCatalogDetail", "description", "desclasearma", "i.pk.catalog = t.clase and  i.pk.catalogcode=t.clasecodigo");
            SubQuery stipoarma = new SubQuery("TgeneCatalogDetail", "description", "destipoarma", "i.pk.catalog = t.tipoarmaexplosivo and  i.pk.catalogcode=t.tipoarmaexplosivocodigo");
            SubQuery sunidad = new SubQuery("TgeneCatalogDetail", "description", "desunidad", "i.pk.catalog = t.unidadmedidapeso and  i.pk.catalogcode=t.unidadmedidapesocodigo");
            SubQuery stiporegistro = new SubQuery("TgeneCatalogDetail", "description", "destiporegistro", "i.pk.catalog = t.tiporegistro and  i.pk.catalogcode=t.tiporegistrocodigo");
            dto.addSubQuery(snombre);
            dto.addSubQuery(snumerodocumento);
            dto.addSubQuery(stipoarma);
            dto.addSubQuery(sclasearma);
            dto.addSubQuery(sunidad);
            dto.addSubQuery(stiporegistro);

            HashMap<String, DtoQuery> mtables = new HashMap<String, DtoQuery>();
            mtables.put(this.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) {
                this.lrecord = new ArrayList<TarmComercianteCupo>();
                MessageHelper.setMessageError(resp);
            } else {
                this.lrecord = (List<TarmComercianteCupo>) resp
                        .get(this.beanalias);
                super.postQuery(this.lrecord);
            }

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

    @Override
    public void save() {
        try {
            DtoSave dtosave = super.getDtoSave();
            if (!dtosave.pendingProcess()) {
                return;
            }
            dtosave.setReturnpk(true); // Para que el core devuelva el pk de los
            // registros nuevos.
            HashMap<String, DtoSave> msave = new HashMap<String, DtoSave>();

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

            request.setSaveTables(msave);
            Response resp = this.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);
        }
    }

    /**
     * Crea una instancia del registro como nuevo.
     *
     * @throws Exception
     */
    @Override
    public void create() throws Exception {
        cupoAsignado = new BigDecimal(0);
        regEditar = Boolean.FALSE;
        nombreComercianteDialog = null;
        numeroDocumentoDialog = null;
        descripcionClaseDialog = null;
        descripcionTipoArmaDialog = null;
        descripcionUnidadMedida = null;
        super.create();
        this.record.setFecharegistro(new Timestamp(new Date().getTime()));
        if (ltiposRegistro == null || ltiposRegistro.size() == 0) {
            ltiposRegistro = CatalogDetailController.find("TIPOREGISTRO");
        }
    }

    @Override
    public void update() throws Exception {
        if (record.getPersoncodigo() != null) {
            if (record.getClase() != null && record.getClase().trim().length() > 0) {
                this.record.setTiporegistrocodigo("TIPOREGISTRO");
                if (record.getCupounidad().compareTo(new BigDecimal(0)) > 0 && record.getCupounidad().compareTo(cupoAsignado) >= 0) {
                    if (!regEditar) {
                        catalogos(ltiposRegistro, record.getTiporegistro(), "destiporegistro");
                    }
                    super.update();
                } else if (!regEditar) {
                    MessageHelper.setMessageError("EL CUPO DEDE SER MAYOR A CERO");
                } else {
                    MessageHelper.setMessageError("EL CUPO DEDE SER MAYOR AL ASIGNADO INICIALMENTE");
                }
            } else {
                MessageHelper.setMessageError("SELECCIONE LA CLASE");
            }
        } else {
            MessageHelper.setMessageError("SELECCIONE EL No. DE DOCUMENTO");
        }

    }

    public void updateSimple(TarmComercianteCupo bean) throws Exception {
        record = bean;
        super.update();
    }

    /**
     * Metodo para cargar las variables para editar
     */
    public void loadEdit() {
        regEditar = Boolean.TRUE;
        cupoAsignado = record.getCupounidad();
        nombreComercianteDialog = record.getModifiedData().get("nombre").toString();
        numeroDocumentoDialog = record.getModifiedData().get("identification").toString();
        descripcionClaseDialog = record.getModifiedData().get("desclasearma").toString();
        descripcionTipoArmaDialog = record.getModifiedData().get("destipoarma").toString();
        descripcionUnidadMedida = record.getModifiedData().get("desunidad").toString();
        //    destiporegistro
    }

    /**
     * Metodo para recorreer los combos y setear las descripciones de lo q se
     * escoge para la vista
     *
     * @param list
     * @param codigo
     * @param pk
     */
    public void catalogos(List<TgeneCatalogDetail> list, String codigo, String pk) {
        for (TgeneCatalogDetail item : list) {
            if (codigo.equals(item.getPk().getCatalog())) {
                record.modifiedData.put(pk, item.getDescription());
                break;
            }
        }
    }

    /**
     * Entrega una lista de objetos TgeneCatalogDetail
     *
     * @param catalogcode C&oacute de cat&aacute;logo
     * @return lrecord Lista de objetos TgeneCatalogDetail
     */
    public static List<TarmComercianteCupo> find(String code) {
        try {
            ComercianteCupoController cc = new ComercianteCupoController();
            cc.init();
            cc.recperpage = 300;
            cc.addFilter("pk", code);
            cc.querydatabase();
            if ((cc.lrecord != null) && !cc.lrecord.isEmpty()) {
                return cc.lrecord;
            }
            return null;
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
            return null;
        }
    }

    /**
     * Devuelve la lista de cupos de una persona
     *
     * @param catalogcode
     */
    public static List<TarmComercianteCupo> findByPersonCode(String personCode, String classCode, String tipoArmaExplosivoCodigo, String unidad) {
        try {
            ComercianteCupoController cc = new ComercianteCupoController();
            cc.init();
            cc.recperpage = 300;
            cc.addFilter("personcodigo", personCode);
            cc.addFilter("clase", classCode);
            cc.addFilter("tipoarmaexplosivo", tipoArmaExplosivoCodigo);
            cc.addFilter("unidadmedidapeso", unidad);
            cc.querydatabase();
            if ((cc.lrecord != null) && !cc.lrecord.isEmpty()) {
                return cc.lrecord;
            }
            return null;
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
            return null;
        }
    }

    //lov de persona
    /**
     * M&eacute;todo para abrir el lov de personas
     */
    public void openPersonLov() {
        Map<String, List<String>> params = new HashMap<>();
        PersonLovController.openLov(params);
    }

    /**
     * Maneja la respuesta del Lov de Personas
     *
     * @param event
     * @throws Exception
     */
    public void onReturnPersonLov(SelectEvent event) throws Exception {
        TcustPersonDetail personaDetailSelecionada = (TcustPersonDetail) event.getObject();
        nombreComerciante = personaDetailSelecionada.getName();
        numeroDocumento = personaDetailSelecionada.getIdentification();
        super.getMfilters().put("personcodigo", personaDetailSelecionada.getPk().getPersoncode().toString());
    }

    /**
     * Maneja la respuesta del Lov de Personas que se ejecuta desde el dialog de
     * comerciante cupo
     *
     * @param event
     * @throws Exception
     */
    public void onReturnPersonLovDialog(SelectEvent event) throws Exception {
        TcustPersonDetail personaDetailSelecionada = (TcustPersonDetail) event.getObject();
        nombreComercianteDialog = personaDetailSelecionada.getName();
        numeroDocumentoDialog = personaDetailSelecionada.getIdentification();
        record.setPersoncodigo(personaDetailSelecionada.getPk().getPersoncode());
        record.getModifiedData().put("nombre", personaDetailSelecionada.getName());
        record.getModifiedData().put("identification", personaDetailSelecionada.getIdentification());

    }

    //lov de UnidadTipo
    /**
     * M&eacute;todo para abrir el lov de UnidadTipo
     */
    public void openUnidadTipoLov() {
        Map<String, List<String>> params = new HashMap<>();
        UnidadTipoLovController.openLov(params);
    }

    /**
     * Return del LOV de UnidadTipo
     *
     * @param event
     * @throws Exception
     */
    public void onReturnUnidadTipoLov(SelectEvent event) throws Exception {
        TarmUnidadTipo t = (TarmUnidadTipo) event.getObject();
        super.getMfilters().put("clase", t.getPk().getClase());
        super.getMfilters().put("clasecodigo", t.getPk().getClasecode());
        super.getMfilters().put("tipoarmaexplosivo", t.getPk().getTipoarmaexplosivo());
        super.getMfilters().put("tipoarmaexplosivocodigo", t.getPk().getTipoarmaexplosivocodigo());
        descripcionClase = t.getModifiedData().get("desclasearma").toString();
        descripcionTipoArma = t.getModifiedData().get("destipoarma").toString();
    }

    /**
     * Return del LOV de UnidadTipo ejecutado desde el Dialog
     *
     * @param event
     * @throws Exception
     */
    public void onReturnUnidadTipoLovDialog(SelectEvent event) throws Exception {
        TarmUnidadTipo t = (TarmUnidadTipo) event.getObject();
        record.setClase(t.getPk().getClase());
        record.setClasecodigo(t.getPk().getClasecode());
        record.setTipoarmaexplosivo(t.getPk().getTipoarmaexplosivo());
        record.setTipoarmaexplosivocodigo(t.getPk().getTipoarmaexplosivocodigo());
        record.setUnidadmedidapeso(t.getPk().getUnidadmedidapeso());
        record.setUnidadmedidapesocodigo(t.getPk().getUnidadmedidapesocodigo());
        descripcionClaseDialog = t.getModifiedData().get("desclasearma").toString();
        descripcionTipoArmaDialog = t.getModifiedData().get("destipoarma").toString();
        descripcionUnidadMedida = t.getModifiedData().get("desunidad").toString();
        record.getModifiedData().put("desclasearma", t.getModifiedData().get("desclasearma").toString());
        record.getModifiedData().put("destipoarma", t.getModifiedData().get("destipoarma").toString());
        record.getModifiedData().put("desunidad", t.getModifiedData().get("desunidad").toString());
    }

    public String getDescripcionClase() {
        return descripcionClase;
    }

    public void setDescripcionClase(String descripcionClase) {
        this.descripcionClase = descripcionClase;
    }

    public String getDescripcionTipoArma() {
        return descripcionTipoArma;
    }

    public void setDescripcionTipoArma(String descripcionTipoArma) {
        this.descripcionTipoArma = descripcionTipoArma;
    }

    public String getNombreComerciante() {
        return nombreComerciante;
    }

    public void setNombreComerciante(String nombreComerciante) {
        this.nombreComerciante = nombreComerciante;
    }

    public String getNumeroDocumento() {
        return numeroDocumento;
    }

    public void setNumeroDocumento(String numeroDocumento) {
        this.numeroDocumento = numeroDocumento;
    }

    public String getNombreComercianteDialog() {
        return nombreComercianteDialog;
    }

    public void setNombreComercianteDialog(String nombreComercianteDialog) {
        this.nombreComercianteDialog = nombreComercianteDialog;
    }

    public String getNumeroDocumentoDialog() {
        return numeroDocumentoDialog;
    }

    public void setNumeroDocumentoDialog(String numeroDocumentoDialog) {
        this.numeroDocumentoDialog = numeroDocumentoDialog;
    }

    public String getDescripcionClaseDialog() {
        return descripcionClaseDialog;
    }

    public void setDescripcionClaseDialog(String descripcionClaseDialog) {
        this.descripcionClaseDialog = descripcionClaseDialog;
    }

    public String getDescripcionTipoArmaDialog() {
        return descripcionTipoArmaDialog;
    }

    public void setDescripcionTipoArmaDialog(String descripcionTipoArmaDialog) {
        this.descripcionTipoArmaDialog = descripcionTipoArmaDialog;
    }

    public String getDescripcionUnidadMedida() {
        return descripcionUnidadMedida;
    }

    public void setDescripcionUnidadMedida(String descripcionUnidadMedida) {
        this.descripcionUnidadMedida = descripcionUnidadMedida;
    }

    public List<TgeneCatalogDetail> getLtiposRegistro() {
        return ltiposRegistro;
    }

    public void setLtiposRegistro(List<TgeneCatalogDetail> ltiposRegistro) {
        this.ltiposRegistro = ltiposRegistro;
    }

    public Boolean getRegEditar() {
        return regEditar;
    }

    public void setRegEditar(Boolean regEditar) {
        this.regEditar = regEditar;
    }

}
