package com.crm.manager.service.impl;

import com.alibaba.fastjson.JSON;
import com.crm.manager.dao.mapper.MarketEmailRecordMapper;
import com.crm.manager.dao.repository.MarketEmailRecordRepository;
import com.crm.manager.service.EmailSendFeignService;
import com.crm.manager.service.MarketEmailRecordService;
import com.crm.manager.service.impl.base.BaseUploadServiceImpl;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.constant.EmailSendEnum;
import com.crm.rely.backend.core.constant.MapConstants;
import com.crm.rely.backend.core.dto.base.BaseResultDto;
import com.crm.rely.backend.core.dto.base.PageDto;
import com.crm.rely.backend.core.dto.base.ResultWithPagerDto;
import com.crm.rely.backend.core.entity.base.SingleLongEntity;
import com.crm.rely.backend.core.entity.system.email.SupplementSendEmailEntity;
import com.crm.rely.backend.core.entity.system.email.SysEmailSendEntity;
import com.crm.rely.backend.core.exception.ServiceException;
import com.crm.rely.backend.core.pojo.table.SysEmailRecordTable;
import com.crm.rely.backend.model.constant.ManagerConstants;
import com.crm.rely.backend.model.dto.market.MarketEmailStatusNumberDto;
import com.crm.rely.backend.model.dto.market.email.record.MarketEmailRecordListDto;
import com.crm.rely.backend.model.entity.market.MarketEmailAddEntity;
import com.crm.rely.backend.model.entity.market.record.MarketEmailRecordSearchPageEntity;
import com.crm.rely.backend.model.entity.market.record.MarketEmailRecordSendEntity;
import com.crm.rely.backend.model.entity.market.record.MarketEmailRecordStatusNumberEntity;
import com.crm.rely.backend.model.entity.market.record.MarketEmailRecordSupplementSendEntity;
import com.crm.rely.backend.model.pojo.table.MarketEmailRecordTable;
import com.crm.rely.backend.model.pojo.view.MarketEmailStatusNumberView;
import com.crm.rely.backend.service.EmailService;
import com.crm.rely.backend.util.DateUtil;
import com.crm.rely.backend.util.RexUtil;
import com.crm.rely.backend.util.SynchronizedKey;
import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

@Slf4j
@Service
public class MarketEmailRecordServiceImpl extends BaseUploadServiceImpl implements MarketEmailRecordService {

    @Autowired
    private MarketEmailRecordRepository marketEmailRecordRepository;

    @Autowired
    private MarketEmailRecordMapper marketEmailRecordMapper;

    @Autowired
    private EmailSendFeignService emailSendFeignService;

    @Autowired
    private EmailService emailService;

    private static boolean isSendMq = false;

    @Override
//    @Transactional(rollbackFor = Exception.class)
    public Integer add(MarketEmailAddEntity entity) throws ServiceException {

        try {
            isSendMq = true;
            return marketEmailRecordMapper.insertSaves(entity.getId());
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        } finally {
            isSendMq = false;
        }
        return 0;
    }

    @Override
//    @Transactional(rollbackFor = Exception.class)
    public void send(MarketEmailRecordSendEntity entity) throws ServiceException {
        List<MarketEmailRecordTable> marketEmailRecordTables =
                marketEmailRecordRepository.getAllByEmailIdAndStatus(entity.getEmailId(),
                        ManagerConstants.MARKET_PENDING_STATUS);

        if (marketEmailRecordTables != null) {
            sendEmails(marketEmailRecordTables);
        }
    }

    private void send() throws ServiceException {
//        List<MarketEmailRecordTable> marketEmailRecordTables =
//                marketEmailRecordRepository.selectLimitByStatus(Constants.MARKET_PENDING_STATUS, 10);

        List<MarketEmailRecordTable> marketEmailRecordTables =
                marketEmailRecordMapper.selectLimitByStatus(ManagerConstants.MARKET_PENDING_STATUS, 100);
        if (marketEmailRecordTables != null) {
            sendEmails(marketEmailRecordTables);
        }
    }

    /**
     * @throws ServiceException
     */
    @Scheduled(fixedDelay = 1000 * 60)
//    @Transactional(rollbackFor = Exception.class)
    public void scheduleSendTask() throws ServiceException {

        send();
    }

    private void sendEmails(List<MarketEmailRecordTable> tables) throws ServiceException {

        if (tables == null || tables.size() <= 0) {
            return;
        }
        for (MarketEmailRecordTable table : tables) {
            try {
                SynchronizedKey.exec("MarketEmailRecordServiceImpl" + table.getId().toString(), new Thread(() -> {
                    table.setStatus(ManagerConstants.MARKET_PROCESSING_STATUS);
//                    marketEmailRecordRepository.save(table);

                    marketEmailRecordMapper.updateStatus(table.getStatus(), table.getId());
                    try {
                        SysEmailSendEntity sysEmailSendEntity = sendEmail(table);
                        emailService.sendEmail(sysEmailSendEntity, Constants.ACTIVEMQ_JMS_URL_EMAIL_MARKETS);
                    } catch (ServiceException e) {
                        e.printStackTrace();
                    }
                }));

            } catch (Exception e) {
                e.printStackTrace();
            }
        }


    }

