package com.viettel.campaign.service.impl;

import com.viettel.campaign.mapper.CampaignAgentsMapper;
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.CampaignAgentsRepository;
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.CampaignAgentsDTO;
import com.viettel.campaign.web.dto.ResultDTO;
import com.viettel.campaign.web.dto.VSAUsersDTO;
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.List;

@Service
public class AgentsServiceImpl implements AgentsService {

    @Autowired
    AgentsRepository agentsRepository;

    @Autowired
    CampaignAgentsRepository campaignAgentsRepository;

    @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 getAllAgentsByCompanySiteId(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 sqlStrBuilder = new StringBuilder();
            sqlStrBuilder.append(SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_MNG, "campaign-agents-by-params"));

            sqlStrBuilder.append(" LEFT JOIN CAMPAIGN_AGENT b on a.USER_ID = b.AGENT_ID");
            sqlStrBuilder.append(" WHERE 1 = 1");
            sqlStrBuilder.append(" AND a.COMPANY_SITE_ID = :p_company_site_id");
            sqlStrBuilder.append(" AND b.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);

            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 getAllAgentsSelectedByCompanySiteId(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 sqlStrBuilder = new StringBuilder();
            sqlStrBuilder.append(SQLBuilder.getSqlQueryById(SQLBuilder.SQL_MODULE_CAMPAIGN_MNG, "campaign-agents-by-params"));

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

            SQLQuery query = session.createSQLQuery(sqlStrBuilder.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 createCampaignAgents(CampaignAgentsDTO campaignAgentsDTO) {
        ResultDTO resultDTO = new ResultDTO();
        CampaignAgentsMapper campaignAgentsMapper = new CampaignAgentsMapper();
        CampaignAgent campaignAgent = new CampaignAgent();
        try {
            if (campaignAgentsDTO != null) {
                // insert
                campaignAgent = campaignAgentsMapper.toPersistenceBean(campaignAgentsDTO);
                campaignAgentsRepository.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;
    }
}
