package com.viettel.campaign.service.impl;

import com.viettel.campaign.mapper.CampaignAgentMapper;
import com.viettel.campaign.config.DataSourceQualify;
import com.viettel.campaign.model.acd_full.Agents;
import com.viettel.campaign.model.ccms_full.CampaignAgent;
import com.viettel.campaign.repository.acd_full.AgentsRepository;
import com.viettel.campaign.repository.ccms_full.CampaignAgentRepository;
import com.viettel.campaign.service.AgentsService;
import com.viettel.campaign.utils.Constants;
import com.viettel.campaign.utils.DataUtil;
import com.viettel.campaign.utils.HibernateUtil;
import com.viettel.campaign.utils.SQLBuilder;
import com.viettel.campaign.web.dto.CampaignAgentDTO;
import com.viettel.campaign.web.dto.ResultDTO;
import com.viettel.campaign.web.dto.VSAUsersDTO;
import com.viettel.campaign.web.dto.request_dto.CampaignAgentRequestDTO;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.transform.Transformers;
import org.hibernate.type.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
public class AgentsServiceImpl implements AgentsService {

    @Autowired
    AgentsRepository agentsRepository;

    @Autowired
    CampaignAgentRepository campaignAgentRepository;

    @Override
    public ResultDTO getAgentsByAgentId(String agentId) {
        ResultDTO result = new ResultDTO();

        try {
            Agents data = agentsRepository.findByAgentId(agentId);

            if (data != null) {
                result.setErrorCode(Constants.ApiErrorCode.SUCCESS);
                result.setDescription("agents data");
                result.setData(data);

            } else {
                result.setErrorCode(Constants.ApiErrorCode.ERROR);
                result.setDescription("agents data null");
            }
        } catch (Exception e) {
            // e.printStackTrace();
        }

        return result;
    }

    @Override
    @Transactional(DataSourceQualify.ACD_FULL)
    public ResultDTO getAllAgentByCompanySiteId(int page, int pageSize, Long companySiteId, Long campaignId) {
        ResultDTO resultDTO = new ResultDTO();
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

        Session session = null;

        if (DataUtil.isNullOrZero(companySiteId)) {
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
            return resultDTO;
        }

        try {
            session = sessionFactory.openSession();
            session.beginTransaction();
//            StringBuilder  sb = new StringBuilder();
//             sb.append(SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_MNG, "campaign-agents-by-params"));

            StringBuilder sb = new StringBuilder();

            sb.append("SELECT");
            sb.append("    vu.USER_ID         userId,");
            sb.append("    vu.USER_NAME       userName,");
            sb.append("    vu.STATUS          status,");
            sb.append("    vu.FULL_NAME       fullName,");
            sb.append("    vu.COMPANY_SITE_ID companySiteId,");
            sb.append("    r.ROLE_CODE       roleCode");
            sb.append(" FROM VSA_USERS vu");
            sb.append(" INNER JOIN USER_ROLE ur on vu.USER_ID = ur.USER_ID");
            sb.append(" INNER JOIN ROLE r on ur.ROLE_ID = r.ROLE_ID");
            sb.append(" WHERE 1 = 1");
            sb.append(" AND vu.COMPANY_SITE_ID = :p_company_site_id");
            sb.append(" AND vu.STATUS = 1");
            sb.append(" AND r.ROLE_CODE IN ('AGENT', 'SUPERVISOR')");
            sb.append(" AND vu.USER_ID NOT IN (SELECT vu.USER_ID         userId");
            sb.append("                         FROM VSA_USERS vu");
            sb.append("                             LEFT JOIN CAMPAIGN_AGENT ca on vu.USER_ID = ca.AGENT_ID");
            sb.append("                             INNER JOIN USER_ROLE ur on vu.USER_ID = ur.USER_ID");
            sb.append("                             INNER JOIN ROLE r on ur.ROLE_ID = r.ROLE_ID");
            sb.append("                         WHERE 1 = 1");
            sb.append("                            AND vu.COMPANY_SITE_ID = :p_company_site_id");
            sb.append("                            AND vu.STATUS = 1");
            sb.append("                            AND ca.CAMPAIGN_ID = :p_campaign_id");
            sb.append("                            AND r.ROLE_CODE IN ('AGENT', 'SUPERVISOR'))");
            sb.append(" ORDER BY UPPER(vu.FULL_NAME)");

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

            query.setParameter("p_company_site_id", companySiteId);
            query.setParameter("p_campaign_id", campaignId);

            query.addScalar("userId", new LongType());
            query.addScalar("userName", new StringType());
            query.addScalar("status", new ShortType());
            query.addScalar("fullName", new StringType());
            query.addScalar("companySiteId", new LongType());
            query.addScalar("roleCode", new StringType());

            query.setResultTransformer(Transformers.aliasToBean(VSAUsersDTO.class));
            int count = 0;
            List<VSAUsersDTO> dtoList = query.list();
            if (dtoList.size() > 0) {
                count = query.list().size();
            }

            Pageable pageable = PageRequest.of(page, pageSize);
            if (pageable != null) {
                query.setFirstResult(pageable.getPageNumber() * pageable.getPageSize());
                query.setMaxResults(pageable.getPageSize());
            }

            List<VSAUsersDTO> data = query.list();
            Page<VSAUsersDTO> dataPage = new PageImpl<>(data, pageable, count);
            resultDTO.setData(dataPage);
            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
        } catch (Exception e) {
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
        } finally {
            if(session != null) session.close();
        }

        return resultDTO;
    }

