package com.fp.general.rules.query.trans;

import com.fp.common.helper.Constant;
import com.fp.persistence.pgeneral.product.TgeneProduct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.fp.dto.Response;
import com.fp.dto.query.QueryBean;
import com.fp.dto.query.QueryRequest;
import com.fp.dto.rules.QueryRule;
import com.fp.persistence.commondb.PersistenceHelper;
import com.fp.persistence.pcustomer.gene.TcustPersonDetail;
import com.fp.persistence.pcustomer.gene.TcustPersonDetailKey;
import com.fp.persistence.pgeneral.acco.TgeneAccount;
import com.fp.persistence.pgeneral.acco.TgeneAccountStatus;
import com.fp.persistence.pgeneral.acco.TgeneAccountStatusKey;
import com.fp.persistence.pgeneral.gene.TgeneBranch;
import com.fp.persistence.pgeneral.gene.TgeneBranchKey;
import com.fp.persistence.pgeneral.gene.TgeneCurrency;
import com.fp.persistence.pgeneral.gene.TgeneOffice;
import com.fp.persistence.pgeneral.gene.TgeneOfficeKey;
import com.fp.persistence.pgeneral.product.TgeneModule;
import com.fp.persistence.pgeneral.product.TgeneProductKey;
import com.fp.persistence.pgeneral.product.TgeneSubProduct;
import com.fp.persistence.pgeneral.product.TgeneSubProductKey;
import com.fp.persistence.pgeneral.safe.TsafeUserDetail;
import javax.persistence.Query;

public class ProductsByClient extends QueryRule {

    @Override
    public QueryRequest process(QueryRequest pQueryRequest) throws Exception {
        Response response = pQueryRequest.getResponse();
        QueryBean queryBean = (QueryBean) pQueryRequest.get("TCUSTPERSONDETAIL");
        Integer personcode = Integer.valueOf(queryBean.getCriteriaValue("pk.personcode").toString());
        List<TgeneAccount> ldata = TgeneAccount.find(PersistenceHelper.getEntityManager(), pQueryRequest.getCompany(), personcode);
        this.fillResponse(response, pQueryRequest.getUser(), ldata);
        return pQueryRequest;
    }

    private void fillResponse(Response response, String usercode, List<TgeneAccount> ldata) throws Exception {
        List<Map<String, Object>> lresult = new ArrayList<Map<String, Object>>();
        for (TgeneAccount obj : ldata) {
            Map<String, Object> m = this.processBYAccount(obj, usercode);
            lresult.add(m);
        }
        response.put("datos", lresult);
    }

    private Map<String, Object> processBYAccount(TgeneAccount tgeneAccount, String usercode) throws Exception {
        Map<String, Object> m = new HashMap<String, Object>();
        m.put("branch", this.getBranchName(tgeneAccount)); //nombre de la sucursal
        m.put("office", this.getOfficeName(tgeneAccount)); //nombre de la oficiana
        m.put("descmodule", this.getModuleName(tgeneAccount)); //nombre del módulo
        m.put("product", this.getProductName(tgeneAccount)); //nombre del producto
        m.put("subproduct", this.getSubProductName(tgeneAccount)); //nombre del subproducto
        m.put("currency", this.getCurrencyName(tgeneAccount)); //nombre de la moneda
        m.put("executive", this.getExecutiveName(tgeneAccount, usercode)); //nombre del ejecutivo
        m.put("operation", tgeneAccount.getPk().getAccount()); //númeo de operación
        m.put("operationstatus", tgeneAccount.getAccountstatuscode()); //código de estado de operación
        TgeneAccountStatusKey tgeneAccountStatusKey = new TgeneAccountStatusKey(tgeneAccount.getModulecode(), tgeneAccount.getAccountstatuscode());
        TgeneAccountStatus tgeneAccountStatus = TgeneAccountStatus.find(PersistenceHelper.getEntityManager(), tgeneAccountStatusKey);
        m.put("operationdesc", tgeneAccountStatus.getDescription()); //código de estado de operación
        m.put("account", tgeneAccount.getPk().getAccount()); //numero de cuenta
        m.put("company", tgeneAccount.getPk().getCompany()); //numero de compania
        m.put("module", tgeneAccount.getModulecode()); //numero de módulo
        return m;
    }

    /**
     * Metodo que entrega el nombre de la sucursal a la que pertenece la cuenta.
     *
     * @param tgeneAccount Datos generales de la cuenta.
     * @return String
     * @throws Exception
     */
    private String getBranchName(TgeneAccount tgeneAccount) throws Exception {
        String branch = "";
        if (tgeneAccount.getBranchcode() != null && tgeneAccount.getPk().getCompany() != null) {
            TgeneBranchKey key = new TgeneBranchKey(tgeneAccount.getBranchcode(), tgeneAccount.getPk().getCompany());
            if (key != null) {
                TgeneBranch b = TgeneBranch.find(PersistenceHelper.getEntityManager(), key);
                branch = b.getDescription();
            }
        }
        return branch;
    }

