package com.viettel.campaign.service.impl;

import com.viettel.campaign.config.DataSourceQualify;
import com.viettel.campaign.mapper.CampaignCompleteCodeMapper;

import com.viettel.campaign.model.ccms_full.CampaignCfg;
import com.viettel.campaign.repository.ccms_full.CampaignCfgRepository;
import com.viettel.campaign.service.CampaignCfgService;
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.CampaignCfgDTO;
import com.viettel.campaign.web.dto.ResultDTO;
import com.viettel.campaign.web.dto.request_dto.CampaignCfgRequestDTO;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.*;

@Service
public class CampaignCfgServiceImpl implements CampaignCfgService {

    protected Logger logger = LoggerFactory.getLogger(CampaignCfgServiceImpl.class);

    @Autowired
    CampaignCfgRepository completeCodeRepository;

    @Override
    @Transactional(DataSourceQualify.CCMS_FULL)
    public ResultDTO listAllCompleteCode(int page, int pageSize, String sort,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_STATUS_MNG, "findAll-CampaignCompleteCode"));

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

            query.setParameter("p_company_site_id", companySiteId);

            query.addScalar("campaignCompleteCodeId", new LongType());
            query.addScalar("campaignId", new LongType());
            query.addScalar("completeName", new StringType());
            query.addScalar("completeValue", new StringType());
            query.addScalar("description", new StringType());
            query.addScalar("status", new ShortType());
            query.addScalar("completeType", new ShortType());
            query.addScalar("isRecall", new ShortType());
            query.addScalar("updateAt", new DateType());
            query.addScalar("updateBy", new StringType());
            query.addScalar("createBy", new StringType());
            query.addScalar("createAt", new DateType());
            query.addScalar("campaignType", new StringType());
            query.addScalar("isFinish", new ShortType());
            query.addScalar("isLock", new ShortType());
            query.addScalar("companySiteId", new LongType());
            query.addScalar("durationLock", new LongType());
            query.addScalar("chanel", new LongType());
            query.setResultTransformer(Transformers.aliasToBean(CampaignCfgDTO.class));
            int count = 0;
            List<CampaignCfgDTO> dtoList = query.list();
            if (dtoList.size() > 0) {
                count = query.list().size();
            }

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

            List<CampaignCfgDTO>data = query.list();
            Page<CampaignCfgDTO> 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);
            logger.error(e.getMessage(), e);
        } finally {
            session.close();
        }

        return resultDTO;
    }

    @Override
    @Transactional(DataSourceQualify.CCMS_FULL)
    public Map listCompleteCodeByName(int page, int pageSize, String sort, String name) {
        Map result = new HashMap();
        List<CampaignCfg> lst = new ArrayList<>();
        List<CampaignCfg> count = new ArrayList<>();

        lst = completeCodeRepository.findByCompleteNameContains(name, PageRequest.of(page, pageSize, Sort.by(sort)));
        count = completeCodeRepository.findByCompleteNameContains(name, null);

        result.put("totalItem", count.size());
        result.put("customers", lst);

        return result;
    }

    @Override
    @Transactional(DataSourceQualify.CCMS_FULL)
    public ResultDTO createCompleteCode(CampaignCfgDTO completeCodeDTO) {
        ResultDTO resultDTO = new ResultDTO();
        CampaignCompleteCodeMapper compCodeMapper = new CampaignCompleteCodeMapper();
        Date today = new Date();
        CampaignCfg compCode = new CampaignCfg();

        try {
            if (completeCodeDTO != null) {
                // insert
                compCode = compCodeMapper.toPersistenceBean(completeCodeDTO);
                compCode = completeCodeRepository.save(compCode);

                resultDTO.setErrorCode("0");
                resultDTO.setDescription("Complete Code: " + compCode.getCampaignCompleteCodeId() + " created!");
            } else {
                resultDTO.setErrorCode("-2");
                resultDTO.setDescription("CompleteCodeDTO null");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return resultDTO;
    }

    @Override
    @Transactional(DataSourceQualify.CCMS_FULL)
    public ResultDTO updateCompleteCode(CampaignCfgDTO completeCodeDTO) {
        ResultDTO resultDTO = new ResultDTO();
        CampaignCompleteCodeMapper compCodeMapper = new CampaignCompleteCodeMapper();
        Date today = new Date();
        CampaignCfg compCode = new CampaignCfg();

        try {
            if (completeCodeDTO != null) {
                // update
                compCode = compCodeMapper.toPersistenceBean(completeCodeDTO);
                compCode = completeCodeRepository.save(compCode);

                resultDTO.setErrorCode("0");
                resultDTO.setDescription("Complete Code: " + compCode.getCampaignCompleteCodeId() + " updated!");
            } else {
                resultDTO.setErrorCode("-2");
                resultDTO.setDescription("CompleteCodeDTO null");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return resultDTO;
    }

    @Override
    @Transactional(DataSourceQualify.CCMS_FULL)
    public ResultDTO deleteCompleteCode(CampaignCfgRequestDTO completeCodeDTO) {
        ResultDTO resultDTO = new ResultDTO();

        try {
            // delete
            if (completeCodeDTO != null) {
                completeCodeRepository.deleteCampaignCompleteCodeBy(completeCodeDTO.getCampaignCompleteCodeID(), completeCodeDTO.getCompanySiteId());

                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 deleteList(CampaignCfgRequestDTO completeCodeDTO) {
        ResultDTO resultDTO = new ResultDTO();
        try {
            if (completeCodeDTO != null) {
                    completeCodeRepository.deletedList(completeCodeDTO.getListId(), completeCodeDTO.getCompanySiteId());

                    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 deleteById(Long id) {
        ResultDTO result = new ResultDTO();

        try {
            completeCodeRepository.deleteById(id);
            result.setErrorCode(Constants.Status.ACTIVE_STR);
            result.setDescription(Constants.Status.ACTIVE_STR);

        } catch (Exception e) {
            result.setErrorCode("-1");
            return result;
        }
        result.setErrorCode("0");
        return result;
    }


    @Override
    @Transactional(DataSourceQualify.CCMS_FULL)
    public ResultDTO findMaxValueCampaignCompleteCode(CampaignCfgDTO completeCodeDTO) {
        ResultDTO resultDTO = new ResultDTO();
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

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

        if (DataUtil.isNullOrZero(completeCodeDTO.getCompanySiteId())) {
            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_STATUS_MNG, "get-max-value-completevalue"));

            SQLQuery query = session.createSQLQuery(sqlStrBuilder.toString());
            query.setParameter("p_site_id", completeCodeDTO.getCompanySiteId());

            query.addScalar("completeValue", new StringType());
            query.addScalar("companySiteId", new LongType());
            query.setResultTransformer(Transformers.aliasToBean(CampaignCfgDTO.class));

            List<CampaignCfgDTO> data = query.list();
            if (data != null && data.size() > 0) {
                int tmp = 5;
                String completeValue = data.get(0).getCompleteValue();
                if (completeValue != null && !completeValue.trim().equals("")) {
                    tmp = Integer.parseInt(completeValue) + 1;
                }
                resultDTO.setData(tmp);
            } else {
                resultDTO.setData(null);
            }

            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
        } catch (Exception e) {
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
            logger.error(e.getMessage(), e);
        } finally {
            session.close();
            return resultDTO;
        }
    }

    @Override
    @Transactional(DataSourceQualify.CCMS_FULL)
    public ResultDTO getListStatus(String completeValue, Short completeType, Long companySiteId) {
        ResultDTO resultDTO = new ResultDTO();
        try {
            List<CampaignCfg> list = completeCodeRepository.getCustomerStatus(completeValue, completeType, companySiteId);

            resultDTO.setListData(list);
            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
        } catch (Exception e) {
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(e.getMessage());
        }
        return resultDTO;
    }

    @Override
    @Transactional(DataSourceQualify.CCMS_FULL)
    public ResultDTO getListStatusWithoutType(String completeValue, Short completeType, Long companySiteId) {
        ResultDTO resultDTO = new ResultDTO();
        try {
            List<CampaignCfg> list = completeCodeRepository.getCustomerStatusWithoutValue(completeValue, completeType, companySiteId);
            resultDTO.setListData(list);
            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
        } catch (Exception e) {
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(e.getMessage());
        }
        return resultDTO;
    }

    @Override
    @Transactional(DataSourceQualify.CCMS_FULL)
    public ResultDTO editCampaignCompleteCode(Long campaignCompleteCodeId) {
        ResultDTO resultDTO = new ResultDTO();
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

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

        if (DataUtil.isNullOrZero(campaignCompleteCodeId)) {
            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_STATUS_MNG,"findCampaignCodeById"));

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

            query.setParameter("p_campaignComleteCode",campaignCompleteCodeId);

            query.addScalar("campaignCompleteCodeId", new LongType());
            query.addScalar("campaignId", new LongType());
            query.addScalar("completeName", new StringType());
            query.addScalar("completeValue", new StringType());
            query.addScalar("description", new StringType());
            query.addScalar("status", new ShortType());
            query.addScalar("completeType", new ShortType());
            query.addScalar("isRecall", new ShortType());
            query.addScalar("updateAt", new DateType());
            query.addScalar("updateBy", new StringType());
            query.addScalar("createBy", new StringType());
            query.addScalar("createAt", new DateType());
            query.addScalar("campaignType", new StringType());
            query.addScalar("isFinish", new ShortType());
            query.addScalar("isLock", new ShortType());
            query.addScalar("companySiteId", new LongType());
            query.addScalar("durationLock", new LongType());
            query.addScalar("chanel", new LongType());
            query.setResultTransformer(Transformers.aliasToBean(CampaignCfgDTO.class));
            List<CampaignCfgDTO>data = query.list();
            resultDTO.setData(data);
            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
        } catch (Exception e) {
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
            logger.error(e.getMessage(), e);
        } finally {
            session.close();
        }

        return resultDTO;
    }

}
