package com.viettel.campaign.repository.ccms_full.impl;

import com.viettel.campaign.config.DataSourceQualify;
import com.viettel.campaign.repository.ccms_full.CustomerRepositoryCustom;
import com.viettel.campaign.utils.DataUtil;
import com.viettel.campaign.utils.HibernateUtil;
import com.viettel.campaign.web.dto.*;
import com.viettel.campaign.web.dto.request_dto.CustomerDetailRequestDTO;
import com.viettel.campaign.web.dto.request_dto.CustomerQueryDTO;
import com.viettel.campaign.web.dto.request_dto.SearchCustomerRequestDTO;
import com.viettel.econtact.filter.UserSession;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.transform.Transformers;
import org.hibernate.type.DateType;
import org.hibernate.type.LongType;
import org.hibernate.type.ShortType;
import org.hibernate.type.StringType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.*;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository
public class CustomerRepositoryImpl implements CustomerRepositoryCustom {

    @Autowired
    @Qualifier(DataSourceQualify.NAMED_JDBC_PARAMETER_TEMPLATE_CCMS_FULL)
    NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    @Override
    public List<CustomerDetailRequestDTO> getCustomerDetailById(Long companySiteId, Long customerListId, Long customerId) {
        List<CustomerDetailRequestDTO> data = new ArrayList<>();
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
        Session session = null;

        try {
            session = sessionFactory.openSession();
            session.beginTransaction();
            StringBuilder sb = new StringBuilder();

            sb.append("select");
            sb.append("    a.COMPANY_SITE_ID companySiteId,");
            sb.append("    a.CUSTOMER_LIST_ID customerListId,");
            sb.append("    a.CUSTOMER_ID customerId,");
            sb.append("    e.TITLE title,");
            sb.append("    f.TYPE type,");
            sb.append("    h.VALUE_COMBOBOX valueCombobox,");
            sb.append("    e.VALUE_CHECKBOX valueCheckbox,");
            sb.append("    e.VALUE_DATE valueDate,");
            sb.append("    e.VALUE_NUMBER valueNumber,");
            sb.append("    e.VALUE_TEXT valueText");
            sb.append(" from CUSTOMER_LIST_MAPPING a");
            sb.append("         left join CUSTOMIZE_FIELD_OBJECT e on a.CUSTOMER_ID = e.OBJECT_ID");
            sb.append("         left join CUSTOMIZE_FIELDS f on e.CUSTOMIZE_FIELDS_ID = f.CUSTOMIZE_FIELD_ID");
            sb.append("         left join (SELECT FIELD_OPTION_VALUE_ID, NAME AS VALUE_COMBOBOX");
            sb.append("                    FROM CUSTOMIZE_FIELD_OPTION_VALUE) h on h.FIELD_OPTION_VALUE_ID = ");
            sb.append(" e.FIELD_OPTION_VALUE_ID");
            sb.append(" where 1 = 1");
            sb.append("  and a.COMPANY_SITE_ID = :p_company_site_id");
            sb.append("  and a.CUSTOMER_LIST_ID = :p_customer_list_id");
            sb.append("  and a.CUSTOMER_ID = :p_customer_id");

            sb.append(" AND e.FUNCTION_CODE = 'CUSTOMER'");

            SQLQuery query = session.createSQLQuery(sb.toString());

            query.setParameter("p_company_site_id", companySiteId);
            query.setParameter("p_customer_list_id", customerListId);
            query.setParameter("p_customer_id", customerId);
            query.addScalar("companySiteId", new LongType());
            query.addScalar("customerListId", new LongType());
            query.addScalar("customerId", new LongType());
            query.addScalar("title", new StringType());
            query.addScalar("type", new StringType());
            query.addScalar("valueCombobox", new StringType());
            query.addScalar("valueCheckbox", new ShortType());
            query.addScalar("valueDate", new DateType());
            query.addScalar("valueNumber", new LongType());
            query.addScalar("valueText", new StringType());

            query.setResultTransformer(Transformers.aliasToBean(CustomerDetailRequestDTO.class));

            data = query.list();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null) session.close();
        }