    @Override
    public ResultDTO getAllAgentSelectedByCompanySiteId(int page, int pageSize, Long companySiteId, Long campaignId) {
        ResultDTO resultDTO = new ResultDTO();
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

        Session session = null;

        if (DataUtil.isNullOrZero(companySiteId)) {
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
            return resultDTO;
        }

        try {
            session = sessionFactory.openSession();
            session.beginTransaction();
//            StringBuilder sb = new StringBuilder();
//            sb.append(SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_MNG, "campaign-agents-by-params"));
            StringBuilder sb = new StringBuilder();


            sb.append("SELECT");
            sb.append("    a.CAMPAIGN_AGENT_ID campaignAgentId,");
            sb.append("    a.FILTER_TYPE filterType,");
            sb.append("    a.COMPANY_SITE_ID companySiteId,");
            sb.append("    b.USER_ID userId,");
            sb.append("    b.USER_NAME userName,");
            sb.append("    b.STATUS status,");
            sb.append("    b.FULL_NAME fullName");

            sb.append(" FROM CAMPAIGN_AGENT a");

            sb.append(" INNER JOIN VSA_USERS b ON a.AGENT_ID = b.USER_ID");
            sb.append(" WHERE 1 = 1");
            sb.append(" AND a.COMPANY_SITE_ID = :p_company_site_id");
            sb.append(" AND a.CAMPAIGN_ID = :p_campaign_id");
            sb.append(" ORDER BY UPPER(b.FULL_NAME)");

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

            query.setParameter("p_company_site_id", companySiteId);
            query.setParameter("p_campaign_id", campaignId);

            query.addScalar("userId", new LongType());
            query.addScalar("userName", new StringType());
            query.addScalar("status", new ShortType());
            query.addScalar("fullName", new StringType());
            query.addScalar("companySiteId", new LongType());
            query.addScalar("filterType", new ShortType());
            query.addScalar("campaignAgentId", new LongType());

            query.setResultTransformer(Transformers.aliasToBean(VSAUsersDTO.class));
            int count = 0;
            List<VSAUsersDTO> dtoList = query.list();
            if (dtoList.size() > 0) {
                count = query.list().size();
            }

            Pageable pageable = PageRequest.of(page, pageSize);
            if (pageable != null) {
                query.setFirstResult(pageable.getPageNumber() * pageable.getPageSize());
                query.setMaxResults(pageable.getPageSize());
            }

            List<VSAUsersDTO> data = query.list();
            Page<VSAUsersDTO> dataPage = new PageImpl<>(data, pageable, count);
            resultDTO.setData(dataPage);
            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
        } catch (Exception e) {
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
        } finally {
            if(session != null) session.close();
        }

        return resultDTO;
    }

    @Override
    public ResultDTO createCampaignAgent(CampaignAgentDTO campaignAgentDTO) {
        ResultDTO resultDTO = new ResultDTO();
        CampaignAgentMapper campaignAgentMapper = new CampaignAgentMapper();
        CampaignAgent campaignAgent = new CampaignAgent();
        try {
            if (campaignAgentDTO != null) {
                // insert
                campaignAgent.setAgentId(campaignAgentDTO.getAgentId());
                campaignAgent.setStatus(0);
                campaignAgent.setReSchedule(0L);
                campaignAgent.setFilterType((short) 0);
                campaignAgent.setCompanySiteId(campaignAgentDTO.getCompanySiteId());
                campaignAgent.setCampaignId(campaignAgentDTO.getCampaignId());

                campaignAgentRepository.save(campaignAgent);

                resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
                resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
            } else {
                resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
                resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
            }
        } catch (Exception e) {
            // e.printStackTrace();
        }

        return resultDTO;
    }

    @Override
    @Transactional(DataSourceQualify.CCMS_FULL)
    public ResultDTO deleteCampaignAgentById(List<Long> campaignAgentId) {
        ResultDTO resultDTO = new ResultDTO();

        try {
            if (campaignAgentId.size() > 0) {
                // delete
                campaignAgentRepository.deleteCampaignAgent(campaignAgentId);

                resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
                resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
            } else {
                resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
                resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
            }
        } catch (Exception e) {
            // e.printStackTrace();
        }

        return resultDTO;
    }

