package com.viettel.campaign.service.impl;

import com.viettel.campaign.mapper.CampaignCompleteCodeMapper;
import com.viettel.campaign.model.CampaignCompleteCode;
import com.viettel.campaign.repository.CampaignCompleteCodeRepository;
import com.viettel.campaign.service.CampaignCompleteCodeService;
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.CampaignCompleteCodeDTO;
import com.viettel.campaign.web.dto.ResultDTO;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.transform.Transformers;
import org.hibernate.type.LongType;
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.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class CampaignCompleteCodeServiceImpl implements CampaignCompleteCodeService {

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

    @Autowired
    CampaignCompleteCodeRepository completeCodeRepository;

    @Override
    public Map listAllCompleteCode(int page, int pageSize, String sort) {
        Map result = new HashMap();
        Page<CampaignCompleteCode> pg = completeCodeRepository.findAll(PageRequest.of(page, pageSize, Sort.by(sort)));
        result.put("totalItems", pg.getTotalElements());
        result.put("data", pg.iterator());
        return result;
    }

    @Override
    public Map listCompleteCodeByName(int page, int pageSize, String sort, String name) {
        Map result = new HashMap();
        List<CampaignCompleteCode> lst = new ArrayList<>();
        List<CampaignCompleteCode> 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
    public ResultDTO createCompleteCode(CampaignCompleteCodeDTO completeCodeDTO) {
        ResultDTO resultDTO = new ResultDTO();
        CampaignCompleteCodeMapper compCodeMapper = new CampaignCompleteCodeMapper();
        Date today = new Date();
        CampaignCompleteCode compCode = new CampaignCompleteCode();

        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
    public ResultDTO updateCompleteCode(CampaignCompleteCodeDTO completeCodeDTO) {
        ResultDTO resultDTO = new ResultDTO();
        CampaignCompleteCodeMapper compCodeMapper = new CampaignCompleteCodeMapper();
        Date today = new Date();
        CampaignCompleteCode compCode = new CampaignCompleteCode();

        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
    public ResultDTO deleteCompleteCode(CampaignCompleteCodeDTO completeCodeDTO) {
        ResultDTO resultDTO = new ResultDTO();
        CampaignCompleteCodeMapper compCodeMapper = new CampaignCompleteCodeMapper();
        Date today = new Date();
        CampaignCompleteCode compCode = new CampaignCompleteCode();

        try {
            if (completeCodeDTO != null) {
                // delete
                completeCodeRepository.deleteById(completeCodeDTO.getCampaignCompleteCodeId());

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

        return resultDTO;
    }

    @Transactional
    @Override
    public ResultDTO deleteList(List<Long> completeCodeDtos) {
        ResultDTO resultDTO = new ResultDTO();
        try {
            completeCodeRepository.deleteds(completeCodeDtos);
            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);

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

        return resultDTO;
    }

    @Override
    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
//    public ResultDTO findMaxValueCampaignCompleteCode(CampaignCompleteCodeDTO completeCodeDTO) {
//        ResultDTO resultDTO = new ResultDTO();
//        CampaignCompleteCodeMapper campaignCompleteCodeMapper = new CampaignCompleteCodeMapper();
//        try {
//            short maxValue = 0;
////            List<CampaignCompleteCode> list = completeCodeRepository.findCampaignCompleteCodesByCompanySiteId(completeCodeDTO.getCompanySiteId());
////            for (int i = 0; i<list.size();i++) {
////                if (list.get(i).getCompleteValue() != null && !list.get(i).getCompleteValue().equals("")) {
////                    if (maxValue < Short.parseShort(list.get(i).getCompleteValue())) {
////                        maxValue = Short.parseShort(list.get(i).getCompleteValue());
////                    }
////                }
////            }
//            maxValue = completeCodeRepository.findByMaxCompanySiteId(completeCodeDTO.getCompanySiteId());
//            if (maxValue < 4) {
//                maxValue = 4;
//            }
//            maxValue+= 1;
//            resultDTO.setData(maxValue);
//            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
//            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
//        } catch (Exception e) {
//            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
//            resultDTO.setDescription(e.getMessage());
//            logger.error(e.getMessage(), e);
//        }
//        return resultDTO;
//    }

    @Override
    public ResultDTO findMaxValueCampaignCompleteCode(CampaignCompleteCodeDTO 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(CampaignCompleteCodeDTO.class));

            List<CampaignCompleteCodeDTO> data = query.list();
            if (data != null && data.size() > 0) {
                int tmp = 4;
                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
    public ResultDTO getListStatus(String completeValue, Short completeType, Long companySiteId) {
        ResultDTO resultDTO = new ResultDTO();
        try {
            List<CampaignCompleteCode> 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
    public ResultDTO getListStatusWithoutType(String completeValue, Short completeType, Long companySiteId) {
        ResultDTO resultDTO = new ResultDTO();
        try {
            List<CampaignCompleteCode> list = completeCodeRepository.getCustomerStatusWithoutType(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
//    public ResultDTO findMaxValueCampaignCompleteCode(CampaignCompleteCodeDTO completeCodeDTO) {
//        ResultDTO result = new ResultDTO();
//        CampaignCompleteCodeMapper campaignCompleteCodeMapper = new CampaignCompleteCodeMapper();
//        CampaignCompleteCode campaignCompleteCode = new CampaignCompleteCode();
//        try{
//            short resultmaxValue = completeCodeRepository.findByMaxCompanySiteId(completeCodeDTO.getCompanySiteId());
//            campaignCompleteCode.setCompleteValue(String.valueOf(resultmaxValue + 1));
////            if (resultmaxValue < 4) {
////                resultmaxValue =4;
////            }
//            result.setData(resultmaxValue);
//            result.setErrorCode(Constants.Status.ACTIVE_STR);
//            result.setDescription(Constants.Status.ACTIVE_STR);
//        }
//        catch (Exception e){
//            logger.error(e.getMessage(), e);
//            result.setErrorCode("-1");
//            return result;
//        }
//        result.setErrorCode("0");
//        return result;
//    }

}
