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

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
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.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

import org.primefaces.event.SelectEvent;

import com.fp.dto.AbstractDataTransport;
import com.fp.dto.Request;
import com.fp.dto.Response;
import com.fp.dto.save.DtoSave;
import com.fp.frontend.controller.AbstractController;
import com.fp.frontend.controller.armas.funcionalidad.MovimientoController;
import com.fp.frontend.controller.armas.funcionalidad.RegistroArmController;
import com.fp.frontend.controller.armas.parametros.ArmaController;
import com.fp.frontend.controller.armas.parametros.GuardiasController;
import com.fp.frontend.controller.armas.parametros.PreguntasParaEvaluacionesController;
import com.fp.frontend.controller.armas.solicitud.ArmasController;
import com.fp.frontend.controller.pcustomer.PersonDetailController;
import com.fp.frontend.controller.pcustomer.lov.PersonLovController;
import com.fp.frontend.controller.pgeneral.date.TgeneNotAccountingDayController;
import com.fp.frontend.controller.pgeneral.gene.CatalogDetailController;
import com.fp.frontend.controller.pgeneral.gene.CountryController;
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.ValidateIdentification;
import com.fp.frontend.webservices.snap.cedula.ClienteCedula;
import com.fp.frontend.webservices.snap.ruc.ClienteRUC;
import com.fp.persistence.parmas.soli.TarmGuardias;
import com.fp.persistence.pcustomer.gene.TcustPersonDetail;
import com.fp.persistence.pgeneral.date.TgeneNotAccountingDay;
import com.fp.persistence.pgeneral.gene.TgeneCatalogDetail;
import com.fp.persistence.pgeneral.safe.TsafeUserDetail;

import ec.gob.registrocivil.consultacedula.Cedula;
import ec.gov.sri.wsconsultacontribuyente.Contribuyente;

/**
 * @author Andres Cevallos Clase la cual valida que un usuario pueda rendir una evaluacion. Almacena la evaluacion en la Base de Datos
 */
@ManagedBean
@ViewScoped
public class TestConocimientosController extends AbstractController<AbstractDataTransport> {

    /**
     * Persona a ser evaluada
     */
    private TcustPersonDetail evaluado;

    /**
     * Controlador inyectado EvaluacionController
     */
    @ManagedProperty(value = "#{evaluacionController}")
    private EvaluacionController evaluacionController;
    private TarmGuardias guardia;
    /**
     * Controlador inyectado DetallePreguntasController
     */
    @ManagedProperty(value = "#{detallePreguntasController}")
    private DetallePreguntasController detallePreguntas;

    private TcustPersonDetail evaluadoSNAP;

    /**
     * Controlador Fecha
     */
    private Date fecha;

    /**
     * Booleano que activa la opcion de guardar
     */
    private Boolean guardar;
    /**
     * Tipo de persona referenciada en el catalogo
     */
    TgeneCatalogDetail lTipoPersona;
    /**
     * numero de intentos
     */
    Integer numeroIntentos;
    /**
     * intento actual
     */
    Long intento;
    /**
     * Referencia en el catalogo del tipo de evaluacion
     */
    private List<TgeneCatalogDetail> ltipoevaluacion;
    /**
     * Lista de las preguntas y respuestas de una evaluacion
     */
    private List<Evaluacion> levaluacion;
    private String tipoevaluacion;

    private boolean bloquear = Boolean.FALSE;

    private TcustPersonDetail compania;

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

    private static final long serialVersionUID = 1L;

    @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.lrecord = new ArrayList<>();
            this.beanalias = "TCONOCIMIENTO";
            setLtipoevaluacion(CatalogDetailController.find("TIPOEVALUACION"));
            fecha = new Date();
            tipoevaluacion = "CONOCIMIENTO";
            numeroIntentos = ParametersController.find("INTENTOS", "1").getNumbervalue().intValue();
            guardar = false;

