package com.fp.frontend.controller.general.audit;

import java.util.ArrayList;
import java.util.Calendar;
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 org.primefaces.event.SelectEvent;

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.Filter;
import com.fp.frontend.controller.AbstractController;
import com.fp.frontend.controller.ReportController;
import com.fp.frontend.controller.pcustomer.lov.PersonLovController;
import com.fp.frontend.controller.pgeneral.lov.EntityLovController;
import com.fp.frontend.controller.pgeneral.lov.TransactionLovController;
import com.fp.frontend.controller.pgeneral.lov.UserLovController;
import com.fp.frontend.controller.pgeneral.product.ModuleController;
import com.fp.frontend.controller.pgeneral.safe.AuditInsDelController;
import com.fp.frontend.controller.pgeneral.safe.SafeAuditController;
import com.fp.frontend.helper.MessageHelper;
import com.fp.persistence.pcustomer.gene.TcustPersonDetail;
import com.fp.persistence.pgeneral.gene.TgeneEntity;
import com.fp.persistence.pgeneral.product.TgeneModule;
import com.fp.persistence.pgeneral.safe.TsafeAudit;
import com.fp.persistence.pgeneral.safe.TsafeAuditInsDel;
import com.fp.persistence.pgeneral.safe.TsafeUserDetail;
import com.fp.persistence.pgeneral.trans.TgeneTransaction;

/**
 * Clase que se utliza para la llanada del reporte de Auditoria
 *
 * @author Jacqueline Arias
 *
 * @version 2.1
 */
@SuppressWarnings("serial")
@ManagedBean
@ViewScoped
public class AuditReportController extends AbstractController<AbstractDataTransport> {

    /**
     * Fecha desde
     */
    private Date dateFrom;

    /**
     * Fecha desde
     */
    private Date maxDateTo;

    private Date minDateFrom;
    /**
     * Fecha hasta
     */
    private Date dateTo;

    private String user;

    private String userName;

    private String transactioncode;

    private String transactionmodule;

    private String transactionname;

    private String transactionversion;

    private String entityName;

    private String clientCode;

    private String clientName;

    private String moduleCode;

    private List<TgeneModule> listModule;

    @ManagedProperty(value = "#{safeAuditController}")
    private SafeAuditController safeAudit;

    @ManagedProperty(value = "#{auditInsDelController}")
    private AuditInsDelController auditinsdel;

    @ManagedProperty(value = "#{reportController}")
    private ReportController reportController;

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

    @PostConstruct
    public void postConstruct() {
        this.init();
    }

    private void init() {
        try {

            this.lrecord = new ArrayList<>();
            this.beanalias = "REPORTAUDIT";
            this.recperpage = 15;
            this.listModule = ModuleController.find();
            // this.create();
        } catch (Exception e) {
            MessageHelper.setMessageError(e);
        }
    }

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

