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) {
        ResultDTO resultDTO = new ResultDTO();
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

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

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

        try {
//            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.USER_ID userId,");
            sb.append("    a.USER_NAME userName,");
            sb.append("    a.STATUS status,");
            sb.append("    a.FULL_NAME fullName,");
            sb.append("    a.USER_TYPE_ID userTypeId,");
            sb.append("    a.CREATE_DATE createDate,");
            sb.append("    a.DESCRIPTION description,");
            sb.append("    a.STAFF_CODE staffCode,");
            sb.append("    a.MANAGER_ID managerId,");
            sb.append("    a.LOCATION_ID locationId,");
            sb.append("    a.DEPT_ID deptId,");
            sb.append("    a.DEPT_LEVEL deptLevel,");
            sb.append("    a.POS_ID posId,");
            sb.append("    a.DEPT_NAME deptName,");
            sb.append("    a.GROUP_ID groupId,");
            sb.append("    a.SITE_ID siteId,");
            sb.append("    a.COMPANY_SITE_ID companySiteId,");
            sb.append("    a.AGENT_TYPE agentType,");
            sb.append("    a.MOBILE_NUMBER mobileNumber,");
            sb.append("    a.FACEBOOK_ID facebookId,");
            sb.append("    a.LOGIN_TYPE loginType,");
            sb.append("    a.GOOGLE_ID googleId,");
            sb.append("    a.EMAIL email,");
            sb.append("    a.AVAILABLE_TICKET availableTicket,");
            sb.append("    a.USER_KAZOO_ID userKazooId,");
            sb.append("    b.FILTER_TYPE filterType");
            sb.append(" FROM VSA_USERS a");

            sb.append(" LEFT JOIN CAMPAIGN_AGENT b on a.USER_ID = b.AGENT_ID");
            sb.append(" WHERE 1 = 1");
            sb.append(" AND a.COMPANY_SITE_ID = :p_company_site_id");
            sb.append(" AND b.AGENT_ID IS NULL");
            sb.append(" ORDER BY a.FULL_NAME ASC");

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

            query.setParameter("p_company_site_id", companySiteId);

            query.addScalar("userId", new LongType());
            query.addScalar("userName", new StringType());
            query.addScalar("status", new ShortType());
            query.addScalar("fullName", new StringType());
            query.addScalar("userTypeId", new LongType());
            query.addScalar("createDate", new DateType());
            query.addScalar("description", new StringType());
            query.addScalar("staffCode", new StringType());
            query.addScalar("managerId", new LongType());
            query.addScalar("locationId", new LongType());
            query.addScalar("deptId", new LongType());
            query.addScalar("deptLevel", new StringType());
            query.addScalar("posId", new LongType());
            query.addScalar("deptName", new StringType());
            query.addScalar("groupId", new LongType());
            query.addScalar("siteId", new LongType());
            query.addScalar("companySiteId", new LongType());
            query.addScalar("agentType", new ShortType());
            query.addScalar("mobileNumber", new StringType());
            query.addScalar("facebookId", new StringType());
            query.addScalar("loginType", new ShortType());
            query.addScalar("googleId", new StringType());
            query.addScalar("email", new StringType());
            query.addScalar("availableTicket", new LongType());
            query.addScalar("userKazooId", new StringType());
            query.addScalar("filterType", new ShortType());

            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 {
            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 = sessionFactory.openSession();
        session.beginTransaction();

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

        try {
//            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.USER_ID userId,");
            sb.append("    a.USER_NAME userName,");
            sb.append("    a.STATUS status,");
            sb.append("    a.FULL_NAME fullName,");
            sb.append("    a.USER_TYPE_ID userTypeId,");
            sb.append("    a.CREATE_DATE createDate,");
            sb.append("    a.DESCRIPTION description,");
            sb.append("    a.STAFF_CODE staffCode,");
            sb.append("    a.MANAGER_ID managerId,");
            sb.append("    a.LOCATION_ID locationId,");
            sb.append("    a.DEPT_ID deptId,");
            sb.append("    a.DEPT_LEVEL deptLevel,");
            sb.append("    a.POS_ID posId,");
            sb.append("    a.DEPT_NAME deptName,");
            sb.append("    a.GROUP_ID groupId,");
            sb.append("    a.SITE_ID siteId,");
            sb.append("    a.COMPANY_SITE_ID companySiteId,");
            sb.append("    a.AGENT_TYPE agentType,");
            sb.append("    a.MOBILE_NUMBER mobileNumber,");
            sb.append("    a.FACEBOOK_ID facebookId,");
            sb.append("    a.LOGIN_TYPE loginType,");
            sb.append("    a.GOOGLE_ID googleId,");
            sb.append("    a.EMAIL email,");
            sb.append("    a.AVAILABLE_TICKET availableTicket,");
            sb.append("    a.USER_KAZOO_ID userKazooId,");
            sb.append("    b.FILTER_TYPE filterType");
            sb.append(" FROM VSA_USERS a");

            sb.append(" RIGHT JOIN CAMPAIGN_AGENT b on a.USER_ID = b.AGENT_ID");
            sb.append(" WHERE 1 = 1");
            sb.append(" AND b.COMPANY_SITE_ID = :p_company_site_id");
            sb.append(" AND b.CAMPAIGN_ID = :p_campaign_id");
            sb.append(" ORDER BY a.FULL_NAME ASC");

            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("userTypeId", new LongType());
            query.addScalar("createDate", new DateType());
            query.addScalar("description", new StringType());
            query.addScalar("staffCode", new StringType());
            query.addScalar("managerId", new LongType());
            query.addScalar("locationId", new LongType());
            query.addScalar("deptId", new LongType());
            query.addScalar("deptLevel", new StringType());
            query.addScalar("posId", new LongType());
            query.addScalar("deptName", new StringType());
            query.addScalar("groupId", new LongType());
            query.addScalar("siteId", new LongType());
            query.addScalar("companySiteId", new LongType());
            query.addScalar("agentType", new ShortType());
            query.addScalar("mobileNumber", new StringType());
            query.addScalar("facebookId", new StringType());
            query.addScalar("loginType", new ShortType());
            query.addScalar("googleId", new StringType());
            query.addScalar("email", new StringType());
            query.addScalar("availableTicket", new LongType());
            query.addScalar("userKazooId", new StringType());
            query.addScalar("filterType", new ShortType());

            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 {
            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 = campaignAgentMapper.toPersistenceBean(campaignAgentDTO);
                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 companySiteId, String userName, String fullName) {
        ResultDTO resultDTO = new ResultDTO();
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

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

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

        try {
//            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("    a.USER_ID userId,");
            sqlStrBuilder.append("    a.USER_NAME userName,");
            sqlStrBuilder.append("    a.STATUS status,");
            sqlStrBuilder.append("    a.FULL_NAME fullName,");
            sqlStrBuilder.append("    a.COMPANY_SITE_ID companySiteId,");
            sqlStrBuilder.append("    b.FILTER_TYPE filterType,");
            sqlStrBuilder.append("    b.CAMPAIGN_AGENT_ID campaignAgentId");
            sqlStrBuilder.append(" FROM VSA_USERS a");
            sqlStrBuilder.append(" LEFT JOIN CAMPAIGN_AGENT b on a.USER_ID = b.AGENT_ID");
            sqlStrBuilder.append(" JOIN USER_ROLE c on a.USER_ID = c.USER_ID");
            sqlStrBuilder.append(" JOIN ROLE d on c.ROLE_ID = d.ROLE_ID");
            sqlStrBuilder.append(" WHERE 1 = 1");
            sqlStrBuilder.append(" AND a.COMPANY_SITE_ID = :p_company_site_id");

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

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

            sqlStrBuilder.append(" AND d.ROLE_CODE IN ('AGENT', 'SUPERVISOR')");
            sqlStrBuilder.append(" AND a.STATUS = 1");
            sqlStrBuilder.append(" AND b.CAMPAIGN_AGENT_ID IS NULL");
            sqlStrBuilder.append(" ORDER BY a.FULL_NAME ASC");

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

            query.setParameter("p_company_site_id", companySiteId);

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

            if (!DataUtil.isNullOrEmpty(fullName)) {
                query.setParameter("p_full_name", "%" +
                        fullName
                                .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("userTypeId", new LongType());
//            query.addScalar("createDate", new DateType());
//            query.addScalar("description", new StringType());
//            query.addScalar("staffCode", new StringType());
//            query.addScalar("managerId", new LongType());
//            query.addScalar("locationId", new LongType());
//            query.addScalar("deptId", new LongType());
//            query.addScalar("deptLevel", new StringType());
//            query.addScalar("posId", new LongType());
//            query.addScalar("deptName", new StringType());
//            query.addScalar("groupId", new LongType());
//            query.addScalar("siteId", new LongType());
            query.addScalar("companySiteId", new LongType());
//            query.addScalar("agentType", new ShortType());
//            query.addScalar("mobileNumber", new StringType());
//            query.addScalar("facebookId", new StringType());
//            query.addScalar("loginType", new ShortType());
//            query.addScalar("googleId", new StringType());
//            query.addScalar("email", new StringType());
//            query.addScalar("availableTicket", new LongType());
//            query.addScalar("userKazooId", new StringType());
            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 {
            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;
    }
}
