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

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.ViewScoped;

import org.primefaces.context.RequestContext;
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.pgeneral.gene.CantonController;
import com.fp.frontend.controller.pgeneral.gene.CatalogDetailController;
import com.fp.frontend.controller.pgeneral.gene.ParroquiaController;
import com.fp.frontend.controller.pgeneral.gene.ProvinceController;
import com.fp.frontend.enums.EnumLovOption;
import com.fp.frontend.helper.MessageHelper;
import com.fp.persistence.parmas.param.TarmCentroControl;
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.TgeneParroquia;
import com.fp.persistence.pgeneral.gene.TgeneProvince;

@SuppressWarnings("serial")
@ManagedBean
@ViewScoped
public class CentroControlArmasController extends AbstractController<TarmCentroControl> {

    /**
     * Atributo para la lista de objetos TgeneCatalogDetail
     */
    private List<TgeneCatalogDetail> linstitucion;
    /**
     * Atributo para la lista de objetos TgeneCatalogDetail
     */
    private List<TgeneCatalogDetail> lnombreInstitucion;
    /**
     * Atributo para la lista de objetos TgeneProvince
     */
    private List<TgeneProvince> lprovinces;
    /**
     * Atributo para la lista de objetos TgeneProvince
     */
    private List<TgeneCanton> lcantones;

    /**
     * Atributo para la lista de objetos TgeneParroquia
     */
    private List<TgeneParroquia> lparroquias;
    /**
     * Atributo para la lista de objetos TgeneCatalogDetail (catalogo de grados
     * asignados a los militares)
     */
    private List<TgeneCatalogDetail> lgrados;
    /**
     * Variable para activar o desactivar los campos segun la opcion
     * seleccionada
     */
    private String editarReg;
    /**
     * Variable de tipo TcustPersonDetail para setear cuando seleccione del lov
     */
    private TcustPersonDetail personaDetailSelecionada;