    private SysEmailSendEntity sendEmail(MarketEmailRecordTable marketEmailRecordTable) throws ServiceException {
        if (marketEmailRecordTable == null) {
            throw ServiceException.exception(Constants.SYSTEM_ERROR);
        }
        SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
        Map<String, String> map = new HashMap<>(3);

        map.put(MapConstants.NAME, RexUtil.rexName(marketEmailRecordTable.getName()));
        map.put(MapConstants.DATE_TIME, DateUtil.formatTime());
        map.put(MapConstants.C_ID, String.valueOf(marketEmailRecordTable.getCId()));

        sysEmailSendEntity.setAddIp(marketEmailRecordTable.getAddIp());
        sysEmailSendEntity.setAddTime(new Date());
        sysEmailSendEntity.setNote(String.valueOf(marketEmailRecordTable.getId()));

        sysEmailSendEntity.setEmailConfigId(marketEmailRecordTable.getEmailConfigId());
        sysEmailSendEntity.setUsers(marketEmailRecordTable.getUser());
        sysEmailSendEntity.setEmailSendEnum(EmailSendEnum.MARKET_EMAIL);
        sysEmailSendEntity.setSubject(marketEmailRecordTable.getSubject());
        sysEmailSendEntity.setContent(marketEmailRecordTable.getContent());
        sysEmailSendEntity.setCallbackMq(Constants.MARKET_EMAIL_CALLBACK);

        sysEmailSendEntity.setMap(map);


        return sysEmailSendEntity;
    }

