package com.viettel.campaign.service.impl;

import com.viettel.campaign.config.DataSourceQualify;
import com.viettel.campaign.model.acd_full.Agents;
import com.viettel.campaign.model.ccms_full.*;
import com.viettel.campaign.repository.acd_full.AgentsRepository;
import com.viettel.campaign.repository.ccms_full.*;
import com.viettel.campaign.service.CampaignExecuteService;
import com.viettel.campaign.utils.*;
import com.viettel.campaign.web.dto.*;
import com.viettel.campaign.web.dto.request_dto.CampaignCustomerListColumnRequestDTO;
import com.viettel.campaign.web.dto.request_dto.CampaignRequestDTO;
import com.viettel.econtact.filter.UserSession;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.modelmapper.ModelMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

@Service
public class CampaignExecuteServiceImp implements CampaignExecuteService {

    private static final Logger logger = LoggerFactory.getLogger(CampaignExecuteServiceImp.class);
    private SimpleDateFormat formatter = new SimpleDateFormat(Constants.DATE_FORMAT.FOMART_DATE_TYPE_1);

    private Random rand = SecureRandom.getInstanceStrong();

    @Autowired
    ModelMapper modelMapper;

    @Autowired
    ReceiveCustLogRepository custLogRepository;

    @Autowired
    CampaignRepositoryCustom campaignRepositoryCustom;

    @Autowired
    CampaignExecuteRepository campaignExecuteRepository;

    @Autowired
    CampaignCustomerRepository campaignCustomerRepository;

    @Autowired
    AgentsRepository agentsRepository;

    @Autowired
    CampaignAgentRepository campaignAgentRepository;

    @Autowired
    TimeZoneDialModeRepository zoneDialModeRepository;

    @Autowired
    TimeRangeDialModeRepository rangeDialModeRepository;

    @Autowired
    CampaignCustomerListColumnRepository campaignCustomerListColumnRepository;

    @Autowired
    ContactCustResultRepository ccResultRepository;

    @Autowired
    ContactQuestResultRepository contactQuestResultRepository;

    @Autowired
    CampaignCfgRepository cfgRepository;

    @Autowired
    CustomerRepository customerRepository;

    public CampaignExecuteServiceImp() throws NoSuchAlgorithmException {
    }

