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

import com.viettel.campaign.repository.ccms_full.CustomerRepositoryCustom;
import com.viettel.campaign.utils.Constants;
import com.viettel.campaign.utils.DataUtil;
import com.viettel.campaign.utils.HibernateUtil;
import com.viettel.campaign.web.dto.CustomerCustomDTO;
import com.viettel.campaign.web.dto.ResultDTO;
import com.viettel.campaign.web.dto.request_dto.CustomerDetailRequestDTO;
import com.viettel.campaign.web.dto.request_dto.SearchCustomerRequestDTO;
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.data.domain.*;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;

@Repository
public class CustomerRepositoryImpl implements CustomerRepositoryCustom {
    @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;
    }
}
