/**
 *
 */
package com.fp.frontend.controller.security;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

import org.primefaces.context.RequestContext;

import com.fp.dto.AbstractDataTransport;
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.pcustomer.PersonAddressController;
import com.fp.frontend.controller.pcustomer.lov.PersonLovController;
import com.fp.frontend.controller.pgeneral.gene.ParametersController;
import com.fp.frontend.controller.pgeneral.message.MessageTemplatesController;
import com.fp.frontend.controller.pgeneral.message.MessageTemplatesDescController;
import com.fp.frontend.helper.MessageHelper;
import com.fp.frontend.utility.MsgControlArmas;
import com.fp.mail.Mail;
import com.fp.persistence.pcustomer.gene.TcustPersonAddress;
import com.fp.persistence.pcustomer.gene.TcustPersonDetail;
import com.fp.persistence.pgeneral.message.TgeneMessageTemplates;
import com.fp.persistence.pgeneral.message.TgeneMessageTemplatesDesc;
import com.fp.persistence.pgeneral.safe.TsafeUserDetail;

/**
 * Clase controladora del bean TsafeUserDetail.
 *
 * @author Andres E. Carpio
 * @version 2.1
 */
@ManagedBean
@ViewScoped
public class ChangePassPersonalController extends
        AbstractController<TsafeUserDetail> implements Serializable {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    @ManagedProperty(value = "#{personAddressController}")
    private PersonAddressController personAddress;
    // @ManagedProperty(value = "#{userProfileController}")
    // private UserProfileController userprofile;

    // Control para el mensaje de confirmacion
    private boolean habilitaCampos = true;

    public ChangePassPersonalController() throws Exception {
        super(TsafeUserDetail.class);
    }

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

    /**
     * Incializa el controlador, cuando se esta utilizando una pagina que utliza
     * el controlador.
     */
    private void init() {
        try {
            this.create();
            this.lrecord = new ArrayList<>();
            this.beanalias = "TSAFEUSERDETAIL";
        } catch (Exception e) {
            MessageHelper.setMessageError(e);
        }
    }

    @Override
    protected void querydatabase() {
        try {

            super.addFilter("pk.usercode", super.getLoginController()
                    .getRequest().getUser());
            super.addFilterDateto();
            super.addFilter("companycode", super.getLoginController()
                    .getRequest().getCompany().toString());

            if (!this.existAtLeastOneFilterValue()) {
                MessageHelper.setMessageError("msg_filterrequird");
                return;
            }

            Request request = this.callerhelper.getRequest();
            DtoQuery dto = super.getDtoQuery(false);
            dto.setOrderby("t.pk.personcode"); // En en string van todos los
            // campos de orden
            // ("t.pk,  t.nombre, t.cpais").

            // subqueries
            SubQuery subquery = new SubQuery("TgeneChannels", "description",
                    "chanelname", "i.pk = t.channelcode");
            dto.addSubQuery(subquery);

            SubQuery subqueryName = new SubQuery(
                    "TcustPersonDetail",
                    "name",
                    "name",
                    " i.pk.personcode = t.pk.personcode"
                    + " and i.pk.dateto = to_date('2999-12-31', 'YYYY-MM-DD')");
            dto.addSubQuery(subqueryName);

            SubQuery subquerya = new SubQuery("TgeneArea", "descripction",
                    "areaname",
                    "i.pk.companycode = t.companycode and i.pk.areacode = t.areacode ");
            dto.addSubQuery(subquerya);

            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.record = new TsafeUserDetail();
                MessageHelper.setMessageError(resp);
            } else {
                this.record = (TsafeUserDetail) resp.get(this.beanalias);
                if (this.record != null) {
                    // this.userprofile.addFilter("pk.usercode",
                    // this.record.getPk().getUsercode());
                    // this.userprofile.query();
                    TcustPersonDetail tcpd = PersonLovController
                            .find(this.record.getPk().getPersoncode()
                                    .toString());
                    super.addField("personname", tcpd != null ? tcpd.getName()
                            : "");
                    TcustPersonAddress mail = personAddress
                            .findPersonaPorDireccionTipoCatalogo(this.record
                                    .getPk().getPersoncode().toString(), "3");
                    this.personAddress.setPersoncode(this.record.getPk()
                            .getPersoncode());
                    if (mail != null) {
                        super.addField("email", mail.getAddress());
                        personAddress.setRecord(mail);
                    } else {
                        personAddress.create();
                    }
                    super.postQuery((AbstractDataTransport) resp
                            .get(this.beanalias));
                } else {
                    // this.userprofile.setLrecord(null);
                    this.create();
                }
            }

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

    @Override
    public void save() {
        try {
            if (this.validateUser()) {
                MessageHelper.setMessageError("msg_userrequired");
                return;
            }
            if (!this.passwordvalidate()) {
                return;
            }

            String oldPass = this.callerhelper
                    .getPasswordEncriptado((String) this.getMfilelds().get(
                            "oldpassword"));
            String newPass = this.callerhelper
                    .getPasswordEncriptado((String) this.getMfilelds().get(
                            "newpassword"));

            this.record.put("newpassword", this.getMfilelds()
                    .get("newpassword"));
            this.record.put("origination", newPass);
            this.record.put("oldpassword", oldPass);

            this.record.setPassword(newPass);
            if (this.record.getChangepassword().compareTo("Y") == 0) {
                this.record.setChangepassword("N");
            }
            this.update();
            if (this.getMfilelds().get("email") != null) {
                this.personAddress.getRecord().setAddress(
                        this.getMfilelds().get("email").toString());
            }
            this.personAddress.update();

            Request request = this.callerhelper.getRequest();
            HashMap<String, DtoSave> msave = new HashMap<String, DtoSave>();
            DtoSave dtoSavePassword = super.getDtoSave();
            dtoSavePassword.setIsForm(true);
            dtoSavePassword.setPosition(1);
            if (!dtoSavePassword.pendingProcess()) {
                MessageHelper
                        .setMessageError(MsgControlArmas
                                .getProperty("msg_error_claveanteriornopuederserigualactual"));
                return;
            }
            DtoSave dtosaveMail = personAddress.getDtoSave();
            dtosaveMail.setPosition(2);
            msave.put(this.beanalias, dtoSavePassword);
            msave.put(this.personAddress.getBeanalias(), dtosaveMail);
            request.setSaveTables(msave);
            Response resp = this.callerhelper.executeSave(request);
            if (resp.getResponseCode().compareTo(Response.RESPONSE_OK) == 0) {
                this.postCommit(resp);
                this.envioCorreoCambio();
                MessageHelper.setMessageInfo(resp);
                confirmaChangePasswd();
            } else {

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

            MessageHelper.setMessageError(e);
        }
    }

    public void saveUser() {
        try {
            if (this.validateUser()) {
                MessageHelper.setMessageError("msg_userrequired");
                return;
            }
            if (!this.passwordvalidate()) {
                return;
            }

            String oldPass = this.callerhelper
                    .getPasswordEncriptado((String) this.getMfilelds().get(
                            "oldpassword"));
            String newPass = this.callerhelper
                    .getPasswordEncriptado((String) this.getMfilelds().get(
                            "newpassword"));
            System.out.println("Nuevo Password " + newPass);
            System.out.println("Nuevo Password "
                    + (String) this.getMfilelds().get("newpassword"));
            if (verificaPasswd((String) this.getMfilelds().get("newpassword"))) {

                this.record.put("newpassword",
                        this.getMfilelds().get("newpassword"));
                this.record.put("origination", newPass);
                this.record.put("oldpassword", oldPass);

                this.record.setPassword(newPass);
                if (this.record.getChangepassword().compareTo("Y") == 0) {
                    this.record.setChangepassword("N");
                }
                this.update();
                if (this.getMfilelds().get("email") != null) {
                    this.personAddress.getRecord().setAddress(
                            this.getMfilelds().get("email").toString());
                }
                this.personAddress.update();

                Request request = this.callerhelper.getRequest();
                HashMap<String, DtoSave> msave = new HashMap<String, DtoSave>();
                DtoSave dtoSavePassword = super.getDtoSave();
                dtoSavePassword.setIsForm(true);
                dtoSavePassword.setPosition(1);
                if (!dtoSavePassword.pendingProcess()) {
                    MessageHelper
                            .setMessageError(MsgControlArmas
                                    .getProperty("msg_error_claveanteriornopuederserigualactual"));
                    return;
                }
                DtoSave dtosaveMail = personAddress.getDtoSave();
                dtosaveMail.setPosition(2);
                msave.put(this.beanalias, dtoSavePassword);
                msave.put(this.personAddress.getBeanalias(), dtosaveMail);
                request.setSaveTables(msave);

                Response resp = this.callerhelper.executeSave(request);
                if (resp.getResponseCode().compareTo(Response.RESPONSE_OK) == 0) {
                    this.postCommit(resp);
                    try {
                        this.envioCorreoCambio();
                    } catch (Exception e) {
                        // TODO: handle exception
                        e.printStackTrace();
                    }

                    MessageHelper.setMessageInfo(resp);
                    //habilitaCampos = false;
                    confirmaChangePasswd();
                    mensajeconfirmaChangePasswd();
                    // mensajeconfirmaChangePasswd();
                    // abre el dialogo que acepte

                } else {

                    MessageHelper.setMessageError(resp);
                }
            } else {
                MessageHelper
                        .setMessageError("LA CLAVE NO CUMPLE LAS POLÍTICAS DE SEGURIDAD");
                System.out
                        .println("La clave no cumple las politicas de seguridad nuevo Save");
            }
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
            e.printStackTrace();
        }
    }

    /**
     * Env&iacute;a el correo de cambio de email
     *
     * @throws Exception
     */
    /*
	 * private void envioCorreoCambio() throws Exception{ Mail m = new Mail();
	 * m.config(ParametersController.find("MAIL.FROM", "1").getTextvalue(),
	 * ParametersController.find("MAIL.SMTP.SERVER", "1").getTextvalue(),
	 * ParametersController.find("MAIL.SMTP.PORT",
	 * "1").getNumbervalue().intValue(),
	 * ParametersController.find("MAIL.SMTP.USER", "1").getTextvalue(),
	 * ParametersController.find("MAIL.SMTP.PASSWORD", "1").getTextvalue(),
	 * Boolean.valueOf(ParametersController.find("MAIL.SMTP.AUTH",
	 * "1").getTextvalue()),
	 * Boolean.valueOf(ParametersController.find("MAIL.SMTPS",
	 * "1").getTextvalue())); m.setTo(personAddress.getRecord().getAddress());
	 * MessageTemplatesController message = new MessageTemplatesController();
	 * message.addFilter("pk", "62"); message.query(); if(message.getLrecord()
	 * != null && !message.getLrecord().isEmpty()){ TgeneMessageTemplates asunto
	 * = message.getLrecord().get(0); MessageTemplatesDescController content =
	 * new MessageTemplatesDescController(); content.addFilter("pk.code", "62");
	 * content.addFilter("pk.languagecode", "ES"); content.query();
	 * if(content.getLrecord() != null && !content.getLrecord().isEmpty()){
	 * TgeneMessageTemplatesDesc descripcionContenido =
	 * content.getLrecord().get(0); //Velocity.init(); //VelocityContext context
	 * = new VelocityContext(); //context.put("nombreusuario",
	 * this.getLoginController().getRequest().getUser()); //context.put("clave",
	 * this.record.get("newpassword")); m.setSubject(asunto.getDescription());
	 * //StringWriter sw = new StringWriter(); String
	 * sw=descripcionContenido.getTemplate().replace("$clave",
	 * this.record.get("newpassword").toString());
	 * sw=sw.replace("$nombreusuario", this.record.get("name")+"");
	 * //Velocity.evaluate(context, sw, "", descripcionContenido.getTemplate());
	 * m.setCont(sw.toString()); m.setContentMessageType("text/html"); m.send();
	 * } } }
     */
    private void envioCorreoCambio() throws Exception {
        try {
            Mail m = new Mail();
            m.config(
                    ParametersController.find("MAIL.FROM", "1").getTextvalue(),
                    ParametersController.find("MAIL.SMTP.SERVER", "1")
                    .getTextvalue(),
                    ParametersController.find("MAIL.SMTP.PORT", "1")
                    .getNumbervalue().intValue(), ParametersController
                    .find("MAIL.SMTP.USER", "1").getTextvalue(),
                    ParametersController.find("MAIL.SMTP.PASSWORD", "1")
                    .getTextvalue(), Boolean
                    .valueOf(ParametersController.find(
                            "MAIL.SMTP.AUTH", "1").getTextvalue()),
                    Boolean.valueOf(ParametersController
                            .find("MAIL.SMTPS", "1").getTextvalue()));
            m.setTo(personAddress.getRecord().getAddress());
            MessageTemplatesController message = new MessageTemplatesController();
            message.addFilter("pk", "62");
            message.query();
            if (message.getLrecord() != null && !message.getLrecord().isEmpty()) {
                TgeneMessageTemplates asunto = message.getLrecord().get(0);
                MessageTemplatesDescController content = new MessageTemplatesDescController();
                content.addFilter("pk.code", "62");
                content.addFilter("pk.languagecode", "ES");
                content.query();
                if (content.getLrecord() != null
                        && !content.getLrecord().isEmpty()) {
                    TgeneMessageTemplatesDesc descripcionContenido = content
                            .getLrecord().get(0);
                    // Velocity.init();
                    // VelocityContext context = new VelocityContext();
                    // context.put("nombreusuario",
                    // this.getLoginController().getRequest().getUser());
                    // context.put("clave", this.record.get("newpassword"));
                    m.setSubject(asunto.getDescription());
                    // StringWriter sw = new StringWriter();
                    String sw = descripcionContenido.getTemplate()
                            .replace("$clave",
                                    this.record.get("newpassword").toString());
                    sw = sw.replace("$nombreusuario", this.record.get("name")
                            + "");
                    // Velocity.evaluate(context, sw, "",
                    // descripcionContenido.getTemplate());
                    m.setCont(sw.toString());
                    m.setContentMessageType("text/html");
                    m.send();
                }
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }

    }

    private boolean validateUser() {
        boolean result = false;
        if (this.record.getPk() == null) {
            result = true;
        }
        return result;
    }

    @Override
    public void postCommit(Response response) throws Exception {
        super.postCommitGeneric(response, this.beanalias);
        RequestContext.getCurrentInstance().execute(
                "PF('dialogChangePassword').hide()");
    }

    // /**
    // * Entrega el valor de: userprofile
    // *
    // * @return UserProfileController
    // */
    // public UserProfileController getUserprofile() {
    // return userprofile;
    // }
    //
    // /**
    // * Fija el valor de: userprofile
    // *
    // * @param UserProfileController
    // */
    // public void setUserprofile(UserProfileController userprofile) {
    // this.userprofile = userprofile;
    // }
    /**
     * Valida que el usuario ingrese la contrasena y la contrasena de validacion
     * y que las dos sean iguales.
     *
     * @return boolean
     * @throws Exception
     */
    private boolean passwordvalidate() throws Exception {
        Object p = super.getFieldvalue("newpassword");
        Object np = super.getFieldvalue("confirmpassword");
        if ((p == null) || (np == null)) {
            MessageHelper.setMessageError("msg_passwordrequired");
            return false;
        }
        if (!p.equals(np)) {
            MessageHelper.setMessageError("msg_passwordnomatch");
            return false;
        }
        return true;
    }

    public PersonAddressController getPersonAddress() {
        return personAddress;
    }

    public void setPersonAddress(PersonAddressController personAddress) {
        this.personAddress = personAddress;
    }

    public boolean isHabilitaCampos() {
        return habilitaCampos;
    }

    public void setHabilitaCampos(boolean habilitaCampos) {
        this.habilitaCampos = habilitaCampos;
    }

    public void cancelChangePasswd() throws IOException {
        // RequestContext.getCurrentInstance().execute("PF('dialog').show()");
        logout();
        ExternalContext ec = FacesContext.getCurrentInstance()
                .getExternalContext();
        ec.redirect(ec.getRequestContextPath() + "/" + "login.xhtml");
    }

    public void confirmaChangePasswd() throws IOException {
        // logout();
        MessageHelper
                .setMessageInfo("SU CLAVE HA SIDO CAMBIADA SATISFACTORIAMENTE");
        // confirmaChangePswd();
        // ExternalContext ec =
        // FacesContext.getCurrentInstance().getExternalContext();
        // ec.redirect(ec.getRequestContextPath() + "/" + "login.xhtml");
        // ec.redirect(ec.getRequestContextPath() + "/" +
        // "passwordExpired.xhtml");
    }

    public void mensajeconfirmaChangePasswd() throws IOException {
        logout();

        ExternalContext ec = FacesContext.getCurrentInstance()
                .getExternalContext();
        ec.redirect(ec.getRequestContextPath() + "/" + "login.xhtml");
    }

    public String logout() {
        System.out.println("logout::cerrando session bean");
        FacesContext fc = FacesContext.getCurrentInstance();
        if (fc != null) {
            fc.getExternalContext().invalidateSession();
        }
        return "/login?faces-redirect=true";
    }

    // Procedimiento Verifica Seguridad de la Clave del Usuario
    private boolean verificaPasswd(String clave) {
        boolean minuscula = false;
        boolean mayuscula = false;
        boolean numero = false;
        boolean caracter = false;
        // Hace un barrido de los caracteres ingresados en la clave
        for (int i = 0; i < clave.length(); i++) {
            // Verifica que el codigo ASCII ( letras minusculas)
            if (clave.charAt(i) >= 97 && clave.charAt(i) <= 122) {
                minuscula = true;
                // Verifica que el codigo ASCII ( letras mayusculas)
            } else if (clave.charAt(i) >= 65 && clave.charAt(i) <= 90) {
                mayuscula = true;
                // Verifica que el codigo ASCII ( numeros)
            } else if (clave.charAt(i) >= 48 && clave.charAt(i) <= 57) {
                numero = true;
                // Si no cumple las condiciones anteriores es caracter especial
            } else {
                caracter = true;
            }
        }
        if ((minuscula == true) && (mayuscula == true) && (numero == true)
                && (caracter == true)) {
            return true;
        } else {
            return false;
        }
    }

    public String confirmaChangePswd() {
        System.out.println("logout::cerrando session bean confirma clave");
        /*
		 * FacesContext fc = FacesContext.getCurrentInstance(); if (fc != null)
		 * { fc.getExternalContext().invalidateSession(); }
         */
        return "/passwordExpired?faces-redirect=true";
    }

}