    public CentroControlArmasController() throws Exception {
        super(TarmCentroControl.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 = "CENTCONTARMAS";
            //CARGA DE CATALOGOS
            linstitucion = CatalogDetailController.find("INSTITUCION");
        } catch (Exception e) {
            MessageHelper.setMessageError(e);
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void querydatabase() {
        try {

            Request request = this.callerhelper.getRequest();
            DtoQuery dto = super.getDtoQuery(true);
            SubQuery stipoInstitucion = new SubQuery("TgeneCatalogDetail", "description", "desinstitucion", "i.pk.catalog = t.institucion and  i.pk.catalogcode=t.instituciontipo");
            SubQuery stipoInstitucionLegalcode = new SubQuery("TgeneCatalogDetail", "legalcode", "legalcode", "i.pk.catalog = t.institucion and  i.pk.catalogcode=t.instituciontipo");
            SubQuery snombreinstitucion = new SubQuery("TgeneCatalogDetail", "description", "desnombreinstitucion", "i.pk.catalog = t.nombreinstitucion and  i.pk.catalogcode=t.nombreinstitucioncodigo");
            SubQuery sprovincia = new SubQuery("TgeneProvince", "description", "desprovincia", "i.pk.countrycode = t.countrycode and i.pk.provincecode= t.provincecode");
            SubQuery scanton = new SubQuery("TgeneCanton", "description", "descanton", "i.pk.countrycode = t.countrycode and  i.pk.provincecode=t.provincecode and i.pk.cantoncode=t.cantoncode");
            SubQuery sparroquia = new SubQuery("TgeneParroquia", "description", "desparroquia", "i.pk.countrycode = t.countrycode and  i.pk.provincecode=t.provincecode and i.pk.cantoncode=t.cantoncode and i.pk.parroquiacode=t.parroquiacode");
            SubQuery spersona = new SubQuery("TcustPersonDetail", "name", "nombre", "i.pk.personcode=t.personcode  and i.pk.dateto=to_date('2999-12-31', 'YYYY-MM-DD')");
            SubQuery sgrado = new SubQuery("TgeneCatalogDetail", "description", "desgrado", "i.pk.catalog = t.grado and  i.pk.catalogcode=t.gradocodigo");
            dto.addSubQuery(stipoInstitucion);
            dto.addSubQuery(stipoInstitucionLegalcode);
            dto.addSubQuery(snombreinstitucion);
            dto.addSubQuery(sprovincia);
            dto.addSubQuery(scanton);
            dto.addSubQuery(sparroquia);
            dto.addSubQuery(spersona);
            dto.addSubQuery(sgrado);
            dto.setOrderby("t.institucion"); // En en string van todos los campos de orden ("t.pk,  t.nombre, t.cpais").
            HashMap<String, DtoQuery> mtables = new HashMap<String, DtoQuery>();
            mtables.put(this.beanalias, dto); // permite adicionar mas de una tabla.
            request.setQueryTables(mtables);
            Response resp = this.callerhelper.executeQuery(request);
            if (resp.getResponseCode().compareTo(Response.RESPONSE_OK) != 0) {
                this.lrecord = new ArrayList<TarmCentroControl>();
                MessageHelper.setMessageError(resp);
            } else {
                this.lrecord = (List<TarmCentroControl>) resp.get(this.beanalias);
                if (this.lrecord != null && !this.lrecord.isEmpty()) {
                    this.record = lrecord.get(0);
                }
                super.postQuery(this.lrecord);
            }

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

    @Override
    public void save() {
        try {
            Request request = this.callerhelper.getRequest();
            DtoSave dtosave = super.getDtoSave();
            dtosave.setReturnpk(true);
            if (!dtosave.pendingProcess()) {
                return;
            }
            HashMap<String, DtoSave> msave = new HashMap<String, DtoSave>();
            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);
        }
    }

    /**
     * M&eacute;todo para el evento change del combo institucion
     */
    public void executeInstitucion() {
        if ((getMfilters().get("institucion") != null) && (getMfilters().get("institucion").compareTo("") != 0)) {
            lnombreInstitucion = CatalogDetailController.find("NOMBREINSTITUCION", getMfilters().get("institucion"));
        }
    }

    /**
     * Metodo q se ejecuta cuando pulsamos el boton crear
     */
    @Override
    public void create() throws Exception {
        if (super.getMfilters().get("institucion") == null || super.getMfilters().get("institucion").equals("%")) {
            MessageHelper.setMessageError("INSTITUCI\u00D3N REQUERIDA");
            return;
        }
        editarReg = null;
        super.create();
        //se carga el nombre de la institucion seleccionada
        catalogos(linstitucion, getMfilters().get("institucion"), "desinstitucion");
        record.setInstituciontipo("INSTITUCION");
        record.setInstitucion(super.getMfilters().get("institucion"));
        record.setNombreinstitucioncodigo("NOMBREINSTITUCION");
        record.setGradocodigo("MILITARYGRADE");
        //se consulta las provincias del ecuador
        record.setCountrycode("EC");
        if (lprovinces == null || lprovinces.size() == 0) {
            lprovinces = ProvinceController.find(record.getCountrycode());
        }
        //consulta los grados
        if (lgrados == null || lgrados.size() == 0) {
            lgrados = CatalogDetailController.find("MILITARYGRADE");
        }
        personaDetailSelecionada = new TcustPersonDetail();
    }

    @Override
    public void update() throws Exception {
        catalogos(lnombreInstitucion, record.getNombreinstitucion(), "desnombreinstitucion");//lista, campo a validar, pk del mdafile
        catalogos(linstitucion, record.getInstitucion(), "desinstitucion");
        catalogos(lgrados, record.getGrado(), "desgrado");
        nombreProvincia();
        nombreCanton();
        nombreParroquia();
        super.update();
    }

    /**
     * M&eacute;todo para cargar datos en el editar
     */
    public void loadEdit() {
        personaDetailSelecionada = new TcustPersonDetail();
        personaDetailSelecionada.setName(record.getModifiedData().get("nombre").toString());
        //consulta los nombres de las intituciones
        lnombreInstitucion = CatalogDetailController.find("NOMBREINSTITUCION", record.getInstitucion());
        if (lprovinces == null || lprovinces.size() == 0) {
            lprovinces = ProvinceController.find(record.getCountrycode());
        }
        lcantones = CantonController.find(record.getCountrycode(), record.getProvincecode());
        lparroquias = ParroquiaController.find(record.getCountrycode(), record.getProvincecode(), record.getCantoncode());
        //consulta los grados
        if (lgrados == null || lgrados.size() == 0) {
            lgrados = CatalogDetailController.find("MILITARYGRADE");
        }
        editarReg = "SI";
    }

    /**
     * M&eacute;todo para el evento change del combo provincias
     */
    public void executeProvince() {
        if ((record.getCountrycode() != null) && (record.getCountrycode().compareTo("") != 0)) {
            lcantones = CantonController.find(record.getCountrycode(), record.getProvincecode());
            lparroquias = new ArrayList<>();
        }
    }

    /**
     * M&eacute;todo para el evento change del combo cantones
     */
    public void executeCanton() {
        if ((record.getCountrycode() != null) && (record.getCountrycode().compareTo("") != 0)) {
            lparroquias = ParroquiaController.find(record.getCountrycode(), record.getProvincecode(), record.getCantoncode());
        }
    }

    /**
     * Metodos para recorreer los combos y setear las descripciones de lo q se
     * escoge
     */
    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;
            }
        }
    }