    //<editor-fold: hungtt>
    @Override
    @Transactional(DataSourceQualify.CCMS_FULL)
    public ResultDTO getComboBoxStatus(String companySiteId, String completeType) {
        ResultDTO resultDTO = new ResultDTO();
        try {
            List<ApParamDTO> lst = campaignExecuteRepository.getComboBoxStatus(companySiteId, completeType);
            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
            resultDTO.setData(lst);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return resultDTO;
    }

    @Override
    @Transactional(DataSourceQualify.CCMS_FULL)
    public ResultDTO getComboCampaignType(String companySiteId) {
        ResultDTO resultDTO = new ResultDTO();
        try {
            List<ApParamDTO> lst = campaignExecuteRepository.getComboCampaignType(companySiteId);
            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
            resultDTO.setData(lst);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return resultDTO;
    }

    @Override
    @Transactional(DataSourceQualify.CCMS_FULL)
    public ResultDTO searchInteractiveResult(CampaignRequestDTO dto) {
        ResultDTO resultDTO = new ResultDTO();

        try {
            List<ContactCustResultDTO> list = campaignExecuteRepository.getInteractiveResult(dto, SQLBuilder.buildPageable(dto));
            resultDTO.setListData(list);
            resultDTO.setTotalRow(campaignExecuteRepository.getInteractiveResult(dto, null).size());
            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
        }

        return resultDTO;
    }

    @Override
    @Transactional(DataSourceQualify.CCMS_FULL)
    public XSSFWorkbook exportInteractiveResult(CampaignRequestDTO dto) throws IOException {
        Locale locale = Locale.forLanguageTag("vi");
        List<ContactCustResultDTO> list = campaignExecuteRepository.getExcelInteractiveResult(dto);

        XSSFWorkbook workbook = null;
        Sheet sheet;
        try {
            // create font style
            workbook = new XSSFWorkbook();
            Font defaultFont = workbook.createFont();
            defaultFont.setFontHeightInPoints((short) 13);
            defaultFont.setFontName("Times New Roman");
            defaultFont.setColor(IndexedColors.BLACK.getIndex());

            Font titleFont = workbook.createFont();
            titleFont.setFontHeightInPoints((short) 18);
            titleFont.setFontName("Times New Roman");
            titleFont.setColor(IndexedColors.BLACK.getIndex());
            titleFont.setBold(true);

            Font headerFont = workbook.createFont();
            headerFont.setFontHeightInPoints((short) 13);
            headerFont.setFontName("Times New Roman");
            headerFont.setColor(IndexedColors.BLACK.getIndex());
            headerFont.setBold(true);

            CellStyle styleTitle = workbook.createCellStyle();
            styleTitle.setFont(titleFont);
            styleTitle.setAlignment(HorizontalAlignment.CENTER);

            CellStyle styleRowHeader = workbook.createCellStyle();
            styleRowHeader.setFont(headerFont);
            styleRowHeader.setAlignment(HorizontalAlignment.CENTER);
            styleRowHeader.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());
            styleRowHeader.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            styleRowHeader.setBorderRight(BorderStyle.THIN);
            styleRowHeader.setRightBorderColor(IndexedColors.BLACK.getIndex());
            styleRowHeader.setBorderBottom(BorderStyle.THIN);
            styleRowHeader.setBottomBorderColor(IndexedColors.BLACK.getIndex());
            styleRowHeader.setBorderLeft(BorderStyle.THIN);
            styleRowHeader.setLeftBorderColor(IndexedColors.BLACK.getIndex());
            styleRowHeader.setBorderTop(BorderStyle.THIN);
            styleRowHeader.setTopBorderColor(IndexedColors.BLACK.getIndex());

            CellStyle styleRow = workbook.createCellStyle();
            styleRow.setFont(defaultFont);

            // list header
            List<String> headerList = new ArrayList<>();
            headerList.add(BundleUtils.getLangString("stt", locale));
            headerList.add(BundleUtils.getLangString("campaign.execute.interactive.campaignCode", locale));
            headerList.add(BundleUtils.getLangString("campaign.execute.interactive.campaignName", locale));
            headerList.add(BundleUtils.getLangString("campaign.execute.interactive.agentId", locale));
            headerList.add(BundleUtils.getLangString("campaign.execute.interactive.phoneNumber", locale));
            headerList.add(BundleUtils.getLangString("campaign.execute.interactive.customerId", locale));
            headerList.add(BundleUtils.getLangString("campaign.execute.interactive.customerName", locale));
            headerList.add(BundleUtils.getLangString("campaign.execute.interactive.createTime", locale));
            headerList.add(BundleUtils.getLangString("campaign.execute.interactive.contactStatus", locale));
            headerList.add(BundleUtils.getLangString("campaign.execute.interactive.surveyStatus", locale));
            headerList.add(BundleUtils.getLangString("campaign.execute.interactive.status", locale));
            headerList.add(BundleUtils.getLangString("campaign.execute.interactive.recordStatus", locale));

            //
            String sheetName = BundleUtils.getLangString("detail", locale);
            sheet = workbook.createSheet(sheetName);

            // Title
            String title = BundleUtils.getLangString("campaign.execute.interactive.title", locale);
            int rowTitleStart = 3;
            Row rowTitle = sheet.createRow(rowTitleStart);
            rowTitle.setHeight((short) 800);
            writeCellContent(rowTitle, styleTitle, 3, title);
            sheet.addMergedRegion(new CellRangeAddress(rowTitleStart, rowTitleStart, 3, 8));
            // Header
            int startRowTable = 5;
            int count = 1;
            Row rowHeader = sheet.createRow(startRowTable);
            for (int i = 0; i < headerList.size(); i++) {
                writeCellContent(rowHeader, styleRowHeader, i, headerList.get(i));
            }
            // Content
            for (int i = 0, rowIndex = 1; i < list.size(); i++) {
                Row row = sheet.createRow(startRowTable + count);
                int col = 0;
                writeCellContent(row, styleRow, col++, rowIndex);
                writeCellContent(row, styleRow, col++, list.get(i).getCampaignCode());
                writeCellContent(row, styleRow, col++, list.get(i).getCampaignName());
                writeCellContent(row, styleRow, col++, list.get(i).getUserName());
                writeCellContent(row, styleRow, col++, list.get(i).getPhoneNumber());
                writeCellContent(row, styleRow, col++, list.get(i).getCustomerName());
                writeCellContent(row, styleRow, col++, list.get(i).getCustomerName());
                writeCellContent(row, styleRow, col++, formatter.format(list.get(i).getCreateTime()));
                writeCellContent(row, styleRow, col++, list.get(i).getContactStatus());
                writeCellContent(row, styleRow, col++, list.get(i).getSurveyStatus());
                writeCellContent(row, styleRow, col++, list.get(i).getStatus());
                writeCellContent(row, styleRow, col++, list.get(i).getRecordStatus());
                ++rowIndex;
                ++count;
            }
        } catch (Exception e) {

        } finally {
            if (workbook != null) workbook.close();
        }

        return workbook;
    }

    private void writeCellContent(Row row, CellStyle rowStyle, int colNo, Object content) {
        Cell cell = row.createCell(colNo);
        if (content == null) {
            cell.setCellValue("");
        } else {
            cell.setCellValue(String.valueOf(content));
        }
        cell.setCellStyle(rowStyle);
    }
    //</editor-fold: hungtt>

    @Override
    public ResultDTO searchCampaignExecute(CampaignRequestDTO requestDto, String xAuthToken) {
        ResultDTO result = new ResultDTO();
        Map data = new HashMap();
        UserSession userSession = (UserSession) RedisUtil.getInstance().get(xAuthToken);

        Integer count = campaignExecuteRepository.searchCampaignExecute(requestDto, null).size();

        if (count > 0) {
            result.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            result.setDescription(Constants.ApiErrorDesc.SUCCESS);
            result.setTotalRow(count);
            result.setListData(campaignExecuteRepository.searchCampaignExecute(requestDto, SQLBuilder.buildPageable(requestDto)));

            Agents agents = agentsRepository.findByAgentId(requestDto.getAgentId());
            //TimeZoneDialMode zoneDialMode = zoneDialModeRepository.findDialModeAtCurrent(Long.parseLong(requestDto.getCampaignId()), Long.parseLong(requestDto.getCompanySiteId()));
            //TimeRangeDialMode rangeDialMode = rangeDialModeRepository.findDialModeAtCurrent(Long.parseLong(requestDto.getCampaignId()), Long.parseLong(requestDto.getCompanySiteId()));

            if (agents.getUserStatus() != null && agents.getCampaignSystemStatus() != null) {
                if (agents.getUserStatus().equalsIgnoreCase("CALLOUT") && agents.getCampaignSystemStatus().equalsIgnoreCase("AVAILABLE")) {
                    //if (zoneDialMode != null && zoneDialMode.getDialMode().equals(0) || rangeDialMode != null && rangeDialMode.getDialMode().equals(0))
                    data.put("dialModeManual", "1");
                }
            }
            result.setData(data);
        } else {
            result.setErrorCode(Constants.ApiErrorCode.ERROR);
            result.setDescription(Constants.ApiErrorDesc.ERROR);
        }

        return result;
    }

    @Override
    public ResultDTO getExecuteCampaign(CampaignRequestDTO requestDto) {
        ResultDTO result = new ResultDTO();
        String dialMode = getDialModeAtCurrent(Long.parseLong(requestDto.getCompanySiteId()), Long.parseLong(requestDto.getCampaignId()));

        try {
            // update acd_full.agents table
            Agents agents = agentsRepository.findByAgentId(requestDto.getAgentId());
            agents.setAgentId(requestDto.getAgentId());
            agents.setCampaignSystemStatus("AVAILABLE");
            agents.setCurrentCampaignId(Long.parseLong(requestDto.getCampaignId()));
            agents.setUpdateDate(new Date());
            Agents a1 = agentsRepository.save(agents);

            // update ccms_full.campaign_agent table
            List<CampaignAgent> ca = campaignAgentRepository.findByCampaignIdAndAgentId(Long.parseLong(requestDto.getCampaignId()), Long.parseLong(requestDto.getAgentId()));
            for (CampaignAgent item : ca) {
                item.setStatus(1);
            }
            List<CampaignAgent> ca1 = campaignAgentRepository.saveAll(ca);

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

        return result;
    }

    @Override
    public ResultDTO getCustomer(CampaignCustomerDTO dto) {
        ResultDTO result = new ResultDTO();
        String dialMode = getDialModeAtCurrent(dto.getCompanySiteId(), dto.getCampaignId());

        //Agents agents = agentsRepository.findByAgentId(dto.getAgentId());
        //TimeZoneDialMode zoneDialMode = zoneDialModeRepository.findDialModeAtCurrent(Long.parseLong(dto.getCampaignId()), Long.parseLong(dto.getCompanySiteId()));
        //TimeRangeDialMode rangeDialMode = rangeDialModeRepository.findDialModeAtCurrent(Long.parseLong(dto.getCampaignId()), Long.parseLong(dto.getCompanySiteId()));
        List<CampaignCustomerDTO> lst = new ArrayList<>();

        StringBuilder sb = new StringBuilder();
        sb.append("SELECT CC.CUSTOMER_ID AS customerId");
        sb.append(" FROM CAMPAIGN_CUSTOMER CC");
        sb.append("    LEFT JOIN CCMS_FULL.RECEIVE_CUST_LOG CL ON CC.CUSTOMER_ID = CL.CUSTOMER_ID");
        sb.append(" WHERE CC.CAMPAIGN_ID = :campaignId");
        sb.append("  AND CC.COMPANY_SITE_ID = :companySiteId");
        sb.append("  AND CC.IN_CAMPAIGN_STATUS = 1");
        sb.append("  AND CL.CUSTOMER_ID IS NULL");
        sb.append("  AND CL.END_TIME IS NULL");
        sb.append("  AND EXISTS(SELECT 1");
        sb.append("        FROM CCMS_FULL.CAMPAIGN_COMPLETE_CODE CCC");
        sb.append("        WHERE CC.STATUS = CCC.COMPLETE_VALUE");
        sb.append("          AND STATUS = 1");
        sb.append("          AND IS_RECALL = 1");
        sb.append("          AND COMPLETE_TYPE = 2");
        sb.append("          AND COMPANY_SITE_ID = :companySiteId)");
        sb.append("  AND CC.RECALL_TIME <= SYSDATE");
        sb.append("  AND CC.RECALL_TIME + NUMTODSINTERVAL(:dungSai, 'MINUTE') >= SYSDATE");
        sb.append("  AND CC.AGENT_ID = :agentId");

        StringBuilder sb2 = new StringBuilder();
        sb2.append("SELECT CC.CUSTOMER_ID AS customerId");
        sb2.append(" FROM CCMS_FULL.CAMPAIGN_CUSTOMER CC");
        sb2.append("    LEFT JOIN CCMS_FULL.RECEIVE_CUST_LOG CL ON CC.CUSTOMER_ID = CL.CUSTOMER_ID");
        sb2.append("    LEFT JOIN ACD_FULL.AGENTS AG ON CC.AGENT_ID = AG.AGENT_ID AND CC.CAMPAIGN_ID = AG.CURRENT_CAMPAIGN_ID");
        sb2.append(" WHERE CC.CAMPAIGN_ID = :campaignId");
        sb2.append("  AND CC.COMPANY_SITE_ID = :companySiteId");
        sb2.append("  AND CC.IN_CAMPAIGN_STATUS = 1");
        sb2.append("  AND CL.CUSTOMER_ID IS NULL");
        sb2.append("  AND CL.END_TIME IS NULL");
        sb2.append("  AND EXISTS(SELECT 1");
        sb2.append("        FROM CCMS_FULL.CAMPAIGN_COMPLETE_CODE CCC");
        sb2.append("        WHERE CC.STATUS = CCC.COMPLETE_VALUE");
        sb2.append("          AND STATUS = 1");
        sb2.append("          AND IS_RECALL = 1");
        sb2.append("          AND COMPLETE_TYPE = 2");
        sb2.append("          AND COMPANY_SITE_ID = :companySiteId)");
        sb2.append("  AND CC.RECALL_TIME <= SYSDATE");
        sb2.append("  AND CC.RECALL_TIME + NUMTODSINTERVAL(:dungSai, 'MINUTE') >= SYSDATE");
        sb2.append("  AND (AG.CAMPAIGN_SYSTEM_STATUS IS NULL OR AG.CAMPAIGN_SYSTEM_STATUS <> 'AVAILABLE')");

        StringBuilder sb3 = new StringBuilder();
        sb3.append("SELECT CC.CUSTOMER_ID AS customerId");
        sb3.append(" FROM CAMPAIGN_CUSTOMER CC");
        sb3.append("    LEFT JOIN RECEIVE_CUST_LOG CL ON CC.CUSTOMER_ID = CL.CUSTOMER_ID");
        sb3.append(" WHERE CC.CAMPAIGN_ID = :campaignId");
        sb3.append("  AND CC.COMPANY_SITE_ID = :companySiteId");
        sb3.append("  AND CC.IN_CAMPAIGN_STATUS = 1");
        sb3.append("  AND CL.CUSTOMER_ID IS NULL");
        sb3.append("  AND CL.END_TIME IS NULL");
        sb3.append("  AND EXISTS(SELECT 1");
        sb3.append("        FROM CCMS_FULL.CAMPAIGN_COMPLETE_CODE CCC");
        sb3.append("        WHERE CC.STATUS = CCC.COMPLETE_VALUE");
        sb3.append("          AND STATUS = 1");
        sb3.append("          AND IS_RECALL = 1");
        sb3.append("          AND COMPLETE_TYPE = 2");
        sb3.append("          AND COMPANY_SITE_ID = :companySiteId)");
        sb3.append("  AND CC.RECALL_TIME + NUMTODSINTERVAL(:dungSai, 'MINUTE') <= SYSDATE");

        StringBuilder sb4 = new StringBuilder();
        sb4.append("SELECT CC.CUSTOMER_ID AS customerId ");
        sb4.append(" FROM CAMPAIGN_CUSTOMER CC");
        sb4.append("    INNER JOIN CUSTOMER C ON CC.CUSTOMER_ID = C.CUSTOMER_ID");
        sb4.append("    LEFT JOIN RECEIVE_CUST_LOG CL ON CC.CUSTOMER_ID = CL.CUSTOMER_ID");
        sb4.append(" WHERE CC.CAMPAIGN_ID = :campaignId");
        sb4.append("  AND CC.COMPANY_SITE_ID = :companySiteId");
        sb4.append("  AND CC.IN_CAMPAIGN_STATUS = 1");
        sb4.append("  AND CL.CUSTOMER_ID IS NULL");
        sb4.append("  AND CL.END_TIME IS NULL");
        sb4.append("  AND CC.STATUS = 0");
        sb4.append("  AND C.STATUS = 1");
        sb4.append("  AND C.CALL_ALLOWED = 1");
        sb4.append("  AND C.IPCC_STATUS = 'active'");

        StringBuilder sb5 = new StringBuilder();
        sb5.append("SELECT CC.CUSTOMER_ID AS customerId");
        sb5.append(" FROM CAMPAIGN_CUSTOMER CC");
        sb5.append("    LEFT JOIN CCMS_FULL.RECEIVE_CUST_LOG CL ON CC.CUSTOMER_ID = CL.CUSTOMER_ID");
        sb5.append(" WHERE CC.CAMPAIGN_ID = :campaignId");
        sb5.append("  AND CC.COMPANY_SITE_ID = :companySiteId");
        sb5.append("  AND CC.IN_CAMPAIGN_STATUS = 1");
        sb5.append("  AND CL.CUSTOMER_ID IS NULL");
        sb5.append("  AND CL.END_TIME IS NULL");
        sb5.append("  AND EXISTS(SELECT 1");
        sb5.append("        FROM CCMS_FULL.CAMPAIGN_COMPLETE_CODE CCC");
        sb5.append("        WHERE CC.STATUS = CCC.COMPLETE_VALUE");
        sb5.append("          AND STATUS = 1");
        sb5.append("          AND IS_FINISH = 0");
        sb5.append("          AND COMPLETE_TYPE = 1");
        sb5.append("          AND COMPANY_SITE_ID = :companySiteId)");
        sb5.append("  AND CC.RECALL_COUNT < C.MAX_RECALL");
        sb5.append("  AND C.STATUS = 1");
        sb5.append("  AND C.CALL_ALLOWED = 1");
        sb5.append("  AND C.IPCC_STATUS = 'active'");

        String getExecuteCus1Str = sb.toString();
        String getExecuteCus2Str = sb2.toString();
        String getExecuteCus3Str = sb3.toString();
        String getExecuteCus4Str = sb4.toString();
        String getExecuteCus5Str = sb5.toString();

        // Khách hàng đến thời điểm hẹn gọi lại và là khách hàng mà chính NSD hẹn gọi lại
        List<CampaignCustomerDTO> lst1 = campaignCustomerRepository.getDataCampaignCustomer(dto, getExecuteCus1Str);
        if (lst1.size() > 0) {
            lst = lst1;
        } else {
            // Khách hàng đến thời điểm hẹn gọi lại và không là khách hàng mà NSD dùng hẹn gọi lại nhưng TVV hẹn gọi lại không đăng nhập hoặc không thực hiện chiến dịch hiện tại
            List<CampaignCustomerDTO> lst2 = campaignCustomerRepository.getDataCampaignCustomer(dto, getExecuteCus2Str);
            if (lst2.size() > 0) {
                lst = lst2;
            } else {
                // Khách hàng là khách hàng hẹn gọi lại nhưng thời gian hẹn gọi lại đã quá thời gian hẹn gọi lại + dung sai
                List<CampaignCustomerDTO> lst3 = campaignCustomerRepository.getDataCampaignCustomer(dto, getExecuteCus3Str);
                if (lst3.size() > 0) {
                    lst = lst3;
                } else {
                    // Khách hàng mới
                    List<CampaignCustomerDTO> lst4 = campaignCustomerRepository.getDataCampaignCustomer(dto, getExecuteCus4Str);
                    if (lst4.size() > 0) {
                        lst = lst4;
                    } else {
                        // Khách hàng không liên lạc được nhưng chưa phải là cuộc gọi kết thúc và có số lần đã gọi < Số lần gọi tối đa được cấu hình và khoảng cách giữa 2 lần gọi < thời gian tương tác giữa 2 lần gọi được cấu hình
                        List<CampaignCustomerDTO> lst5 = campaignCustomerRepository.getDataCampaignCustomer(dto, getExecuteCus5Str);
                        lst = lst5;
                    }
                }
            }
        }

        if (lst != null) {
            result.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            result.setDescription(Constants.ApiErrorDesc.SUCCESS);
            result.setListData(lst);
            //result.setData(data);
        } else {
            result.setErrorCode(Constants.ApiErrorCode.ERROR);
            result.setDescription(Constants.ApiErrorDesc.ERROR);
        }

        return result;
    }

    @Override
    public ResultDTO getCustomerComplete(ReceiveCustLogDTO dto) {
        ResultDTO result = new ResultDTO();

        try {
            ReceiveCustLog rclResult = custLogRepository.save(modelMapper.map(dto, ReceiveCustLog.class));
            agentsRepository.updateAgentLogoutFromCampaign(dto.getAgentId().toString(), "NOT AVAILABLE");

            result.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            result.setDescription(Constants.ApiErrorDesc.SUCCESS);
            result.setData(rclResult);
        } catch (Exception e) {
            // e.printStackTrace();
            result.setErrorCode(Constants.ApiErrorCode.ERROR);
            result.setDescription(Constants.ApiErrorDesc.ERROR);
        }

        return result;
    }

    @Override
    public ResultDTO getCallLog(ReceiveCustLogDTO dto) {
        ResultDTO result = new ResultDTO();

        List<CampaignCustomer> lst = null;//campaignCustomerRepository.getCustomerRecallDate(dto.getCampaignId(), dto.getAgentId(), dto.getCompanySiteId(), );

        result.setErrorCode(Constants.ApiErrorCode.ERROR);
        result.setDescription(Constants.ApiErrorDesc.ERROR);

        return result;
    }

    @Override
    public ResultDTO getAgentLogout(CampaignRequestDTO dto) {
        ResultDTO result = new ResultDTO();

        try {
            agentsRepository.updateAgentLogoutFromCampaign(dto.getAgentId(), "LOGOUT");
            // update ccms_full.campaign_agent table
            List<CampaignAgent> ca = campaignAgentRepository.findByCampaignIdAndAgentId(Long.parseLong(dto.getCampaignId()), Long.parseLong(dto.getAgentId()));
            for (CampaignAgent item : ca) {
                item.setStatus(1);
            }
            List<CampaignAgent> ca1 = campaignAgentRepository.saveAll(ca);

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

        return result;
    }

    @Override
    public ResultDTO updateContactCustResult(ContactCustResultDTO dto, UserSession userSession) {
        ResultDTO result = new ResultDTO();
        ContactCustResult ccr = new ContactCustResult();

        try {
            if (dto.getEventCall().equalsIgnoreCase("call")) {
                ccr = ccResultRepository.save(modelMapper.map(dto, ContactCustResult.class));
            }

            if (dto.getContactCustResultId() != null) {
                ccr = ccResultRepository.getOne(dto.getContactCustResultId());

                if (dto.getEventCall().equalsIgnoreCase("ringing")) {
                    ccr.setCallId(dto.getCallId());
                    ccr.setUpdateBy(userSession.getUserId());
                    ccr.setUpdateTime(new Date());
                    ccr = ccResultRepository.save(ccr);
                }

                if (dto.getEventCall().equalsIgnoreCase("ended")) {
                    ccr.setDurationCall(dto.getDurationCall());
                    ccr.setStartCall(dto.getStartCall());
                    ccr.setReceiveTime(dto.getReceiveTime());
                    ccr.setPreEndTime(ccResultRepository.getMaxCreateTime(dto.getCampaignId(), dto.getAgentId()));
                    ccr.setEndTime(dto.getEndTime());
                    ccr.setWaitTime(dto.getWaitTime());
                    ccr = ccResultRepository.save(ccr);
                    CampaignCustomer cc = campaignCustomerRepository.findCampaignCustomersByCampaignIdAndCustomerId(dto.getCampaignId(), dto.getCustomerId());
                    cc.setCallTime(dto.getStartCall());
                    cc = campaignCustomerRepository.save(cc);
                    Agents ag = agentsRepository.findByAgentId(dto.getAgentId().toString());
                    ag.setSystemStatus("AVAILABLE");
                    ag = agentsRepository.save(ag);
                }

                if (dto.getEventCall().equalsIgnoreCase("endedBeforeTen")) {
                    ccr.setStatus((short) 0);
                    ccr.setUpdateBy(userSession.getUserId());
                    ccr.setUpdateTime(new Date());
                    ccr = ccResultRepository.save(ccr);
                }
            }

            if (dto.getEventCall().equalsIgnoreCase("endedAfterTen")) {
                ccr = modelMapper.map(dto, ContactCustResult.class);
                ccr.setPreEndTime(ccResultRepository.getMaxCreateTime(dto.getCampaignId(), dto.getAgentId()));
                ccr = ccResultRepository.save(ccr);
            }

            result.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            result.setDescription(Constants.ApiErrorDesc.SUCCESS);
            result.setData(ccr);
        } catch (Exception e) {
            // e.printStackTrace();
            result.setErrorCode(Constants.ApiErrorCode.ERROR);
            result.setDescription(Constants.ApiErrorDesc.ERROR);
        }

        return result;
    }

    @Override
    public ResultDTO draftAtTen(ContactCustResultDTO dto, UserSession userSession) {
        ResultDTO result = new ResultDTO();
        ContactCustResult ccr = new ContactCustResult();

        try {
            ccResultRepository.deleteById(dto.getContactCustResultId());

            ccr.setCompanySiteId(dto.getCompanySiteId());
            ccr.setCallStatus(dto.getCallStatus());
            ccr.setContactStatus(dto.getContactStatus());
            ccr.setStatus(dto.getStatus());
            ccr.setDescription(dto.getDescription());
            ccr.setCreateTime(new Date());
            ccr.setAgentId(dto.getAgentId());
            ccr.setCampaignId(dto.getCampaignId());
            ccr.setUpdateBy(userSession.getUserId());
            ccr.setCustomerId(dto.getCustomerId());
            ccr.setDurationCall(dto.getDurationCall());
            ccr.setStartCall(dto.getStartCall());
            ccr.setReceiveCustLogId(dto.getReceiveCustLogId());
            ccr.setCallId(dto.getCallId());
            ccr.setPhoneNumber(dto.getPhoneNumber());
            ccr.setReceiveTime(dto.getReceiveTime());
            ccr.setPreEndTime(ccResultRepository.getMaxCreateTime(dto.getCampaignId(), dto.getAgentId()));
            ccr.setRecallTime(dto.getRecallTime());
            ccr.setIsFinalRecall(dto.getIsFinalRecall());
            ccr.setIsSendEmail(dto.getIsSendEmail());
            ccr.setEndTime(dto.getEndTime());
            ccr.setWaitTime(dto.getWaitTime());
            ccr.setDialMode(dto.getDialMode());
            ccr = ccResultRepository.save(ccr);

            result.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            result.setDescription(Constants.ApiErrorDesc.SUCCESS);
            result.setData(ccr);
        } catch (Exception e) {
            // e.printStackTrace();
            result.setErrorCode(Constants.ApiErrorCode.ERROR);
            result.setDescription(Constants.ApiErrorDesc.ERROR);
        }

        return result;
    }

    @Override
    public ResultDTO recallCustomer(ContactCustResultDTO dto) {
        ResultDTO result = new ResultDTO();

        try {
            ccResultRepository.deleteById(dto.getContactCustResultId());

            ContactCustResult ccr = ccResultRepository.save(modelMapper.map(dto, ContactCustResult.class));

            result.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            result.setDescription(Constants.ApiErrorDesc.SUCCESS);
            result.setData(ccr);
        } catch (Exception e) {
            // e.printStackTrace();
            result.setErrorCode(Constants.ApiErrorCode.ERROR);
            result.setDescription(Constants.ApiErrorDesc.ERROR);
        }

        return result;
    }

    @Override
    public ResultDTO callCustomerEnd(ContactCustResultDTO dto) {
        ResultDTO result = new ResultDTO();
        ContactCustResult ccr = new ContactCustResult();

        try {
            ccr = ccResultRepository.getOne(dto.getContactCustResultId());

            result.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            result.setDescription(Constants.ApiErrorDesc.SUCCESS);
            result.setData(ccr);
        } catch (Exception e) {
            // e.printStackTrace();
            result.setErrorCode(Constants.ApiErrorCode.ERROR);
            result.setDescription(Constants.ApiErrorDesc.ERROR);
        }

        return result;
    }

    @Override
    public ResultDTO updateCustomerResult(ContactCustResultDTO dto) {
        ResultDTO result = new ResultDTO();

        try {
            ContactCustResult ccr = ccResultRepository.getOne(dto.getContactCustResultId());
            ccr.setDurationCall(0L);
            ccr.setStartCall(new Date());
            ccr.setReceiveTime(new Date());
            ccr.setPreEndTime(new Date());
            ccr.setEndTime(new Date());
            ccr.setWaitTime(0L);
            ContactCustResult resultUpdate = ccResultRepository.save(ccr);

            result.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            result.setDescription(Constants.ApiErrorDesc.SUCCESS);
            result.setData(resultUpdate);
        } catch (Exception e) {
            // e.printStackTrace();
            result.setErrorCode(Constants.ApiErrorCode.ERROR);
            result.setDescription(Constants.ApiErrorDesc.ERROR);
        }

        return result;
    }

    @Transactional(DataSourceQualify.CCMS_FULL)
    public ResultDTO countRecallCustomer(Long companySiteId, Long agentId) {
        ResultDTO resultDTO = new ResultDTO();
        Long count = campaignCustomerRepository.countRecallCustomer(companySiteId, agentId);

        if (count != null) {
            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
            resultDTO.setData(count);
        } else {
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
            resultDTO.setData(0);
        }

        return resultDTO;
    }

    @Transactional(DataSourceQualify.CCMS_FULL)
    public ResultDTO getCustomerRecall(Long campaignId, Long customerId) {
        ResultDTO resultDTO = new ResultDTO();

        Long count = campaignCustomerRepository.getCustomerRecall(campaignId, customerId);

        if (count != null) {
            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
            resultDTO.setData(count);
        } else {
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
            resultDTO.setData(0);
        }

        return resultDTO;
    }

    @Override
    public ResultDTO getCustomerInfor(Long companySiteId, Long customerId, Long campaignId) {
        ResultDTO resultDTO = new ResultDTO();

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

        try {
            List<CampaignCustomerListColumnRequestDTO> data = campaignCustomerListColumnRepository.getCustomerInfor(companySiteId, customerId, campaignId);
            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
            resultDTO.setData(data);
        } catch (Exception e) {
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
        }
        return resultDTO;
    }

    @Override
    @Transactional(DataSourceQualify.CCMS_FULL)
    public ResultDTO createListContactQuestResult(List<ContactQuestResultDTO> dtoList) {
        ResultDTO resultDTO = new ResultDTO();
        List<ContactQuestResult> lstContactQuestResult = new ArrayList<>();

        try {
            for (ContactQuestResultDTO item : dtoList) {
                lstContactQuestResult.add(modelMapper.map(item, ContactQuestResult.class));
            }

            List<ContactQuestResult> dataReturn = new ArrayList<>();
            dataReturn = contactQuestResultRepository.saveAll(lstContactQuestResult);
            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
            resultDTO.setListData(dataReturn);
        } catch (Exception e) {
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
        }

        return resultDTO;
    }

    @Override
    @Transactional(DataSourceQualify.CCMS_FULL)
    public ResultDTO updateListContactQuestResult(ContactQuestResultDTO dto) {
        ResultDTO resultDTO = new ResultDTO();
        List<ContactQuestResult> lstContactQuestResult = new ArrayList<>();

        try {
            lstContactQuestResult = contactQuestResultRepository.findByContactCustResultId(dto.getContactCustResultId());
            for (ContactQuestResult item : lstContactQuestResult) {
                item.setStatus((short) 0);
            }
            lstContactQuestResult = contactQuestResultRepository.saveAll(lstContactQuestResult);
            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
            resultDTO.setListData(lstContactQuestResult);
        } catch (Exception e) {
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
        }

        return resultDTO;
    }

    @Override
    public String getDialModeAtCurrent(Long campaignId, Long companySiteId) {
        // 0: manual, 1- Preview, 2-Progressive, 3-Super Progressive, 4- Predictive
        try {
            TimeRangeDialMode lstTimeRange = rangeDialModeRepository.findDialModeAtCurrent(companySiteId, campaignId);
            TimeZoneDialMode lstTimeZone = zoneDialModeRepository.findDialModeAtCurrent(companySiteId, campaignId);

            if (lstTimeRange.getTimeRangeDialModeId() != null) {
                return lstTimeRange.getDialMode().toString();
            } else if (lstTimeZone.getTimeZoneDialModeId() != null) {
                return lstTimeZone.getDialMode().toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return "-1";
    }

    @Override
    public ResultDTO getContactCustResultById(Long contactCustResultId) {
        ResultDTO resultDTO = new ResultDTO();

        try {
            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
            resultDTO.setData(ccResultRepository.findById(contactCustResultId));
        } catch (Exception e) {
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
        }

        return resultDTO;
    }

    @Override
    public ResultDTO updateCampaignCustomer(CampaignCustomerDTO dto) {
        ResultDTO resultDTO = new ResultDTO();

        try {
            CampaignCustomer cc = campaignCustomerRepository.findCampaignCustomersByCampaignIdAndCustomerId(dto.getCampaignId(), dto.getCustomerId());
            cc.setStatus(dto.getStatus());
            cc.setAgentId(dto.getAgentId());
            cc.setRecallTime(dto.getRecallTime());
            cc.setRecallCount(cc.getRecallCount() + 1);
            cc.setCallTime(dto.getCallTime());
            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
            resultDTO.setData(cc);
        } catch (Exception e) {
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
        }

        return resultDTO;
    }

    public ResultDTO updateSurveyStatus(CustomerTimeDTO dto, UserSession userSession) {
        ResultDTO resultDTO = new ResultDTO();

        try {
            CampaignCfg cfg = cfgRepository.findByCompanySiteIdAndCompleteValue(dto.getCompanySiteId(), dto.getCompleteValue());
            if (cfg.getIsLock() == 1) {
                Customer c = customerRepository.getOne(dto.getCustomerId());
                c.setIpccStatus("locked");
                c = customerRepository.save(c);
            } else {
                CustomerTime c = new CustomerTime();
                c.setCompanySiteId(dto.getCompanySiteId());
                c.setCustomerId(dto.getCustomerId());
                c.setStartTime(dto.getStartTime());
                LocalDateTime ldt = dto.getStartTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().plusDays(cfg.getDurationLock());
                c.setEndTime(Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant()));
                c.setStatus((short) 1);
                c.setCreateTime(new Date());
                c.setCreateBy(userSession.getUserId());
                c.setUpdateTime(new Date());
                c.setUpdateBy(userSession.getUserId());
                c.setContactCustResultId(dto.getContactCustResultId());
            }

            resultDTO.setErrorCode(Constants.ApiErrorCode.SUCCESS);
            resultDTO.setDescription(Constants.ApiErrorDesc.SUCCESS);
            resultDTO.setData(null);
        } catch (Exception e) {
            resultDTO.setErrorCode(Constants.ApiErrorCode.ERROR);
            resultDTO.setDescription(Constants.ApiErrorDesc.ERROR);
        }

        return resultDTO;
    }
}