    /**
     * Metodo que entrega el nombre de la oficina a la que pertenece la cuenta.
     *
     * @param tgeneAccount Datos generales de la cuenta.
     * @return String
     * @throws Exception
     */
    private String getOfficeName(TgeneAccount tgeneAccount) throws Exception {
        String office = "";
        if (tgeneAccount.getOfficecode() != null && tgeneAccount.getBranchcode() != null && tgeneAccount.getPk().getCompany() != null) {
            TgeneOfficeKey key = new TgeneOfficeKey(tgeneAccount.getOfficecode(), tgeneAccount.getBranchcode(), tgeneAccount.getPk().getCompany());
            if (key != null) {
                TgeneOffice o = TgeneOffice.find(PersistenceHelper.getEntityManager(), key);
                office = o.getDescription();
            }
        }
        return office;
    }

    /**
     * Metodo que entrega el nombre del módulo a la que pertenece la cuenta.
     *
     * @param tgeneAccount Datos generales de la cuenta.
     * @return String
     * @throws Exception
     */
    private String getModuleName(TgeneAccount tgeneAccount) throws Exception {
        String modul = "";
        if (tgeneAccount.getModulecode() != null) {
            TgeneModule mo = TgeneModule.find(PersistenceHelper.getEntityManager(), tgeneAccount.getModulecode());
            modul = mo.getDescription();
        }
        return modul;
    }

    /**
     * Metodo que entrega el nombre del producto a la que pertenece la cuenta.
     *
     * @param tgeneAccount Datos generales de la cuenta.
     * @return String
     * @throws Exception
     */
    private String getProductName(TgeneAccount tgeneAccount) throws Exception {
        String product = "";
        if (tgeneAccount.getModulecode() != null && tgeneAccount.getProductcode() != null) {
            TgeneProductKey key = new TgeneProductKey(tgeneAccount.getModulecode(), tgeneAccount.getProductcode());
            if (key != null) {
                TgeneProduct p = TgeneProduct.find(PersistenceHelper.getEntityManager(), key);
                product = p.getDescription();
            }
        }
        return product;
    }

    /**
     * Metodo que entrega el nombre del subproducto a la que pertenece la
     * cuenta.
     *
     * @param tgeneAccount Datos generales de la cuenta.
     * @return String
     * @throws Exception
     */
    private String getSubProductName(TgeneAccount tgeneAccount) throws Exception {
        String subprod = "";
        if (tgeneAccount.getModulecode() != null && tgeneAccount.getProductcode() != null && tgeneAccount.getSubproductcode() != null) {
            TgeneSubProductKey key = new TgeneSubProductKey(tgeneAccount.getModulecode(), tgeneAccount.getProductcode(), tgeneAccount.getSubproductcode());
            if (key != null) {
                TgeneSubProduct sp = TgeneSubProduct.find(PersistenceHelper.getEntityManager(), key);
                subprod = sp.getDescription();
            }
        }
        return subprod;
    }

    /**
     * Metodo que entrega el nombre de la moneda a la que pertenece la cuenta.
     *
     * @param tgeneAccount Datos generales de la cuenta.
     * @return String
     * @throws Exception
     */
    private String getCurrencyName(TgeneAccount tgeneAccount) throws Exception {
        String curre = "";
        if (tgeneAccount.getCurrencycode() != null) {
            TgeneCurrency c = TgeneCurrency.find(PersistenceHelper.getEntityManager(), tgeneAccount.getCurrencycode());
            curre = c.getDescription();
        }
        return curre;
    }

    /**
     * Metodo que entrega el nombre del ejecutivo a la que pertenece la cuenta.
     *
     * @param tgeneAccount Datos generales de la cuenta.
     * @param response
     * @return
     * @throws Exception
     */
    private String getExecutiveName(TgeneAccount tgeneAccount, String usercode) throws Exception {
        TsafeUserDetail ud = null;
        String nombExecuti = "";
        String sql = "from TsafeUserDetail t"
                + " where t.pk.usercode = :usercode"
                + " and t.pk.personcode = :personcode"
                + " and t.pk.dateto = :dateto"
                + " and t.officecode = :officecode";
        if (usercode != null && tgeneAccount.getPersoncode() != null && tgeneAccount.getOfficecode() != null) {
            Query qry = PersistenceHelper.getEntityManager().createQuery(sql);
            qry.setParameter("usercode", usercode);
            qry.setParameter("personcode", tgeneAccount.getPersoncode());
            qry.setParameter("dateto", Constant.getDefaultExpiryDate());
            qry.setParameter("officecode", tgeneAccount.getOfficecode());
            List<Object> obj = qry.getResultList();
            if (obj.size() > 0) {
                ud = (TsafeUserDetail) obj.get(0);
            }
            if (ud != null) {
                TcustPersonDetailKey personKey = new TcustPersonDetailKey(ud.getPk().getPersoncode(), Constant.getDefaultExpiryTimestamp());
                if (personKey != null) {
                    TcustPersonDetail ex = TcustPersonDetail.find(PersistenceHelper.getEntityManager(), personKey);
                    nombExecuti = ex.getName();
                }
            }
        }
        return nombExecuti;
    }
}