            // CARGAR INFORMACION DEL USUARIO LOGUEADO DEL SNAP
            TsafeUserDetail tsafeUserDetail = (TsafeUserDetail) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("TSAFEUSERDETAIL");

            evaluado = PersonLovController.find(tsafeUserDetail.getPk().getPersoncode().toString());
            evaluacionController.setTipoTest("CONOCIMIENTO");
            evaluacionController.queryByTipoEvaluacion(tsafeUserDetail.getPk().getPersoncode().toString(), tipoevaluacion);

            guardia = GuardiasController.findxcguardia(evaluado.getPk().getPersoncode().toString());
            lTipoPersona = CatalogDetailController.findxCodigoCodcatalogo(evaluado.getPersontypecatalog(), evaluado.getPersontypecatalogcode());

//				super.create();
//				this.record.setPersoncode(evaluado.getPk().getPersoncode());
//				this.record.getModifiedData().put("nombre", evaluado.getName());
//				this.record.getModifiedData().put("identificacion", evaluado.getIdentification());			
//				this.record.getModifiedData().put("tipopersona", lTipoPersona.getDescription());
            if (evaluado.getIdentification() == null || evaluado.getIdentification() == null) {
                MessageHelper.setMessageError(MsgControlArmas.getProperty("mg_error_seleccioneeltipodedocumentooingreselacedula"));
                return;
            }

            if (evaluado.getIdentificationcatalog().equals("CED")) {
                // valido validez CEDULA
                if (!ValidateIdentification.cedula(evaluado.getIdentification())) {
                    MessageHelper.setMessageError(MsgControlArmas.getProperty("msg_error_nodocumentoinvalido"));
                    return;
                }
//                evaluadoSNAP = buscarPersonaSnap(evaluado.getIdentification(), evaluado.getIdentificationcatalog());
                //TODO: evaluar casos, salto de validacion por error servicio SNAP                
                evaluadoSNAP = PersonDetailController.findxidentification(evaluado.getIdentification(), evaluado.getIdentificationcatalog());
                if (evaluadoSNAP == null) {
                    evaluadoSNAP = PersonDetailController.buscarLocal(evaluado.getIdentification());
                }

            } else if (evaluado.getIdentificationcatalog().equals("RUC")) {
                // valido validez RUC
                if (!ValidateIdentification.ruc(evaluado.getIdentification())) {
                    MessageHelper.setMessageError(MsgControlArmas.getProperty("msg_error_nodocumentoinvalido"));
                    return;
                }
//                evaluadoSNAP = buscarPersonaSnap(evaluado.getIdentification(), evaluado.getIdentificationcatalog());
//TODO: evaluar casos, salto de validacion por error servicio SNAP                
                evaluadoSNAP = PersonDetailController.findxidentification(evaluado.getIdentification(), evaluado.getIdentificationcatalog());
                if (evaluadoSNAP == null) {
                    evaluadoSNAP = PersonDetailController.buscarLocal(evaluado.getIdentification());
                }
            } else {
                // PASAPORTE
                evaluadoSNAP = new TcustPersonDetail();
                evaluadoSNAP.setName(evaluado.getName());
                evaluadoSNAP.setIdentification(evaluado.getIdentification());
                evaluadoSNAP.setIdentificationcatalog("PAS");
                evaluadoSNAP.setIdentificationcatalogcode("IDENTIFICATION");
            }

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

    public String getTipoevaluacion() {
        return tipoevaluacion;
    }

    public void setTipoevaluacion(String tipoevaluacion) {
        this.tipoevaluacion = tipoevaluacion;
    }