    @Override
    public ResultDTO searchCampaignAgentByName(int page, int pageSize, Long campaignId, Long companySiteId, String userName, String fullName) {
        ResultDTO resultDTO = new ResultDTO();
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

        Session session = null;

        if (DataUtil.isNullOrZero(companySiteId)) {
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
            return resultDTO;
        }

        try {
            session = sessionFactory.openSession();
            session.beginTransaction();
//            StringBuilder sqlStrBuilder = new StringBuilder();
//            sqlStrBuilder.append(SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_MNG, "campaign-agents-by-params"));
            StringBuilder sqlStrBuilder = new StringBuilder();

            sqlStrBuilder.append("SELECT");
            sqlStrBuilder.append("    vu.USER_ID         userId,");
            sqlStrBuilder.append("    vu.USER_NAME       userName,");
            sqlStrBuilder.append("    vu.STATUS          status,");
            sqlStrBuilder.append("    vu.FULL_NAME       fullName,");
            sqlStrBuilder.append("    vu.COMPANY_SITE_ID companySiteId,");
            sqlStrBuilder.append("    r.ROLE_CODE       roleCode");
            sqlStrBuilder.append(" FROM VSA_USERS vu");
            sqlStrBuilder.append(" INNER JOIN USER_ROLE ur on vu.USER_ID = ur.USER_ID");
            sqlStrBuilder.append(" INNER JOIN ROLE r on ur.ROLE_ID = r.ROLE_ID");
            sqlStrBuilder.append(" WHERE 1 = 1");
            sqlStrBuilder.append(" AND vu.COMPANY_SITE_ID = :p_company_site_id");
            sqlStrBuilder.append(" AND vu.STATUS = 1");
            sqlStrBuilder.append(" AND r.ROLE_CODE IN ('AGENT', 'SUPERVISOR')");
            sqlStrBuilder.append(" AND vu.USER_ID NOT IN (SELECT vu.USER_ID");
            sqlStrBuilder.append("                         FROM CAMPAIGN_AGENT ca");
            sqlStrBuilder.append("                             INNER JOIN VSA_USERS vu ON ca.AGENT_ID = vu.USER_ID");
            sqlStrBuilder.append("                         WHERE 1 = 1");
            sqlStrBuilder.append("                            AND ca.COMPANY_SITE_ID = :p_company_site_id");
            sqlStrBuilder.append("                            AND ca.CAMPAIGN_ID = :p_campaign_id)");

            if (!DataUtil.isNullOrEmpty(userName)) {
                sqlStrBuilder.append(" AND UPPER(vu.USER_NAME) LIKE UPPER(:p_user_name)");
            }

            if (!DataUtil.isNullOrEmpty(fullName)) {
                sqlStrBuilder.append(" AND UPPER(vu.FULL_NAME) LIKE UPPER(:p_full_name)");
            }

            sqlStrBuilder.append(" ORDER BY UPPER(vu.FULL_NAME)");

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

            query.setParameter("p_company_site_id", companySiteId);
            query.setParameter("p_campaign_id", campaignId);

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

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

            query.addScalar("userId", new LongType());
            query.addScalar("userName", new StringType());
            query.addScalar("status", new ShortType());
            query.addScalar("fullName", new StringType());
            query.addScalar("companySiteId", new LongType());
            query.addScalar("roleCode", new StringType());

            query.setResultTransformer(Transformers.aliasToBean(VSAUsersDTO.class));
            int count = 0;
            List<VSAUsersDTO> dtoList = query.list();
            if (dtoList.size() > 0) {
                count = query.list().size();
            }

            Pageable pageable = PageRequest.of(page, pageSize);
            if (pageable != null) {
                query.setFirstResult(pageable.getPageNumber() * pageable.getPageSize());
                query.setMaxResults(pageable.getPageSize());
            }

            List<VSAUsersDTO> data = query.list();
            Page<VSAUsersDTO> dataPage = new PageImpl<>(data, pageable, count);
            resultDTO.setData(dataPage);
            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
        } catch (Exception e) {
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
        } finally {
            if(session != null) session.close();
        }

        return resultDTO;
    }