    @JmsListener(destination = Constants.MARKET_EMAIL_CALLBACK)
    @Transactional(rollbackFor = Exception.class)
    public void sendEmailCallBack(String content) throws Exception {

        if (Strings.isNullOrEmpty(content)) {
            return;
        }

        //转化为实体对象
        SysEmailRecordTable sysEmailRecordTable = JSON.parseObject(content, SysEmailRecordTable.class);
        if (sysEmailRecordTable == null || Strings.isNullOrEmpty(sysEmailRecordTable.getNote())) {
            return;
        }
        //获取对应的记录id
        Long id = null;
        try {
            id = Long.parseLong(sysEmailRecordTable.getNote());
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        if (id == null) {
            return;
        }
        //获取营销邮件记录
        MarketEmailRecordTable marketEmailRecordTable = marketEmailRecordRepository.getFirstById(id);
        SynchronizedKey.exec("MarketEmailRecordServiceImpl" + marketEmailRecordTable.getId(), new Thread(() -> {

            if (marketEmailRecordTable == null) {
                return;
            }

            //修改记录
            marketEmailRecordTable.setContent(sysEmailRecordTable.getContent());
            marketEmailRecordTable.setErrorCode(sysEmailRecordTable.getErrorCode());
            marketEmailRecordTable.setErrorMsg(sysEmailRecordTable.getErrorMsg());
            marketEmailRecordTable.setSendDate(sysEmailRecordTable.getSendDate());
            marketEmailRecordTable.setSendType(sysEmailRecordTable.getSendType());
            if (sysEmailRecordTable.getStatus() != null && sysEmailRecordTable.getStatus().equals(1)) {
                marketEmailRecordTable.setStatus(ManagerConstants.MARKET_COMPLETED_STATUS);
            } else if (sysEmailRecordTable.getStatus() != null && sysEmailRecordTable.getStatus().equals(2)) {
                marketEmailRecordTable.setStatus(ManagerConstants.MARKET_UNSUBSCRIBE_STATUS);
            } else {
                marketEmailRecordTable.setStatus(ManagerConstants.MARKET_FAIL_STATUS);
            }
            marketEmailRecordTable.setRecordId(sysEmailRecordTable.getId());
            marketEmailRecordTable.setEmailConfigId(sysEmailRecordTable.getEmailConfigId());
            marketEmailRecordTable.setFromAccountName(sysEmailRecordTable.getFromAccountName());
            marketEmailRecordTable.setFromAccount(sysEmailRecordTable.getFromAccount());
            marketEmailRecordTable.setModifyIp("127.0.0.1");
            marketEmailRecordTable.setModifyTime(new Date());
            marketEmailRecordTable.setModifyUser(-1L);
            marketEmailRecordRepository.save(marketEmailRecordTable);
        }));


    }

    /**
     * 重新发起
     *
     * @param singleLongEntity
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResultDto supplementSend(SingleLongEntity singleLongEntity) throws Exception {
        MarketEmailRecordTable marketEmailRecordTable =
                marketEmailRecordRepository.findFirstById(singleLongEntity.getId());
        if (ManagerConstants.MARKET_COMPLETED_STATUS.equals(marketEmailRecordTable.getStatus())) {
            return BaseResultDto.success(Constants.MAIL_SUCCESS);
        }
        //邮件非发送失败或者 记录id为空 则提示系统错误
        if (!ManagerConstants.MARKET_FAIL_STATUS.equals(marketEmailRecordTable.getStatus())
                || marketEmailRecordTable.getRecordId() == null) {
            return BaseResultDto.error(Constants.SYSTEM_ERROR);
        }
        marketEmailRecordTable.setStatus(ManagerConstants.MARKET_PROCESSING_STATUS);
        marketEmailRecordRepository.save(marketEmailRecordTable);
        SupplementSendEmailEntity entity = new SupplementSendEmailEntity();
        entity.setId(marketEmailRecordTable.getRecordId());

        return emailSendFeignService.managerSupplementSendEmail(entity);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void supplementSend(MarketEmailRecordSupplementSendEntity entity) throws Exception {
        List<MarketEmailRecordTable> marketEmailRecordTables = null;
        if (entity.getIds() == null || entity.getIds().size() <= 0) {
            marketEmailRecordTables = marketEmailRecordRepository.findAllByEmailIdAndStatus(entity.getEmailId(),
                    ManagerConstants.MARKET_FAIL_STATUS);
        } else {
            marketEmailRecordTables =
                    marketEmailRecordRepository.findAllByEmailIdAndStatusAndIdIn(entity.getEmailId(),
                            ManagerConstants.MARKET_FAIL_STATUS, entity.getIds());
        }

        if (marketEmailRecordTables != null && marketEmailRecordTables.size() > 0) {
            List<Long> supplementIds = new ArrayList<>(marketEmailRecordTables.size());
            for (MarketEmailRecordTable marketEmailRecordTable : marketEmailRecordTables) {
                supplementIds.add(marketEmailRecordTable.getRecordId());
                marketEmailRecordTable.setStatus(ManagerConstants.MARKET_PROCESSING_STATUS);
            }

            marketEmailRecordRepository.save(marketEmailRecordTables);
            try {
                emailService.sendEmailSupplement(supplementIds);
            } catch (ServiceException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public ResultWithPagerDto<MarketEmailRecordListDto> searchPageList(MarketEmailRecordSearchPageEntity entity) throws Exception {
        Integer count = marketEmailRecordMapper.countList(entity);
        PageDto pageDto = PageDto.format(entity, count);
        if (count == null || count <= 0) {
            return ResultWithPagerDto.success(pageDto);
        }
        List<MarketEmailRecordListDto> sysEmailTemplateSearchDtos = getMarketEmailRecordListDto(entity);
        if (sysEmailTemplateSearchDtos == null) {
            throw ServiceException.exception(Constants.SYSTEM_ERROR);
        }

        return ResultWithPagerDto.success(pageDto, sysEmailTemplateSearchDtos);
    }

    @Override
    public MarketEmailRecordListDto searchSingle(SingleLongEntity entity) throws Exception {
        MarketEmailRecordTable marketEmailRecordTable = marketEmailRecordRepository.getFirstById(entity.getId());
        if (marketEmailRecordTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        return transform(marketEmailRecordTable);
    }

    @Override
    public MarketEmailStatusNumberDto statusNumber(MarketEmailRecordStatusNumberEntity entity) throws ServiceException {
        MarketEmailStatusNumberView marketEmailStatusNumberView = marketEmailRecordMapper.statusNumber(entity);
        MarketEmailStatusNumberDto marketEmailStatusNumberDto = new MarketEmailStatusNumberDto();
        BeanUtils.copyProperties(marketEmailStatusNumberView, marketEmailStatusNumberDto);
        return marketEmailStatusNumberDto;
    }

    @Override
    public String uploadFile(MultipartFile file) throws Exception {
        String middlePath = "/market/email";
        String path = saveFile(middlePath, file);

        return path;
    }

    private List<MarketEmailRecordListDto> getMarketEmailRecordListDto(MarketEmailRecordSearchPageEntity entity) throws ServiceException {
        List<MarketEmailRecordTable> marketEmailRecordTables = marketEmailRecordMapper.pageList(entity);

        if (marketEmailRecordTables == null || marketEmailRecordTables.size() <= 0) {

            return null;
        }
        List<MarketEmailRecordListDto> sysEmailTemplateSearchDtos = new ArrayList<>(marketEmailRecordTables.size());

        for (MarketEmailRecordTable emailRecordTable : marketEmailRecordTables) {
            MarketEmailRecordListDto marketEmailRecordListDto = transform(emailRecordTable);
            sysEmailTemplateSearchDtos.add(marketEmailRecordListDto);
        }
        return sysEmailTemplateSearchDtos;
    }

    private MarketEmailRecordListDto transform(MarketEmailRecordTable marketEmailRecordTable) {
        MarketEmailRecordListDto marketEmailRecordListDto = new MarketEmailRecordListDto();
        BeanUtils.copyProperties(marketEmailRecordTable, marketEmailRecordListDto);
        return marketEmailRecordListDto;
    }
}