    /**
     * Abre el lov donde se realiza la evaluacion. Valida la fecha en la que se puede dar la prueba y el numero de intentos
     */
    public void openTest() {
        if (evaluado == null) {
            MessageHelper.setMessageWarn(MsgControlArmas.getProperty("msg_seleccionepersona"));
            return;
        }

        if (EvaluacionController.find(evaluado.getPk().getPersoncode().toString(), "PSICOLOGICA") == null) {
            MessageHelper.setMessageError(MsgControlArmas.getProperty("lbl_psicologicanecesaria"));
            return;
        }
//    	if(guardia==null){
//    		MessageHelper.setMessageError(MsgControlArmas.getProperty("lbl_psicologicanecesaria"));
//    		return;
//    	}
//    	if(tipoevaluacion==null){
//    		MessageHelper.setMessageWarn(MsgControlArmas.getProperty("msg_tipoevaluacion"));
//    	}
        if (numeroIntentos > EvaluacionController.findIntentosReprobados(evaluado.getPk().getPersoncode().toString(), tipoevaluacion)) {
            intento = EvaluacionController.findIntentosReprobados(evaluado.getPk().getPersoncode().toString(), tipoevaluacion).longValue() + 1;
        } else {
            MessageHelper.setMessageError(MsgControlArmas.getProperty("msg_numerointentos"));
            return;
        }
//    	if(EvaluacionController.findIntentos(evaluado.getPk().getPersoncode().toString(), tipoevaluacion)!=0)
//    	if(fecha.getTime()< EvaluacionController.findFecha(evaluado.getPk().getPersoncode().toString(), tipoevaluacion).getFechapreox().getTime()){
//    		MessageHelper.setMessageError(MsgControlArmas.getProperty("msg_fechaprox") +" " +EvaluacionController.findFecha(evaluado.getPk().getPersoncode().toString(), tipoevaluacion).getFechapreox());
//    		return;
//    	}

        Map<String, List<String>> params = new HashMap<>();

        ConocimientoLovController.openLov(params, evaluado, tipoevaluacion);

    }

    /**
     * Funcion que llama a una evaluacion
     *
     * @param event
     * @throws Exception
     */
    public void onReturnOpenTest(SelectEvent event) throws Exception {
        EvaluacionCompleta eval = new EvaluacionCompleta();
        eval = (EvaluacionCompleta) event.getObject();
        ingresarDatosEvaluacion();
        ingresarDetalleEvaluacion(eval);
        guardar = true;

        save();
    }