        try {
            Request request = this.callerhelper.getRequest();

            DtoQuery dtoQuerySafeUpdate = this.safeAudit.getDtoSafeAudit();
            DtoQuery dtoinsdel = this.auditinsdel.getDtoAuditInsDel();
            if ((this.dateFrom != null) && (this.dateTo != null)) {
                Filter f = null;
                f = new Filter();
                f.setSql("t.pk.changedate >= to_date('" + this.dateFrom + "', 'yyyy-MM-dd') and t.pk.changedate <= to_date('" + this.dateTo
                        + "', 'yyyy-MM-dd') ");
                dtoinsdel.addFiltro(f);
                dtoQuerySafeUpdate.addFiltro(f);
            }

            HashMap<String, DtoQuery> mtables = new HashMap<String, DtoQuery>();
            mtables.put(this.safeAudit.getBeanalias(), dtoQuerySafeUpdate);
            mtables.put(this.auditinsdel.getBeanalias(), dtoinsdel);
            request.setQueryTables(mtables);
            Response resp = this.callerhelper.executeQuery(request);
            if (resp.getResponseCode().compareTo(Response.RESPONSE_OK) != 0) {
                this.lrecord = new ArrayList<>();
                this.safeAudit.setLrecord(new ArrayList<TsafeAudit>());
                this.auditinsdel.setLrecord(new ArrayList<TsafeAuditInsDel>());
                MessageHelper.setMessageError(resp);
            } else {

                this.safeAudit.setLrecord((List<TsafeAudit>) resp.get(this.safeAudit.getBeanalias()));
                this.auditinsdel.setLrecord((List<TsafeAuditInsDel>) resp.get(this.auditinsdel.getBeanalias()));

                this.safeAudit.postQuery(this.safeAudit.getLrecord());
                this.auditinsdel.postQuery(this.auditinsdel.getLrecord());
            }
        } catch (Throwable e) {
            MessageHelper.setMessageError(e);
        }

    }

    /**
     * Metodo que obtiene abre el lov de Personas
     */
    public void openUserLov() {
        Map<String, List<String>> params = new HashMap<>();
        UserLovController.openLov(params);
    }

    /**
     * Metodo que pega los valores del lov de personas
     *
     * @param event
     * @throws Exception
     */
    public void onReturnUserLov(SelectEvent event) throws Exception {
        TsafeUserDetail t = (TsafeUserDetail) event.getObject();
        this.setUser(t.getPk().getUsercode());
        this.setUserName(t.getModifiedData().get("personname") != null ? t.getModifiedData().get("personname").toString() : "");
        this.auditinsdel.addFilter("usercode", this.user);
        this.safeAudit.addFilter("usercode", this.user);
    }

    /**
     * Metodo que obtiene abre el lov de Personas
     */
    public void openTransactionLov() {
        if ((this.moduleCode != null) && !this.moduleCode.isEmpty()) {
            Map<String, List<String>> params = new HashMap<>();
            List<String> lmodule = new ArrayList<>();
            lmodule.add(this.moduleCode);
            params.put("moduleCode", lmodule);
            TransactionLovController.openLov(params);
        } else {
            MessageHelper.setMessageError("msg_modulerequird");
            return;
        }

    }

    /**
     * Metodo que pega los valores del lov de personas
     *
     * @param event
     * @throws Exception
     */
    public void onReturnTransactionLov(SelectEvent event) throws Exception {
        TgeneTransaction t = (TgeneTransaction) event.getObject();
        this.setTransactionmodule(t.getPk().getTransactionmodule());
        this.setTransactioncode(t.getPk().getTransactioncode().toString());
        this.setTransactionname(t.getName());
        this.setTransactionversion(t.getPk().getTransactionversion().toString());
        this.auditinsdel.addFilter("transactionmodule", this.transactioncode);
        this.safeAudit.addFilter("transactionmodule", this.transactioncode);
    }

    /**
     */
    public void openEntityLov() {
        Map<String, List<String>> params = new HashMap<>();
        List<String> logList = new ArrayList<>();
        logList.add("1");
        params.put("log", logList);
        EntityLovController.openLov(params);
    }

    /**
     * Metodo que pega los valores del lov de personas
     *
     * @param event
     * @throws Exception
     */
    public void onReturnEntityLov(SelectEvent event) throws Exception {
        TgeneEntity t = (TgeneEntity) event.getObject();
        this.setEntityName(t.getPk().getTname());
        this.auditinsdel.addFilter("pk.tablename", this.entityName);
        this.safeAudit.addFilter("pk.tablename", this.entityName);
    }

    /**
     * Metodo que obtiene abre el lov de Personas
     */
    public void openPersonLov() {
        Map<String, List<String>> params = new HashMap<>();
        PersonLovController.openLov(params);
    }

    /**
     * Metodo que pega los valores del lov de personas
     *
     * @param event
     * @throws Exception
     */
    public void onReturnPersonLov(SelectEvent event) throws Exception {
        TcustPersonDetail t = (TcustPersonDetail) event.getObject();
        this.setClientCode(t.getPk().getPersoncode().toString());
        this.setClientName(t.getName());
        this.auditinsdel.addFilter("personcode", this.clientCode);
        this.safeAudit.addFilter("personcode", this.clientCode);

    }

    /**
     * Listener del lov de transacciones
     */
    public void listenerTransaction() {
        this.transactionmodule = null;
        this.transactioncode = null;
        this.transactionname = null;
        this.auditinsdel.addFilter("transactionmodule", this.moduleCode);
        this.safeAudit.addFilter("transactionmodule", this.moduleCode);
    }

    /**
     * Metodo que llama al reporte en xlsx
     */
    public void generateXls() {
        this.generateReport("general/reports/auditoria_final", "Auditoria", "xlsx");

    }

    /**
     * Metodo de envio de parametros del reporte
     *
     * @param name
     * @param filename
     * @param format
     */
    private void generateReport(String name, String filename, String format) {
        String path = name;

        // Fija parametros del report.
        HashMap<String, Object> parameters = new HashMap<>();
        parameters.put("dateFrom", this.dateFrom.toString());
        parameters.put("dateTo", this.dateTo.toString());
        parameters.put("userCode", this.user);
        parameters.put("transactionModule", this.transactionmodule);
        if (moduleCode != null && transactionmodule == null) {
            parameters.put("transactionModule", moduleCode);
        }
        parameters.put("transactionCode", this.transactioncode);
        parameters.put("tableName", this.entityName);
        parameters.put("personcode", this.clientCode);
        parameters.put("transactionVersion", this.transactionversion);
        parameters.put("company", Integer.parseInt(super.getLoginController().getRequest().getCompany().toString()));
        parameters.put("pathLogoIzquierda", "repo:/maia/1/image/comandoconjunto");
        parameters.put("pathLogoDerecha", "repo:/maia/1/image/selloarmas");

        if (format == null) {
            format = "pdf";
        }
        try {
            if (format.equals("xlsx") || format.equals("xls")) {
                this.reportController.executeXls(path, parameters, format, filename, this.getLoginController());
            } else {
                this.reportController.execute(path, parameters, format, filename, this.getLoginController());
            }

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

    /**
     * Metodo que llama al reporte en pdf
     */
    public void generateAudit() {
        this.generateReport("general/reports/auditoria_final", "Auditoria", null);
    }

    public Date getDateFrom() {
        return this.dateFrom;
    }

    /**
     * Validacion de los 7 dias para el calendario
     */
    public void initDatesTo() {
        if (this.dateFrom != null) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(this.dateFrom);
            calendar.add(Calendar.DATE, 6);
            this.maxDateTo = calendar.getTime();
        }

    }

    /**
     * Validacion de los 7 dias para el calendario
     */
    public void initDatesFrom() {
        if (this.dateTo != null) {
            Calendar calendarTo = Calendar.getInstance();
            calendarTo.setTime(this.dateTo);
            calendarTo.add(Calendar.DATE, -6);
            this.minDateFrom = calendarTo.getTime();
        }

    }

    public void setDateFrom(Date dateFrom) {
        this.dateFrom = dateFrom;
    }

    public Date getDateTo() {
        return this.dateTo;
    }

    public void setDateTo(Date dateTo) {
        this.dateTo = dateTo;
    }

    public String getTransactioncode() {
        return this.transactioncode;
    }

    public void setTransactioncode(String transactioncode) {
        this.transactioncode = transactioncode;
    }

    public String getTransactionmodule() {
        return this.transactionmodule;
    }

    public void setTransactionmodule(String transactionmodule) {
        this.transactionmodule = transactionmodule;
    }

    public String getTransactionname() {
        return this.transactionname;
    }

    public void setTransactionname(String transactionname) {
        this.transactionname = transactionname;
    }

    public String getEntityName() {
        return this.entityName;
    }

    public void setEntityName(String entityName) {
        this.entityName = entityName;
    }

    public String getClientCode() {
        return this.clientCode;
    }

    public void setClientCode(String clientCode) {
        this.clientCode = clientCode;
    }

    public String getClientName() {
        return this.clientName;
    }

    public void setClientName(String clientName) {
        this.clientName = clientName;
    }

    public String getModuleCode() {
        return this.moduleCode;
    }

    public void setModuleCode(String moduleCode) {
        this.moduleCode = moduleCode;
    }

    public List<TgeneModule> getListModule() {
        return this.listModule;
    }

    public void setListModule(List<TgeneModule> listModule) {
        this.listModule = listModule;
    }

    public String getUser() {
        return this.user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getUserName() {
        return this.userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public SafeAuditController getSafeAudit() {
        return this.safeAudit;
    }

    public void setSafeAudit(SafeAuditController safeAudit) {
        this.safeAudit = safeAudit;
    }

    public ReportController getReportController() {
        return this.reportController;
    }

    public void setReportController(ReportController reportController) {
        this.reportController = reportController;
    }

    public String getTransactionversion() {
        return this.transactionversion;
    }

    public void setTransactionversion(String transactionversion) {
        this.transactionversion = transactionversion;
    }

    public AuditInsDelController getAuditinsdel() {
        return this.auditinsdel;
    }

    public void setAuditinsdel(AuditInsDelController auditinsdel) {
        this.auditinsdel = auditinsdel;
    }

    /**
     * @return the maxDateTo
     */
    public Date getMaxDateTo() {
        return this.maxDateTo;
    }

    /**
     * @param maxDateTo the maxDateTo to set
     */
    public void setMaxDateTo(Date maxDateTo) {
        this.maxDateTo = maxDateTo;
    }

    public Date getMinDateFrom() {
        return this.minDateFrom;
    }

    public void setMinDateFrom(Date minDateFrom) {
        this.minDateFrom = minDateFrom;
    }

}