    /**
     * Metodo para obtener la descripcion de la provincia
     */
    public void nombreProvincia() {
        for (TgeneProvince provincia : lprovinces) {
            if (provincia.getPk().getProvincecode().equals(record.getProvincecode())) {
                record.getModifiedData().put("desprovincia", provincia.getDescription());

            }
        }
    }

    /**
     * Metodo para obtener la descripcion del canton
     */
    public void nombreCanton() {
        for (TgeneCanton canton : lcantones) {
            if (canton.getPk().getProvincecode().equals(record.getProvincecode()) && canton.getPk().getCantoncode().equals(record.getCantoncode())) {
                record.getModifiedData().put("descanton", canton.getDescription());

            }
        }
    }

    /**
     * Metodo para obtener la descripcion de la provincia
     */
    public void nombreParroquia() {
        for (TgeneParroquia parroquia : lparroquias) {
            if (parroquia.getPk().getProvincecode().equals(record.getProvincecode()) && parroquia.getPk().getCantoncode().equals(record.getCantoncode())
                    && parroquia.getPk().getParroquiacode().equals(record.getParroquiacode())) {
                record.getModifiedData().put("desparroquia", parroquia.getDescription());

            }
        }
    }

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

    public static void openLov(Map<String, List<String>> params) {
        Map<String, Object> options = new HashMap<String, Object>();
        // hint: ver EnumLovOption para las opciones del modal
        options.put(EnumLovOption.MODAL.getLabel(), true);
        options.put(EnumLovOption.HEIGHT.getLabel(), 450);
        options.put(EnumLovOption.WIDTH.getLabel(), 700);
        options.put(EnumLovOption.RESIZABLE.getLabel(), true);
        // lovpersona es el nombre de la pagina
        RequestContext.getCurrentInstance().openDialog("/pages/customer/lov/personLov.xhtml", options, params);
    }

    /**
     * Maneja la respuesta del Lov de Personas
     *
     * @param event
     * @throws Exception
     */
    public void onReturnPersonLov(SelectEvent event) throws Exception {
        personaDetailSelecionada = (TcustPersonDetail) event.getObject();
        this.record.put("dateto", personaDetailSelecionada.getPk().getDateto());
        this.record.put("personcode", personaDetailSelecionada.getPk().getPersoncode());
        this.record.put("nombre", personaDetailSelecionada.getName());
        //seteo de los codigos de persona
        record.setPersoncode(personaDetailSelecionada.getPk().getPersoncode());
        record.setDateto(personaDetailSelecionada.getPk().getDateto());
    }