    /**
     * Llama al record de evaluaciones y carga los datos que se llevaran a la base
     *
     * @throws Exception
     */
    public void ingresarDatosEvaluacion() throws Exception {
        evaluacionController.create();
        Date fecha = new Date();
        Date fechalaboral = new Date();
        Integer dias = null;
        try {
            dias = ParametersController.find("INTENTOS", "1").getNumbervalue().intValue();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (dias == null || dias <= 0) {
            dias = 2;
        }
        Calendar calendario = Calendar.getInstance();
        for (int i = 0; i < dias; i++) {
            calendario.add(Calendar.DAY_OF_YEAR, 1);
            fechalaboral = isfechalaboral(calendario.getTime());
            calendario.setTime(fechalaboral);
        }
        try {
            evaluacionController.getRecord().setTipoevaluacion(tipoevaluacion);
            evaluacionController.getRecord().setTipoevaluacioncodigo("TIPOEVALUACION");
            evaluacionController.getRecord().setFecha(new java.sql.Timestamp(new Date().getTime()));
            evaluacionController.getRecord().setFechapreox(new java.sql.Date(fechalaboral.getTime()));
            evaluacionController.getRecord().setIntento(intento);
            evaluacionController.getRecord().setPersoncode(evaluado.getPk().getPersoncode());
            evaluacionController.getRecord().put("aprobacion", ParametersController.find("VALORAPROBACION", "1").getNumbervalue().floatValue());
            evaluacionController.update();
        } catch (Exception e) {
            MessageHelper.setMessageError("PROBLEMAS DE PARAMETRIZACION. CONSULTE AL EVALUADOR");
        }

    }

    /**
     * Verifica la fecha laboral
     *
     * @param fechalaboral
     * @return
     */
    /**
     * @param fechalaboral
     * @return
     */
    public Date isfechalaboral(Date fechalaboral) {
        String month = "0";
        Calendar calendario = Calendar.getInstance();
        calendario.setTime(fechalaboral);
        if (calendario.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || calendario.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            calendario.add(Calendar.DAY_OF_YEAR, 1);
            fechalaboral = isfechalaboral(calendario.getTime());
        }
        Integer mes = fechalaboral.getMonth();
        if (mes < 10) {
            month += mes.toString();
        } else {
            month = mes.toString();
        }
        if (TgeneNotAccountingDayController.findDaynuevo(month, fechalaboral.getDate())) {
            calendario.add(Calendar.DAY_OF_YEAR, 1);
            fechalaboral = isfechalaboral(calendario.getTime());
        }

        return fechalaboral;

    }

    /**
     * Carga el detalle de la evaluacion
     *
     * @param eval
     * @throws Exception
     */
    public void ingresarDetalleEvaluacion(EvaluacionCompleta eval) throws Exception {

        for (Evaluacion eva : eval.getLevaluacion()) {
            detallePreguntas.create();
            detallePreguntas.getRecord().setCpregunta(eva.getPregunta().getPk());
            detallePreguntas.getRecord().setCrespuestaingresada(eva.getCodigorespuesta());
            detallePreguntas.getRecord().getModifiedData().put("valor", RespuestasController.findxPk(detallePreguntas.getRecord().getCrespuestaingresada()));
            detallePreguntas.update();

        }

    }

//    /**
//     *Abre el lov de persona 
//     */
//    public void openPersonLov() {
//		Map<String, List<String>> params = new HashMap<>();
//		PersonLovController.openLov(params);
//	}
//    /**
//     * Love que regresa la informacion de una persona
//     * @param event
//     * @throws Exception
//     */
//    public void onReturnPersonLov(SelectEvent event) throws Exception {
//		  setEvaluado( (TcustPersonDetail) event.getObject());
//		  if(evaluado.getPersontypecatalog()==null){
//			  lTipoPersona=null;
//			  return;
//		  }
//		  lTipoPersona=CatalogDetailController.findxCodigoCodcatalogo(evaluado.getPersontypecatalog(), evaluado.getPersontypecatalogcode());
////          	guardia=GuardiasController.findxcguardia(evaluado.getPk().getPersoncode().toString());
////          	if(guardia==null){
////          		MessageHelper.setMessageError(MsgControlArmas.getProperty("lbl_psicologicanecesaria"));
////          	}
//    }
    /**
     * Limpia la persona seleccionada
     */
    public void limpiar() {
        evaluado = null;
        lTipoPersona = null;
        bloquear = false;
    }

    @Override
    protected void querydatabase() {
        // TODO Auto-generated method stub

    }

    /* (non-Javadoc)
	 * @see com.fp.frontend.controller.AbstractController#save()
     */
    @Override
    public void save() {
        try {
            if (!guardar) {
                return;
            }
            Request request = this.callerhelper.getRequest();
            DtoSave dtosavevaluacion = this.evaluacionController.getDtoSave(true);
            HashMap<String, DtoSave> msave = new HashMap<String, DtoSave>();
            msave.put(evaluacionController.getBeanalias(), dtosavevaluacion); // adicionar metadata de mantenimiento para cada tabla.
            dtosavevaluacion.setPosition(1);

            DtoSave dtosavepreguntas = this.detallePreguntas.getDtoSave(true);

            msave.put(detallePreguntas.getBeanalias(), dtosavepreguntas); // adicionar metadata de mantenimiento para cada tabla.
            dtosavepreguntas.setPosition(2);

            request.setSaveTables(msave);
            Response resp = this.callerhelper.executeSave(request);
            if (resp.getResponseCode().compareTo(Response.RESPONSE_OK) == 0) {

                MessageHelper.setMessageInfo(MsgControlArmas.getProperty("lbl_examenfinalizado"));
                String calificacion = (String) resp.get("result");
                if (calificacion.equals("APR")) {
                    MessageHelper.setMessageInfo(MsgControlArmas.getProperty("lbl_aprobado"));
                } else {
                    MessageHelper.setMessageInfo(MsgControlArmas.getProperty("lbl_reprobado") + ", Debe Realizar el Test Nuevamente"); //+"."+MsgControlArmas.getProperty("msg_fechaprox") +" " +EvaluacionController.findFecha(evaluado.getPk().getPersoncode().toString(), tipoevaluacion).getFechapreox());
                }

            } else {
                MessageHelper.setMessageError(resp);
            }

        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
        } finally {
            guardar = false;
            evaluacionController.clearAll();
            detallePreguntas.clearAll();
            bloquear = true;
            init();

        }
    }

    /**
     * M&eacute;todo para buscar a la persona en la snap
     *
     * @param documento
     */
    public TcustPersonDetail buscarPersonaSnap(String documento, String tipoDocumento) {
        if (tipoDocumento.equals("CED")) {
            Cedula cedula = ClienteCedula.obtenerCedula(documento);
            if (cedula != null) {
                TcustPersonDetail detail = new TcustPersonDetail();
                detail.setName(cedula.getNombre());
                detail.setIdentification(cedula.getCedula());
                detail.setIdentificationcatalog("CED");
                detail.setIdentificationcatalogcode("IDENTIFICATION");
                return detail;
            } else {
                return null;
            }
        } else {
            Contribuyente contribuyente = ClienteRUC.obtenerRUC(documento);
            if (contribuyente != null) {
                TcustPersonDetail detail = new TcustPersonDetail();
                detail.setName(contribuyente.getRazonSocial());
                detail.setIdentification(contribuyente.getNumeroRuc());
                detail.setIdentificationcatalog("RUC");
                detail.setIdentificationcatalogcode("IDENTIFICATION");
                return detail;
            } else {
                return null;
            }
        }
    }

    public EvaluacionController getEvaluacionController() {
        return evaluacionController;
    }

    public void setEvaluacionController(EvaluacionController evaluacionController) {
        this.evaluacionController = evaluacionController;
    }

    public DetallePreguntasController getDetallePreguntas() {
        return detallePreguntas;
    }

    public void setDetallePreguntas(DetallePreguntasController detallePreguntas) {
        this.detallePreguntas = detallePreguntas;
    }

    public TcustPersonDetail getEvaluado() {
        return evaluado;
    }

    public void setEvaluado(TcustPersonDetail evaluado) {
        this.evaluado = evaluado;
    }

    public List<TgeneCatalogDetail> getLtipoevaluacion() {
        return ltipoevaluacion;
    }

    public void setLtipoevaluacion(List<TgeneCatalogDetail> ltipoevaluacion) {
        this.ltipoevaluacion = ltipoevaluacion;
    }

    public List<Evaluacion> getLevaluacion() {
        return levaluacion;
    }

    public void setLevaluacion(List<Evaluacion> levaluacion) {
        this.levaluacion = levaluacion;
    }

    public Date getFecha() {
        return fecha;
    }

    public void setFecha(Date fecha) {
        this.fecha = fecha;
    }

    public TgeneCatalogDetail getlTipoPersona() {
        return lTipoPersona;
    }

    public void setlTipoPersona(TgeneCatalogDetail lTipoPersona) {
        this.lTipoPersona = lTipoPersona;
    }

    public boolean isBloquear() {
        return bloquear;
    }

    public void setBloquear(boolean bloquear) {
        this.bloquear = bloquear;
    }

    public TcustPersonDetail getCompania() {
        return compania;
    }

    public void setCompania(TcustPersonDetail compania) {
        this.compania = compania;
    }

    public TarmGuardias getGuardia() {
        return guardia;
    }

    public void setGuardia(TarmGuardias guardia) {
        this.guardia = guardia;
    }

    public TcustPersonDetail getEvaluadoSNAP() {
        return evaluadoSNAP;
    }

    public void setEvaluadoSNAP(TcustPersonDetail evaluadoSNAP) {
        this.evaluadoSNAP = evaluadoSNAP;
    }

}