        return data;
    }

    @Override
    public List<CustomerCustomDTO> getAllCustomerByParams(SearchCustomerRequestDTO searchCustomerRequestDTO, Pageable pageable) {
        List<CustomerCustomDTO> data = new ArrayList<>();
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

        Session session = null;
        try {
            session = sessionFactory.openSession();
            session.beginTransaction();

            StringBuilder sb = new StringBuilder();

            sb.append("select");
            sb.append("    a.CUSTOMER_LIST_MAPPING_ID customerListMappingId,");
            sb.append("    a.COMPANY_SITE_ID companySiteId,");
            sb.append("    a.CUSTOMER_LIST_ID customerListId,");
            sb.append("    a.CUSTOMER_ID customerId,");
            sb.append("    b.NAME name,");
            sb.append("    b.DESCRIPTION description,");
            sb.append("    b.COMPANY_NAME companyName,");
            sb.append("    b.CUSTOMER_TYPE customerType,");
            sb.append("    b.CURRENT_ADDRESS currentAddress,");
            sb.append("    b.CALL_ALLOWED callAllowed,");
            sb.append("    b.EMAIL_ALLOWED emailAllowed,");
            sb.append("    b.SMS_ALLOWED smsAllowed,");
            sb.append("    b.IPCC_STATUS ipccStatus,");
            sb.append("    c.MOBILE mobileNumber,");
            sb.append("    d.EMAIL email");
            sb.append(" from CUSTOMER_LIST_MAPPING a");
            sb.append("         join CUSTOMER b on a.CUSTOMER_ID = b.CUSTOMER_ID");
            sb.append("         left join (SELECT CUSTOMER_ID, LISTAGG(CONTACT, ', ') WITHIN GROUP (ORDER BY NULL) AS MOBILE");
            sb.append("               FROM CUSTOMER_CONTACT WHERE CONTACT_TYPE = 5 AND STATUS = 1 GROUP BY CUSTOMER_ID) c on b.CUSTOMER_ID = c.CUSTOMER_ID");
            sb.append("         left join (SELECT CUSTOMER_ID, LISTAGG(CONTACT, ', ') WITHIN GROUP (ORDER BY NULL) AS EMAIL");
            sb.append("               FROM CUSTOMER_CONTACT WHERE CONTACT_TYPE = 2 AND STATUS = 1 GROUP BY CUSTOMER_ID) d on b.CUSTOMER_ID = d.CUSTOMER_ID");
            sb.append(" where 1 = 1");
            sb.append("   and a.COMPANY_SITE_ID = :p_company_site_id");
            sb.append("   and a.CUSTOMER_LIST_ID = :p_customer_list_id");

            if (!DataUtil.isNullOrEmpty(searchCustomerRequestDTO.getName())) {
                sb.append(" AND UPPER(b.NAME) LIKE UPPER(:p_name)");
            }
            if (!DataUtil.isNullOrEmpty(searchCustomerRequestDTO.getMobileNumber())) {
                sb.append(" AND UPPER(c.MOBILE) LIKE UPPER(:p_mobile_number)");
            }
            if (!DataUtil.isNullOrEmpty(searchCustomerRequestDTO.getEmail())) {
                sb.append(" AND UPPER(d.EMAIL) LIKE UPPER(:p_email)");
            }
            sb.append(" ORDER BY name DESC");

            SQLQuery query = session.createSQLQuery(sb.toString());

            query.setParameter("p_company_site_id", searchCustomerRequestDTO.getCompanySiteId());
            query.setParameter("p_customer_list_id", searchCustomerRequestDTO.getCustomerListId());

            if (!DataUtil.isNullOrEmpty(searchCustomerRequestDTO.getName())) {
                query.setParameter("p_name", "%" +
                        searchCustomerRequestDTO.getName().trim().replace("\\", "\\\\")
                                .replaceAll("%", "\\%")
                                .replaceAll("_", "\\_")
                        + "%");
            }

            if (!DataUtil.isNullOrEmpty(searchCustomerRequestDTO.getMobileNumber())) {
                query.setParameter("p_mobile_number", "%" +
                        searchCustomerRequestDTO.getMobileNumber().trim().replace("\\", "\\\\")
                                .replaceAll("%", "\\%")
                                .replaceAll("_", "\\_")
                        + "%");
            }

            if (!DataUtil.isNullOrEmpty(searchCustomerRequestDTO.getEmail())) {
                query.setParameter("p_email", "%" +
                        searchCustomerRequestDTO.getEmail().trim().replace("\\", "\\\\")
                                .replaceAll("%", "\\%")
                                .replaceAll("_", "\\_")
                        + "%");
            }

            query.addScalar("customerListMappingId", new LongType());
            query.addScalar("companySiteId", new LongType());
            query.addScalar("customerListId", new LongType());
            query.addScalar("customerId", new LongType());
            query.addScalar("name", new StringType());
            query.addScalar("description", new StringType());
            query.addScalar("companyName", new StringType());
            query.addScalar("customerType", new StringType());
            query.addScalar("currentAddress", new StringType());
            query.addScalar("mobileNumber", new StringType());
            query.addScalar("email", new StringType());

            query.setResultTransformer(Transformers.aliasToBean(CustomerCustomDTO.class));

            if (pageable != null) {
                query.setFirstResult(pageable.getPageNumber() * pageable.getPageSize());
                query.setMaxResults(pageable.getPageSize());
            }

            data = query.list();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null) session.close();
        }

        return data;
    }

    @Override
    public List<CampaignInformationDTO> getCampaignInformation(CampaignCustomerDTO campaignCustomerDTO) {
        List<CampaignInformationDTO> list = new ArrayList<>();
        Map<String, Object> params = new HashMap<>();
        try {
            StringBuilder sb = new StringBuilder();
            sb.append(" with count_customer as (");
            sb.append(" select  campaign_id campaignId,");
            sb.append("         sum(case");
            sb.append("                 when customer_list_id is null then 1");
            sb.append("                     else 0");
            sb.append("                 end) totalIndividual,");
            sb.append("         sum(case");
            sb.append("                 when customer_list_id is not null then 1");
            sb.append("                     else 0");
            sb.append("         end) totalCusInList");
            sb.append(" from campaign_customer");
            sb.append(" group by campaign_id");
            sb.append(" )");
            sb.append(" select b.campaign_id campaignId, nvl(totalIndividual, 0) totalIndividual, nvl(totalCusInList, 0) totalCusInList, b.customer_number campaignCustomer");
            sb.append(" from campaign b");
            sb.append(" left join count_customer a on a.campaignId = b.campaign_id");
            sb.append(" where b.campaign_id = :p_campaign_id");
            params.put("p_campaign_id", campaignCustomerDTO.getCampaignId());
            params.put("p_company_site_id", campaignCustomerDTO.getCompanySiteId());
            list = namedParameterJdbcTemplate.query(sb.toString(), params, BeanPropertyRowMapper.newInstance(CampaignInformationDTO.class));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    @Override
    public List<CustomerDTO> getIndividualCustomerInfo(CampaignCustomerDTO campaignCustomerDTO) {
        List<CustomerDTO> customerList = new ArrayList<>();
        try {
            //String sql = SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_MNG, "search-individual-customer");
            // BuildMyString.com generated code. Please enjoy your string responsibly.

            StringBuilder sb = new StringBuilder();

            sb.append("with cusPhone as (");
            sb.append(" select customer_id cusId,");
            sb.append(" listagg(contact, ', ') within group (order by create_date desc) phone");
            sb.append(" from customer_contact cc");
            sb.append(" where cc.contact_type = 5");
            sb.append(" and status = 1 ");
            sb.append("  group by customer_id");
            sb.append(" ), cusEmail as (");
            sb.append(" select customer_id cusId,");
            sb.append(" listagg(contact , ', ') within group(order by create_date desc) email");
            sb.append(" from customer_contact cc");
            sb.append(" where cc.contact_type = 2");
            sb.append(" and status = 1 ");
            sb.append("  group by customer_id");
            sb.append(" )," +
                    "cusInCampaign as (" +
                    "select * from campaign_customer " +
                    "where campaign_id = :p_campaign_id " +
                    "and company_site_id = :p_company_site_id " +
                    "and customer_list_id is null " +
                    "and in_campaign_status = 1");
            sb.append(" ), datas as (");
            sb.append(" select c.customer_id customerId,");
            sb.append(" c.name,");
            sb.append(" cP.phone mobileNumber,");
            sb.append(" cE.email,");
            sb.append(" c.customer_type customerType,");
            sb.append(" c.company_name companyName,");
            sb.append(" c.current_address currentAddress,");
            sb.append(" c.description,");
            sb.append(" c.ipcc_status ipccStatus,");
            sb.append(" c.call_allowed customerDnc");
            sb.append(" from customer c");
            sb.append(" inner join cusInCampaign cc on c.customer_id = cc.customer_id");
            sb.append(" left join cusPhone cP on c.customer_id = cP.cusId");
            sb.append(" left join cusEmail cE on c.customer_id = cE.cusId");
            sb.append(" )");
            sb.append(" select * from");
            sb.append(" (");
            sb.append("    select a.*, rownum r__");
            sb.append("    from");
            sb.append("    (");
            sb.append("        select * from datas");
            sb.append("        order by UPPER(datas.name)");
            sb.append("    ) a");
            sb.append("    where rownum < ((:p_page_number * :p_page_size) + 1 )");

            sb.append(" )");
            sb.append(" where r__ >= (((:p_page_number-1) * :p_page_size) + 1)");

            Map<String, Object> param = new HashMap<>();
            param.put("p_page_number", campaignCustomerDTO.getPage());
            param.put("p_page_size", campaignCustomerDTO.getPageSize());
            param.put("p_campaign_id", campaignCustomerDTO.getCampaignId());
            param.put("p_company_site_id", campaignCustomerDTO.getCompanySiteId());
            customerList = namedParameterJdbcTemplate.query(sb.toString(), param, new BeanPropertyRowMapper<>(CustomerDTO.class));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return customerList;
    }

    @Override
    public List<CustomerListDTO> getCustomerListInfo(CampaignCustomerDTO campaignCustomerDTO) {
        List<CustomerListDTO> customerList = new ArrayList<>();
        try {
            //String sql = SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_MNG, "search-customer-list-info-from-customer-list");
            // BuildMyString.com generated code. Please enjoy your string responsibly.

            StringBuilder sb = new StringBuilder();

            sb.append(" with totalCustomer as (");
            sb.append(" select clm.customer_list_id,");
            sb.append(" clm.company_site_id,");
            sb.append(" count(clm.customer_id) total");
            sb.append(" from customer_list_mapping clm");
            sb.append(" inner join customer c on clm.customer_id = c.customer_id");
            sb.append(" where c.status = 1");
            sb.append(" group by clm.customer_list_id,clm.company_site_id");
            sb.append(" ), customerInteractive as (");
            sb.append(" select customer_list_id,");
            sb.append(" company_site_id,");
            sb.append(" count(customer_id) tt");
            sb.append(" from campaign_customer where campaign_id = :p_campaign_id and status <> 0");
            sb.append(" group by customer_list_id, company_site_id");
            sb.append(" ), customerNotInteractive as (");
            sb.append(" select customer_list_id,");
            sb.append(" company_site_id,");
            sb.append(" count(customer_id) ktt");
            sb.append(" from campaign_customer where campaign_id = :p_campaign_id and status = 0");
            sb.append(" and in_campaign_status = 1");
            sb.append(" group by customer_list_id, company_site_id");
            sb.append(" ), datas as (");
            sb.append(" select customer_list_code customerListCode,");
            sb.append(" customer_list_name customerListName,");
            sb.append(" nvl(total, 0) totalCusInList,");
            sb.append(" nvl(tt, 0) totalCusInteract,");
            sb.append(" nvl(ktt, 0) totalCusNotInteract");
            sb.append(" from customer_list cl");
            sb.append(" left join totalCustomer tc on (cl.customer_list_id = tc.customer_list_id and cl.company_site_id = tc.company_site_id)");
            sb.append(" left join customerInteractive ci on (cl.customer_list_id = ci.customer_list_id and cl.company_site_id = ci.company_site_id)");
            sb.append(" left join customerNotInteractive cni on (cl.customer_list_id = cni.customer_list_id and cl.company_site_id = cni.company_site_id)");
            sb.append(" where cl.company_site_id = :p_company_site_id");
            sb.append(" )");
            sb.append(" select * from");
            sb.append(" (");
            sb.append("    select a.*, rownum r__");
            sb.append("    from");
            sb.append("    (");
            sb.append("        select * from datas");
            sb.append("        order by customerListCode");
            sb.append("    ) a");
            sb.append("    where rownum < ((:p_page_number * :p_page_size) + 1 )");
            sb.append(" )");
            sb.append(" where r__ >= (((:p_page_number-1) * :p_page_size) + 1)");


            Map<String, Object> param = new HashMap<>();
            param.put("p_campaign_id", campaignCustomerDTO.getCampaignId());
            param.put("p_company_site_id", campaignCustomerDTO.getCompanySiteId());
            param.put("p_page_number", campaignCustomerDTO.getPage());
            param.put("p_page_size", campaignCustomerDTO.getPageSize());
            customerList = namedParameterJdbcTemplate.query(sb.toString(), param, new BeanPropertyRowMapper<>(CustomerListDTO.class));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return customerList;
    }

    @Override
    public List<CustomerDTO> getCustomizeFields(CampaignCustomerDTO campaignCustomerDTO, UserSession userSession, Pageable pageable) {
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
        List<CustomerDTO> data = new ArrayList<>();

        Session session = sessionFactory.openSession();
        session.beginTransaction();
        Map<String, String> requestCustomer = new HashMap<>();
        requestCustomer.put("-1", "c.code");
        requestCustomer.put("-2", "c.name");
        requestCustomer.put("-3", "c.company_name");
        requestCustomer.put("-4", "c.gender");
        requestCustomer.put("-5", "c.current_address");
        requestCustomer.put("-6", "c.place_of_birth");
        requestCustomer.put("-7", "c.date_of_birth");
        requestCustomer.put("-8", "cc.contact");
        requestCustomer.put("-9", "cc2.contact");
        requestCustomer.put("-10", "c.username");
        requestCustomer.put("-11", "c.customer_type");
        requestCustomer.put("-12", "c.area_code");
        requestCustomer.put("-13", "c.call_allowed");
        requestCustomer.put("-14", "c.email_allowed");
        requestCustomer.put("-15", "c.sms_allowed");
        requestCustomer.put("-16", "c.ipcc_status");


        try {
            StringBuilder sb = new StringBuilder();

            sb.append("select distinct c.customer_id customerId,");
            sb.append("    C.NAME name,");
            sb.append("    cc.CONTACT mobileNumber,");
            sb.append("    cc2.CONTACT email,");
            sb.append("    c.customer_type customerType,");
            sb.append("    C.COMPANY_NAME companyName,");
            sb.append("    c.current_address currentAddress,");
            sb.append("    c.Description description");
            sb.append("    FROM CUSTOMER C");
            sb.append("         left join (SELECT CUSTOMER_ID, LISTAGG(CONTACT, ', ') WITHIN GROUP (ORDER BY ");
            sb.append(" NULL) AS CONTACT");
            sb.append("               FROM CUSTOMER_CONTACT WHERE CONTACT_TYPE = 5 AND STATUS = 1 GROUP BY ");
            sb.append(" CUSTOMER_ID) cc on c.CUSTOMER_ID = cc.CUSTOMER_ID");
            sb.append("         left join (SELECT CUSTOMER_ID, LISTAGG(CONTACT, ', ') WITHIN GROUP (ORDER BY ");
            sb.append(" NULL) AS CONTACT");
            sb.append("               FROM CUSTOMER_CONTACT WHERE CONTACT_TYPE = 2 AND STATUS = 1 GROUP BY ");
            sb.append(" CUSTOMER_ID) cc2 on cc2.CUSTOMER_ID = c.CUSTOMER_ID ");
            sb.append(" left join customize_field_object cfo on c.customer_id = cfo.object_id and cfo.status = 1");
            sb.append("  AND C.STATUS = 1");
            sb.append("   AND C.customer_id not in (select customer_id from campaign_customer where campaign_id = :p_campaign_id) ");
            sb.append(" where 1 = 1  AND C.STATUS = 1 AND C.SITE_ID = :p_site_id ");

            List<CustomerQueryDTO> customerDTOList = campaignCustomerDTO.getListQuery();
            if (customerDTOList.get(0).getField() > 0) {// field dong
                switch (customerDTOList.get(0).getType()) {
                    case "combobox":
                        sb.append("and (cfo.customize_fields_id =" + customerDTOList.get(0).getField() + " and cfo.field_option_value_id " + customerDTOList.get(0).getOperator() + " " + customerDTOList.get(0).getCondition() + ")");
                        break;
                    case "text":
                        if ("like".equals(customerDTOList.get(0).getOperator()) || "not like".equals(customerDTOList.get(0).getOperator())) {
                            sb.append("and (cfo.customize_fields_id =" + customerDTOList.get(0).getField() + " and upper(cfo.value_text) " + customerDTOList.get(0).getOperator() + " '%" + customerDTOList.get(0).getCondition().trim().replace("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_").toUpperCase() + "%'");
                        } else {
                            sb.append("and (cfo.customize_fields_id =" + customerDTOList.get(0).getField() + " and cfo.value_text " + customerDTOList.get(0).getOperator() + " '" + customerDTOList.get(0).getCondition().trim().replace("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_") + "'");
                        }
                        if ("not like".equals(customerDTOList.get(0).getOperator()) || "<>".equals(customerDTOList.get(0).getOperator())) {
                            sb.append(" or cfo.value_text is null");
                        }
                        sb.append(" )");
                        break;
                    case "date":
                        sb.append("and (cfo.customize_fields_id =" + customerDTOList.get(0).getField() + " and (cfo.value_date +" + campaignCustomerDTO.getTimezoneOffset() + "/24)" + customerDTOList.get(0).getOperator() + " to_date('" + customerDTOList.get(0).getCondition().trim() + "', 'DD/MM/YYYY'))");
                        break;
                    case "number":
                        sb.append("and (cfo.customize_fields_id =" + customerDTOList.get(0).getField() + " and cfo.value_number " + customerDTOList.get(0).getOperator() + " " + customerDTOList.get(0).getCondition() + ")");
                        break;
                    case "checkbox":
                        sb.append("and (cfo.customize_fields_id =" + customerDTOList.get(0).getField() + " and cfo.value_checkbox " + customerDTOList.get(0).getOperator() + " " + ("true".equals(customerDTOList.get(0).getCondition()) ? "1" : "0") + ")");
                        break;
                }
            } else {// field tinh
                if ("like".equals(customerDTOList.get(0).getOperator()) || "not like".equals(customerDTOList.get(0).getOperator())) {
                    sb.append("and (upper(" + requestCustomer.get(customerDTOList.get(0).getField().toString()) + ") " + customerDTOList.get(0).getOperator() + " '%" + customerDTOList.get(0).getCondition().trim().replace("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_").toUpperCase() + "%'");
                } else if (customerDTOList.get(0).getField() == -8 || customerDTOList.get(0).getField() == -9) {
                    sb.append("and (" + requestCustomer.get(customerDTOList.get(0).getField().toString()) + " " + ("=".equals(customerDTOList.get(0).getOperator()) ? "like " : "not like") + " '%" + customerDTOList.get(0).getCondition().trim().replace("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_") + "%'");
                } else if ("text".equals(customerDTOList.get(0).getType())) {
                    if ("=".equals(customerDTOList.get(0).getOperator()) || "<>".equals(customerDTOList.get(0).getOperator())) {
                        sb.append("and (" + requestCustomer.get(customerDTOList.get(0).getField().toString()) + " " + customerDTOList.get(0).getOperator() + " '" + customerDTOList.get(0).getCondition().trim().replace("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_") + "'");
                    } else {
                        sb.append("and (upper(" + requestCustomer.get(customerDTOList.get(0).getField().toString()) + ") " + customerDTOList.get(0).getOperator() + " '%" + customerDTOList.get(0).getCondition().trim().replace("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_").toUpperCase() + "%'");
                    }
                } else {
                    sb.append("and (" + requestCustomer.get(customerDTOList.get(0).getField().toString()) + " " + customerDTOList.get(0).getOperator() + " " + customerDTOList.get(0).getCondition());
                }
                if ("<>".equals(customerDTOList.get(0).getOperator()) || "not like".equals(customerDTOList.get(0).getOperator())) {
                    sb.append(" or " + requestCustomer.get(customerDTOList.get(0).getField().toString()) + " is null ");
                }
                sb.append(" )");
            }
            for (int i = 1; i < campaignCustomerDTO.getListQuery().size(); i++) {
                if (customerDTOList.get(i).getField() < 0) { //Field tinh
                    if ("like".equals(customerDTOList.get(i).getOperator()) || "not like".equals(customerDTOList.get(i).getOperator())) {
                        sb.append(" " + customerDTOList.get(i).getJoin() + "  ("
                                + "upper(" + requestCustomer.get(customerDTOList.get(i).getField().toString()) + ")  "
                                + customerDTOList.get(i).getOperator() + "  "
                                + "'%" + customerDTOList.get(i).getCondition().trim().replace("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_").toUpperCase() + "%'  ");
                    } else if (customerDTOList.get(i).getField() == -8 || customerDTOList.get(i).getField() == -9) {
                        sb.append(" " + customerDTOList.get(i).getJoin() + "  ("
                                + requestCustomer.get(customerDTOList.get(i).getField().toString()) + "  "
                                + ("=".equals(customerDTOList.get(i).getOperator()) ? "like" : "not like") + "  '%"
                                + customerDTOList.get(i).getCondition().replace("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_").toUpperCase() + "%'  ");
                    } else if ("text".equals(customerDTOList.get(i).getType())) {
                        if ("=".equals(customerDTOList.get(i).getOperator()) || "<>".equals(customerDTOList.get(i).getOperator())) {
                            sb.append(" " + customerDTOList.get(i).getJoin() + "  ("
                                    + requestCustomer.get(customerDTOList.get(i).getField().toString()) + "  "
                                    + customerDTOList.get(i).getOperator() + "  '"
                                    + customerDTOList.get(i).getCondition().replace("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_") + "'  ");
                        } else {
                            sb.append(" " + customerDTOList.get(i).getJoin() + "  ("
                                    + "upper(" + requestCustomer.get(customerDTOList.get(i).getField().toString()) + ")  "
                                    + customerDTOList.get(i).getOperator() + "  '%"
                                    + customerDTOList.get(i).getCondition().replace("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_").toUpperCase() + "%'  ");
                        }
                    } else {
                        sb.append(" " + customerDTOList.get(i).getJoin() + "  ("
                                + requestCustomer.get(customerDTOList.get(i).getField().toString()) + "  "
                                + customerDTOList.get(i).getOperator() + "  "
                                + customerDTOList.get(i).getCondition());
                    }
                    if ("not like".equals(customerDTOList.get(i).getOperator()) || "<>".equals(customerDTOList.get(i).getOperator())) {
                        sb.append(" or " + requestCustomer.get(customerDTOList.get(i).getField().toString()) + " is null");
                    }
                    sb.append(" )");
                } else { // Field dong
                    switch (customerDTOList.get(i).getType()) {
                        case "combobox":
                            sb.append(customerDTOList.get(i).getJoin() + " (cfo.customize_fields_id =" + customerDTOList.get(i).getField() + " and cfo.field_option_value_id " + customerDTOList.get(i).getOperator() + " " + customerDTOList.get(i).getCondition() + ")");
                            break;
                        case "text":
                            if ("like".equals(customerDTOList.get(i).getOperator()) || "not like".equals(customerDTOList.get(i).getOperator())) {
                                sb.append(customerDTOList.get(i).getJoin() + " (cfo.customize_fields_id =" + customerDTOList.get(0).getField() + " and upper(cfo.value_text) " + customerDTOList.get(0).getOperator() + " '%" + customerDTOList.get(0).getCondition().trim().replace("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_").toUpperCase() + "%'");
                            } else {
                                sb.append(customerDTOList.get(i).getJoin() + " (cfo.customize_fields_id =" + customerDTOList.get(0).getField() + " and cfo.value_text " + customerDTOList.get(0).getOperator() + " '" + customerDTOList.get(0).getCondition().trim().replace("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_") + "'");
                            }
                            if ("not like".equals(customerDTOList.get(i).getOperator()) || "<>".equals(customerDTOList.get(i).getOperator())) {
                                sb.append(" or cfo.value_text is null ");
                            }
                            sb.append(" )");
                            break;
                        case "date":
                            sb.append(customerDTOList.get(i).getJoin() + " (cfo.customize_fields_id =" + customerDTOList.get(i).getField() + " and (cfo.value_date + " + campaignCustomerDTO.getTimezoneOffset() + "/24)" + customerDTOList.get(i).getOperator() + " to_date('" + customerDTOList.get(i).getCondition().trim() + "', 'DD/MM/YYYY'))");
                            break;
                        case "number":
                            sb.append(customerDTOList.get(i).getJoin() + " (cfo.customize_fields_id =" + customerDTOList.get(i).getField() + " and cfo.value_number " + customerDTOList.get(i).getOperator() + " " + customerDTOList.get(i).getCondition() + ")");
                            break;
                        case "checkbox":
                            sb.append(customerDTOList.get(i).getJoin() + " (cfo.customize_fields_id =" + customerDTOList.get(i).getField() + " and cfo.value_checkbox " + customerDTOList.get(i).getOperator() + " " + ("true".equals(customerDTOList.get(i).getCondition()) ? "1" : "0") + ")");
                            break;
                    }
                }


            }
            SQLQuery query = session.createSQLQuery(sb.toString());
            query.addScalar("name", new StringType());
            query.addScalar("customerId", new LongType());
            query.addScalar("mobileNumber", new StringType());
            query.addScalar("email", new StringType());
            query.addScalar("customerType", new LongType());
            query.addScalar("companyName", new StringType());
            query.addScalar("currentAddress", new StringType());
            query.addScalar("description", new StringType());

            query.setParameter("p_campaign_id", campaignCustomerDTO.getCampaignId());
            query.setParameter("p_site_id", userSession.getSiteId());

            query.setResultTransformer(Transformers.aliasToBean(CustomerDTO.class));

            if (pageable != null) {
                query.setFirstResult(pageable.getPageNumber() * pageable.getPageSize());
                query.setMaxResults(pageable.getPageSize());
            }

            data = query.list();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            session.close();
        }

        return data;
    }
}