    /**
     * Metodo para buscar todos los centros de control
     *
     * @param ccentrocontrol
     * @return
     */
    public static List<TarmCentroControl> findAll() {
        try {
            CentroControlArmasController cc = new CentroControlArmasController();
            cc.init();
            cc.recperpage = 10000;
            cc.querydatabase();
            if ((cc.lrecord != null) && !cc.lrecord.isEmpty()) {
                return cc.lrecord;
            }
            return null;
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
            return null;
        }
    }

    /**
     * Metodo para buscar por codigo de centro de control
     *
     * @param ccentrocontrol
     * @return
     */
    public static List<TarmCentroControl> find(String ccentrocontrol) {
        try {
            CentroControlArmasController cc = new CentroControlArmasController();
            cc.init();
            cc.recperpage = 15;
            cc.addFilter("pk", ccentrocontrol);
            cc.querydatabase();
            if ((cc.lrecord != null) && !cc.lrecord.isEmpty()) {
                return cc.lrecord;
            }
            return null;
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
            return null;
        }
    }

    /**
     * Metodo para validar el campo de jefe de centro
     *
     * @param tc
     */
    public void validarJefe(TarmCentroControl tc) {
        System.out.println("nombre...selec..." + tc.getPersoncode());
        if (tc.getPersoncode() != null && tc.getPersoncode() > 0) {
            record.getModifiedData().put("nombre", personaDetailSelecionada.getName());
            return;
        }
        record.getModifiedData().put("nombre", null);

    }

    /**
     * Metodo que devuelve un centro de control de armas por su codigo
     *
     * @param codigoSolicitud
     * @return
     */
    public static TarmCentroControl findPorCodigo(String codigo) {
        try {
            CentroControlArmasController cc = new CentroControlArmasController();
            cc.init();
            cc.recperpage = 300;
            cc.addFilter("pk", codigo);
            cc.querydatabase();
            if (cc.record != null) {
                return cc.record;
            }
            return null;
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
            return null;
        }
    }

    /**
     * Metodo que devuelve un centro de control de armas por su codigo de
     * Catalogo
     *
     * @param codigoSolicitud
     * @return
     */
    public static TarmCentroControl findPorCentroControl(String codigo) {
        try {
            CentroControlArmasController cc = new CentroControlArmasController();
            cc.init();
            cc.recperpage = 300;
            cc.addFilter("nombreinstitucion", codigo);
            cc.querydatabase();
            if (cc.record != null) {
                return cc.record;
            }
            return null;
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
            return null;
        }
    }

    /**
     * Entrega una lista de objetos TgeneCatalogDetail
     *
     * @param catalogcode C&oacute de cat&aacute;logo
     * @return lrecord Lista de objetos TgeneCatalogDetail
     */
    public static TarmCentroControl findxpersoncode(String personcode) {
        try {
            CentroControlArmasController cc = new CentroControlArmasController();
            cc.init();
            cc.recperpage = 300;
            cc.addFilter("personcode", personcode);
            cc.querydatabase();
            if ((cc.lrecord != null) && !cc.lrecord.isEmpty()) {
                return cc.lrecord.get(0);
            }
            return null;
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
            return null;
        }
    }

    /**
     * Metodo para buscar los centros de control asociados a un organismo o
     * unidad
     *
     * @param codigoSolicitud
     * @return
     */
    public static List<TarmCentroControl> findxOrganismoUnidad(String organismo, String unidad) {
        try {
            CentroControlArmasController cc = new CentroControlArmasController();
            cc.init();
            cc.recperpage = 300;
            cc.addFilter("institucion", organismo);
            cc.addFilter("nombreinstitucion", unidad);
            cc.querydatabase();
            if (cc.lrecord != null) {
                return cc.lrecord;
            }
            return null;
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
            return null;
        }
    }

    /**
     * Metodo para buscar el centros de control asociado a un organismo y unidad
     *
     * @param codigoSolicitud
     * @return
     */
    public static TarmCentroControl findxCcontrolUnidad(String ccontrol, String unidad) {
        try {
            CentroControlArmasController cc = new CentroControlArmasController();
            cc.init();
            cc.recperpage = 300;
            cc.addFilter("institucion", ccontrol);
            cc.addFilter("nombreinstitucion", unidad);
            cc.querydatabase();
            if (cc.lrecord != null && !cc.lrecord.isEmpty()) {
                return cc.lrecord.get(0);
            }
            return null;
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
            return null;
        }
    }

