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

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
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 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.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.persistence.parmas.ins.TarmPlanificacionInspeccion;
import com.fp.persistence.parmas.ins.TarmPlanificacionTramite;
import com.fp.persistence.parmas.param.TarmCentroControl;
import com.fp.persistence.parmas.param.TarmCentroControlJur;
import com.fp.persistence.parmas.soli.TarmDocumentoHabilitante;
import com.fp.persistence.pcustomer.gene.TcustPersonDetail;

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

    private TarmCentroControl centroControl;

    private String nombreCentroControl;

    private TarmCentroControlJur jurisdiccionCentroControl;

    private Boolean planificacionSalvada = false;

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

    private List<String> listaMeses = new ArrayList<String>();

    private List<Long> listaAnnos = new ArrayList<Long>();

    List<TarmPlanificacionInspeccion> planificaciones;

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

    @ManagedProperty(value = "#{documentoHabilitanteController}")
    private DocumentoHabilitanteController documentoHabilitanteController;

    @ManagedProperty(value = "#{personAddressController}")
    private PersonAddressController personAddressController;
    /**
     * Atibuto para la habilitacion del boton de completar la tarea del flujo
     */
    private Boolean btnFlujo;

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

    @PostConstruct
    private void postconstruct() {
        try {
            this.startQuery();
            this.init();
            super.query();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            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; // Cambiar al # reg a mirar.
            lrecord = new ArrayList<>();
            record = new TarmPlanificacionInspeccion();
            beanalias = "MODIFICARPLANIFICACIONCONTROLLER";
            btnFlujo = Boolean.FALSE;
            this.planificacionTramiteController = new PlanificacionTramiteController();
            this.planificacionTramiteController.setLrecord(new ArrayList<TarmPlanificacionTramite>());

            //Quemando el codigo de planificacion
            //this.cplanificacion=99L;
            //Obteniendo la planificacion
            if (this.cplanificacion != null) {
                this.record = PlanificacionInspeccionController.findPorCodigo(this.cplanificacion);

                if (this.record != null) {
                    // Obteniendo el centro de control
                    this.centroControl = CentroControlArmasController.findPorCodigo(this.record.getCcentrocontrol());
                    this.nombreCentroControl = CatalogDetailController.findxCodigoCodcatalogo(centroControl.getNombreinstitucion(),
                            centroControl.getNombreinstitucioncodigo()).getDescription();

                    //Obteniendo los tramites
                    this.planificacionTramiteController.setCplanificacion(this.record.getPk());
                    this.planificacionTramiteController.setRecperpage(4000);
                    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());
                        }
                    });
                }
            }
        } catch (Exception e) {
            MessageHelper.setMessageError(e);
        }
    }

    @Override
    public void query() throws Exception {
        // TODO Auto-generated method stub
        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);
            dto.setOrderby("anno desc");

            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.getModifiedData().put("INSPECCIONES", this.planificacionTramiteController.getLrecord());

            Response resp = callerhelper.executeSave(request);

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

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

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

    /**
     * Metodo que carga los meses disponibles atendiendo a la fecha de
     * expiracion del documento
     *
     * @param tramite
     */
    public void cargarMeses(TarmPlanificacionTramite inspeccion) {
        this.listaMeses.clear();
        Calendar calendario = Calendar.getInstance();
        Integer intmesnumero = calendario.get(Calendar.MONTH);
        this.planificacionTramiteController.getRecord().setMesnumero(Long.parseLong(intmesnumero.toString()));
        switch (calendario.get(Calendar.MONTH)) {
            case 0:
                listaMeses.add("Enero");
                listaMeses.add("Febrero");
                listaMeses.add("Marzo");
                listaMeses.add("Abril");
                listaMeses.add("Mayo");
                listaMeses.add("Junio");
                listaMeses.add("Julio");
                listaMeses.add("Agosto");
                listaMeses.add("Septiembre");
                listaMeses.add("Octubre");
                listaMeses.add("Noviembre");
                listaMeses.add("Diciembre");
                break;
            case 1:
                listaMeses.add("Febrero");
                listaMeses.add("Marzo");
                listaMeses.add("Abril");
                listaMeses.add("Mayo");
                listaMeses.add("Junio");
                listaMeses.add("Julio");
                listaMeses.add("Agosto");
                listaMeses.add("Septiembre");
                listaMeses.add("Octubre");
                listaMeses.add("Noviembre");
                listaMeses.add("Diciembre");
                break;
            case 2:
                listaMeses.add("Marzo");
                listaMeses.add("Abril");
                listaMeses.add("Mayo");
                listaMeses.add("Junio");
                listaMeses.add("Julio");
                listaMeses.add("Agosto");
                listaMeses.add("Septiembre");
                listaMeses.add("Octubre");
                listaMeses.add("Noviembre");
                listaMeses.add("Diciembre");
                break;
            case 3:
                listaMeses.add("Abril");
                listaMeses.add("Mayo");
                listaMeses.add("Junio");
                listaMeses.add("Julio");
                listaMeses.add("Agosto");
                listaMeses.add("Septiembre");
                listaMeses.add("Octubre");
                listaMeses.add("Noviembre");
                listaMeses.add("Diciembre");
                break;
            case 4:
                listaMeses.add("Mayo");
                listaMeses.add("Junio");
                listaMeses.add("Julio");
                listaMeses.add("Agosto");
                listaMeses.add("Septiembre");
                listaMeses.add("Octubre");
                listaMeses.add("Noviembre");
                listaMeses.add("Diciembre");
                break;
            case 5:
                listaMeses.add("Junio");
                listaMeses.add("Julio");
                listaMeses.add("Agosto");
                listaMeses.add("Septiembre");
                listaMeses.add("Octubre");
                listaMeses.add("Noviembre");
                listaMeses.add("Diciembre");
                break;
            case 6:
                listaMeses.add("Julio");
                listaMeses.add("Agosto");
                listaMeses.add("Septiembre");
                listaMeses.add("Octubre");
                listaMeses.add("Noviembre");
                listaMeses.add("Diciembre");
                break;
            case 7:
                listaMeses.add("Agosto");
                listaMeses.add("Septiembre");
                listaMeses.add("Octubre");
                listaMeses.add("Noviembre");
                listaMeses.add("Diciembre");
                break;
            case 8:
                listaMeses.add("Septiembre");
                listaMeses.add("Octubre");
                listaMeses.add("Noviembre");
                listaMeses.add("Diciembre");
                break;
            case 9:
                listaMeses.add("Octubre");
                listaMeses.add("Noviembre");
                listaMeses.add("Diciembre");
                break;
            case 10:
                listaMeses.add("Noviembre");
                listaMeses.add("Diciembre");
                break;
            case 11:
                inspeccion.setMes("Diciembre");
                break;
        }
    }

    /**
     * Metodo que ordena las inspecciones por mes y por nombre Ordenamiento
     * simple de burbujas
     */
    public void ordenarPorMesNombre() {
        try {
            // Ordenando por mes
            for (int i = 0; i < this.planificacionTramiteController.getLrecord().size() - 1; i++) {
                for (int j = i + 1; j < this.planificacionTramiteController.getLrecord().size(); j++) {
                    // Verificando que la ispeccion en j tenga un mes anterior
                    // a la inspeccion en i
                    if (this.planificacionTramiteController.getLrecord().get(j).getMesnumero() < this.planificacionTramiteController.getLrecord()
                            .get(i).getMesnumero()) {
                        TarmPlanificacionTramite temp = this.planificacionTramiteController.getLrecord().get(j);
                        this.planificacionTramiteController.getLrecord().set(j, this.planificacionTramiteController.getLrecord().get(i));
                        this.planificacionTramiteController.getLrecord().set(i, temp);
                    }
                }
            }

            // Ordenando por Nombre
            for (int i = 0; i < this.planificacionTramiteController.getLrecord().size() - 1; i++) {
                for (int j = i + 1; j < this.planificacionTramiteController.getLrecord().size(); j++) {

                    // Obteniendo el documento en i
                    TarmDocumentoHabilitante documentoi = DocumentoHabilitanteController.findPorCodigo(this.planificacionTramiteController
                            .getLrecord().get(i).getCdocumento().toString());

                    // Obteniendo el documento en j
                    TarmDocumentoHabilitante documentoj = DocumentoHabilitanteController.findPorCodigo(this.planificacionTramiteController
                            .getLrecord().get(j).getCdocumento().toString());

                    // Obteniendo la persona en i
                    TcustPersonDetail personai = PersonDetailController.find(documentoi.getPersoncode().toString());

                    // Obteniendo la persona en j
                    TcustPersonDetail personaj = PersonDetailController.find(documentoj.getPersoncode().toString());

                    // Verificando que la ispeccion en j tenga un nombre menor
                    // a la inspeccion en i si la inspeccion es del mismo mes
                    if (this.planificacionTramiteController.getLrecord().get(i).getMesnumero() == this.planificacionTramiteController.getLrecord()
                            .get(j).getMesnumero()
                            && personaj.getName().toLowerCase().compareToIgnoreCase(personai.getName().toLowerCase()) < 0) {
                        TarmPlanificacionTramite temp = this.planificacionTramiteController.getLrecord().get(j);
                        this.planificacionTramiteController.getLrecord().set(j, this.planificacionTramiteController.getLrecord().get(i));
                        this.planificacionTramiteController.getLrecord().set(i, temp);
                    }
                }
            }

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

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

    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 DocumentoHabilitanteController getDocumentoHabilitanteController() {
        return documentoHabilitanteController;
    }

    public void setDocumentoHabilitanteController(DocumentoHabilitanteController documentoHabilitanteController) {
        this.documentoHabilitanteController = documentoHabilitanteController;
    }

    public Boolean getPlanificacionSalvada() {
        return planificacionSalvada;
    }

    public void setPlanificacionSalvada(Boolean planificacionSalvada) {
        this.planificacionSalvada = planificacionSalvada;
    }

    public List<String> getListaMeses() {
        return listaMeses;
    }

    public void setListaMeses(List<String> listaMeses) {
        this.listaMeses = listaMeses;
    }

    public List<Long> getListaAnnos() {
        return listaAnnos;
    }

    public void setListaAnnos(List<Long> listaAnnos) {
        this.listaAnnos = listaAnnos;
    }

    public TarmCentroControlJur getJurisdiccionCentroControl() {
        return jurisdiccionCentroControl;
    }

    public void setJurisdiccionCentroControl(TarmCentroControlJur jurisdiccionCentroControl) {
        this.jurisdiccionCentroControl = jurisdiccionCentroControl;
    }

    public List<TarmPlanificacionInspeccion> getPlanificaciones() {
        return planificaciones;
    }

    public void setPlanificaciones(List<TarmPlanificacionInspeccion> planificaciones) {
        this.planificaciones = planificaciones;
    }

    public PersonAddressController getPersonAddressController() {
        return personAddressController;
    }

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

    public Long getCplanificacion() {
        return cplanificacion;
    }

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

    public Boolean getBtnFlujo() {
        return btnFlujo;
    }

    public void setBtnFlujo(Boolean btnFlujo) {
        this.btnFlujo = btnFlujo;
    }

}