    @Override
    public ResultDTO searchCampaignAgentSelectByName(int page, int pageSize, Long companySiteId, Long campaignId, String userName, String fullName) {
        ResultDTO resultDTO = new ResultDTO();
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

//        Session session = sessionFactory.openSession();
//        session.beginTransaction();

        Session session = null;

        if (DataUtil.isNullOrZero(companySiteId)) {
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
            return resultDTO;
        }

        try {
            session = sessionFactory.openSession();
            session.beginTransaction();
//            StringBuilder sb = new StringBuilder();
//            sb.append(SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_MNG, "campaign-agents-by-params"));
            StringBuilder sb = new StringBuilder();


            sb.append("SELECT");
            sb.append("    a.CAMPAIGN_AGENT_ID campaignAgentId,");
            sb.append("    a.FILTER_TYPE filterType,");
            sb.append("    a.COMPANY_SITE_ID companySiteId,");
            sb.append("    b.USER_ID userId,");
            sb.append("    b.USER_NAME userName,");
            sb.append("    b.STATUS status,");
            sb.append("    b.FULL_NAME fullName");

            sb.append(" FROM CAMPAIGN_AGENT a");

            sb.append(" INNER JOIN VSA_USERS b ON a.AGENT_ID = b.USER_ID");
            sb.append(" WHERE 1 = 1");
            sb.append(" AND a.COMPANY_SITE_ID = :p_company_site_id");
            sb.append(" AND a.CAMPAIGN_ID = :p_campaign_id");

            if (!DataUtil.isNullOrEmpty(userName)) {
                sb.append(" AND UPPER(b.USER_NAME) LIKE UPPER(:p_user_name)");
            }

            if (!DataUtil.isNullOrEmpty(fullName)) {
                sb.append(" AND UPPER(b.FULL_NAME) LIKE UPPER(:p_full_name)");
            }

            sb.append(" ORDER BY UPPER(b.FULL_NAME)");

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

            query.setParameter("p_company_site_id", companySiteId);
            query.setParameter("p_campaign_id", campaignId);

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

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

            query.addScalar("userId", new LongType());
            query.addScalar("userName", new StringType());
            query.addScalar("status", new ShortType());
            query.addScalar("fullName", new StringType());
            query.addScalar("companySiteId", new LongType());
            query.addScalar("filterType", new ShortType());
            query.addScalar("campaignAgentId", new LongType());

            query.setResultTransformer(Transformers.aliasToBean(VSAUsersDTO.class));
            int count = 0;
            List<VSAUsersDTO> dtoList = query.list();
            if (dtoList.size() > 0) {
                count = query.list().size();
            }

            Pageable pageable = PageRequest.of(page, pageSize);
            if (pageable != null) {
                query.setFirstResult(pageable.getPageNumber() * pageable.getPageSize());
                query.setMaxResults(pageable.getPageSize());
            }

            List<VSAUsersDTO> data = query.list();
            Page<VSAUsersDTO> dataPage = new PageImpl<>(data, pageable, count);
            resultDTO.setData(dataPage);
            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
        } catch (Exception e) {
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
        } finally {
            if(null != session){
                session.close();
            }
        }

        return resultDTO;
    }

    @Override
    public ResultDTO createMultipleCampaignAgent(CampaignAgentRequestDTO campaignAgentRequestDTO) {
        ResultDTO resultDTO = new ResultDTO();
//        CampaignAgentMapper campaignAgentsMapper = new CampaignAgentMapper();
        List<CampaignAgent> campaignAgentList = new ArrayList<>();
        try {
            if (campaignAgentRequestDTO != null) {
                for (int i = 0; i < campaignAgentRequestDTO.getAgentId().size(); i++) {
                    CampaignAgent campaignAgent = new CampaignAgent();
                    campaignAgent.setAgentId(campaignAgentRequestDTO.getAgentId().get(i));
                    campaignAgent.setStatus(0);
                    campaignAgent.setReSchedule(0L);
                    campaignAgent.setFilterType((short) 0);
                    campaignAgent.setCompanySiteId(campaignAgentRequestDTO.getCompanySiteId());
                    campaignAgent.setCampaignId(campaignAgentRequestDTO.getCampaignId());
                    campaignAgentList.add(campaignAgent);
                }
                // insert
//                campaignAgent = campaignAgentsMapper.toPersistenceBean();
                campaignAgentRepository.saveAll(campaignAgentList);

                resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
                resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
            } else {
                resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
                resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
            }
        } catch (Exception e) {
            // e.printStackTrace();
        }

        return resultDTO;
    }

    @Override
    public ResultDTO updateAgent(CampaignAgentDTO campaignAgentDTO) {
        ResultDTO resultDTO = new ResultDTO();
        try {
            if (campaignAgentDTO != null) {
                Agents agents = new Agents();
                agents.setAgentId(campaignAgentDTO.getAgentId().toString());
                agents.setCampaignSystemStatus("AVAILABLE");
                agentsRepository.save(agents);

                resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
                resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);

            } else {
                resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
                resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
            }
        } catch (Exception e) {
            // e.printStackTrace();
        }

        return resultDTO;
    }
}