    /**
     * Metodo para buscar los centros de control asociados a un organismo o
     * unidad
     *
     * @param codigoSolicitud
     * @return
     */
    public static List<TarmCentroControl> findxInstitucion(String organismo) {
        try {
            CentroControlArmasController cc = new CentroControlArmasController();
            cc.init();
            cc.recperpage = 300;
            cc.addFilter("institucion", organismo);
            cc.querydatabase();
            if (cc.lrecord != null) {
                return cc.lrecord;
            }
            return null;
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
            return null;
        }
    }

    /**
     * Metodo para buscar por codigo de centro de control
     *
     * @param ccentrocontrol
     * @return
     */
    public static List<TarmCentroControl> findEstadoInst(String estado, String institucion) {
        try {
            CentroControlArmasController cc = new CentroControlArmasController();
            cc.init();
            cc.recperpage = 300;
            cc.addFilter("estado", estado);
            cc.addFilter("institucion", institucion);
            cc.querydatabase();
            if ((cc.lrecord != null) && !cc.lrecord.isEmpty()) {
                TarmCentroControl departamento = new TarmCentroControl();
                for (TarmCentroControl centro : cc.lrecord) {
                    if ("DPCA".equals(centro.getNombreinstitucion())) {
                        departamento = centro;
                    }
                }
                cc.lrecord.remove(departamento);
                return cc.lrecord;
            }
            return null;
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
            return null;
        }
    }

    /**
     * Metodo para buscar por codigo de centro de control
     *
     * @param ccentrocontrol
     * @return
     */
    public static List<TarmCentroControl> findEstado(String estado) {
        try {
            CentroControlArmasController cc = new CentroControlArmasController();
            cc.init();
            cc.recperpage = 300;
            cc.addFilter("estado", estado);
            cc.querydatabase();
            if ((cc.lrecord != null) && !cc.lrecord.isEmpty()) {
                TarmCentroControl departamento = new TarmCentroControl();
                for (TarmCentroControl centro : cc.lrecord) {
                    if ("DPCA".equals(centro.getNombreinstitucion())) {
                        departamento = centro;
                    }
                }
                cc.lrecord.remove(departamento);
                return cc.lrecord;
            }
            return null;
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
            return null;
        }
    }

    public List<TgeneCatalogDetail> getLinstitucion() {
        return linstitucion;
    }

    public void setLinstitucion(List<TgeneCatalogDetail> linstitucion) {
        this.linstitucion = linstitucion;
    }

    public List<TgeneCatalogDetail> getLnombreInstitucion() {
        return lnombreInstitucion;
    }

    public void setLnombreInstitucion(List<TgeneCatalogDetail> lnombreInstitucion) {
        this.lnombreInstitucion = lnombreInstitucion;
    }

    public List<TgeneProvince> getLprovinces() {
        return lprovinces;
    }

    public void setLprovinces(List<TgeneProvince> lprovinces) {
        this.lprovinces = lprovinces;
    }

    public List<TgeneCanton> getLcantones() {
        return lcantones;
    }

    public void setLcantones(List<TgeneCanton> lcantones) {
        this.lcantones = lcantones;
    }

    public List<TgeneParroquia> getLparroquias() {
        return lparroquias;
    }

    public void setLparroquias(List<TgeneParroquia> lparroquias) {
        this.lparroquias = lparroquias;
    }

    public List<TgeneCatalogDetail> getLgrados() {
        return lgrados;
    }

    public void setLgrados(List<TgeneCatalogDetail> lgrados) {
        this.lgrados = lgrados;
    }

    public String getEditarReg() {
        return editarReg;
    }

    public void setEditarReg(String editarReg) {
        this.editarReg = editarReg;
    }

    /**
     * Metodo para actualizar un bean en el record desde otros controladores
     */
    public void update(TarmCentroControl bean) throws Exception {
        record = bean;
        super.update();
    }

}
