package com.crm.web.service.impl;

import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.constant.MapConstants;
import com.crm.rely.backend.core.constant.StatusConstants;
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.system.email.SysEmailSendEntity;
import com.crm.rely.backend.core.pojo.table.SysConfigTable;
import com.crm.rely.backend.core.exception.ServiceException;
import com.crm.rely.backend.model.constant.ConfigConstants;
import com.crm.rely.backend.model.constant.EmailTemplateConstants;
import com.crm.rely.backend.model.dto.web.custom.analysis.WebCustomAnalysisInteractionDto;
import com.crm.rely.backend.model.dto.web.custom.analysis.WebCustomAnalysisSearchDto;
import com.crm.rely.backend.model.entity.web.custom.analysis.*;
import com.crm.rely.backend.model.entity.web.custom.analysis.interaction.history.WebCustomAnalysisInteractionHistoryAddEntity;
import com.crm.rely.backend.model.pojo.table.CustomInfoTable;
import com.crm.rely.backend.model.pojo.table.WebCustomAnalysisTable;
import com.crm.rely.backend.model.pojo.view.WebCustomAnalysisView;
import com.crm.rely.backend.service.EmailService;
import com.crm.rely.backend.util.DateUtil;
import com.crm.web.dao.mapper.WebCustomAnalysisMapper;
import com.crm.web.dao.repository.CustomInfoRepository;
import com.crm.web.dao.repository.WebCustomAnalysisRepository;
import com.crm.web.service.SysConfigService;
import com.crm.web.service.WebCustomAnalysisInteractionHistoryService;
import com.crm.web.service.WebCustomAnalysisService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class WebCustomAnalysisServiceImpl implements WebCustomAnalysisService {

    @Autowired
    private WebCustomAnalysisRepository repository;

    @Autowired
    private WebCustomAnalysisMapper mapper;

    @Autowired
    private WebCustomAnalysisInteractionHistoryService webCustomAnalysisInteractionHistoryService;

    @Autowired
    private EmailService emailService;

    @Autowired
    private SysConfigService sysConfigService;


    @Autowired
    private CustomInfoRepository customInfoRepository;


    @Override
    public WebCustomAnalysisTable getById(Long id) throws ServiceException {

        WebCustomAnalysisTable table = repository.getFirstById(id);
        if (table == null) {
            throw ServiceException.notFoundException();
        }
        return table;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WebCustomAnalysisSearchDto searchSingle(Long id) throws ServiceException {
        WebCustomAnalysisView view = mapper.getById(id);

        if (view == null) {

            throw new ServiceException(Constants.SYSTEM_ERROR);
        }

        WebCustomAnalysisSearchDto dto = new WebCustomAnalysisSearchDto();
        BeanUtils.copyProperties(view, dto);

        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultWithPagerDto<WebCustomAnalysisSearchDto> pageSearchList(WebCustomAnalysisSearchListEntity entity) throws ServiceException {
        Integer count = mapper.countList(entity);
        PageDto pageDto = PageDto.format(entity, count);
        if (count == null || count <= 0) {
            return ResultWithPagerDto.success(pageDto);
        }

        List<WebCustomAnalysisSearchDto> dtos = searchList(entity);
        return ResultWithPagerDto.success(pageDto, dtos);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<WebCustomAnalysisSearchDto> searchList(WebCustomAnalysisSearchListEntity entity) throws ServiceException {

        List<WebCustomAnalysisView> views = mapper.pageList(entity);
        if (entity.getPage() != null) {
            if (views == null || views.size() <= 0) {

                throw new ServiceException(Constants.SYSTEM_ERROR);
            }
        }

        List<WebCustomAnalysisSearchDto> dtos = new ArrayList<>(views.size());

        for (WebCustomAnalysisView view : views) {
            WebCustomAnalysisSearchDto dto = new WebCustomAnalysisSearchDto();
            BeanUtils.copyProperties(view, dto);

            if (view.getInteractionAgree() == null && view.getInteractionVeto() == null) {
                dto.setInteraction(0);
            } else if (view.getInteractionAgree() != null) {
                dto.setInteraction(1);
            } else if (view.getInteractionVeto() != null) {
                dto.setInteraction(2);
            }
            dtos.add(dto);

        }
        return dtos;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(WebCustomAnalysisAddEntity entity) throws ServiceException {

        WebCustomAnalysisTable table = new WebCustomAnalysisTable();
        table.setStatus(StatusConstants.APPLY_STATUS);
        table.setAgreeNum(0);
        table.setVetoNum(0);
        table.setReleaseDayAgreeNum(0);
        table.setReleaseDayVetoNum(0);
        table.setTopping(0);
        table.setTotalInteraction(0);
        table.setTotalReleaseDayInteraction(0);
        BeanUtils.copyProperties(entity, table);
        repository.save(table);

        sendManager(table);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(WebCustomAnalysisUpdateEntity entity) throws ServiceException {
        WebCustomAnalysisTable table = repository.findFirstById(entity.getId());
        if (table == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }

        //如果不是后台编辑 则判断是否属于客户自己发布的分析  如果不是 则判断没有权限操作
        if (!table.getCustomId().equals(entity.getCustomId())) {
            throw ServiceException.exception(Constants.NOT_PERMIT);
        }

        //如果 评论已经通过审核 则客户不能进行修改
        if (StatusConstants.PASSED_STATUS.equals(table.getStatus())) {
            throw ServiceException.exception(Constants.NOT_PERMIT);
        }
        table.setAddTime(new Date());
        //直接重置客户记录
        table.setApproveDesc(null);
        table.setApproveTime(null);
        table.setApproveUser(null);
        table.setAgreeNum(0);
        table.setVetoNum(0);
        table.setReleaseDayAgreeNum(0);
        table.setReleaseDayVetoNum(0);
        table.setTopping(0);
        table.setStatus(StatusConstants.APPLY_STATUS);

        BeanUtils.copyProperties(entity, table);

        table.setTotalInteraction((table.getAgreeNum() == null ? 0 : table.getAgreeNum()) + (table.getVetoNum() == null ? 0 : table.getVetoNum()));
        table.setTotalReleaseDayInteraction((table.getReleaseDayAgreeNum() == null ? 0 :
                table.getReleaseDayAgreeNum()) + (table.getReleaseDayVetoNum() == null ? 0 : table.getReleaseDayVetoNum()));

        repository.save(table);

        sendManager(table);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(WebCustomAnalysisManagerUpdateNumEntity entity) throws ServiceException {
        WebCustomAnalysisTable table = repository.findFirstById(entity.getId());
        if (table == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }

        BeanUtils.copyProperties(entity, table);

        table.setTotalInteraction((table.getAgreeNum() == null ? 0 : table.getAgreeNum()) + (table.getVetoNum() == null ? 0 : table.getVetoNum()));
        table.setTotalReleaseDayInteraction((table.getReleaseDayAgreeNum() == null ? 0 :
                table.getReleaseDayAgreeNum()) + (table.getReleaseDayVetoNum() == null ? 0 : table.getReleaseDayVetoNum()));

        repository.save(table);

        sendManager(table);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WebCustomAnalysisInteractionDto interaction(WebCustomAnalysisInteractionEntity entity) throws ServiceException {
        WebCustomAnalysisTable table = repository.findFirstById(entity.getId());
        if (table == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        if (!StatusConstants.PASSED_STATUS.equals(table.getStatus())) {
            throw ServiceException.exception("当前分析不存在");
        }
        WebCustomAnalysisInteractionDto dto = new WebCustomAnalysisInteractionDto();

        //已互动 直接返回
        if (webCustomAnalysisInteractionHistoryService.existInteraction(table.getId(), entity.getCustomId())) {
            dto.setAgreeNum(table.getAgreeNum());
            dto.setVetoNum(table.getVetoNum());
            return dto;
        }

        addHistory(table, entity);
        calculationInteraction(table, entity);

        dto.setAgreeNum(table.getAgreeNum());
        dto.setVetoNum(table.getVetoNum());

        return dto;
    }

    /**
     * 添加互动历史
     *
     * @param table
     * @param entity
     */
    private void addHistory(WebCustomAnalysisTable table, WebCustomAnalysisInteractionEntity entity) {
        WebCustomAnalysisInteractionHistoryAddEntity webCustomAnalysisInteractionHistoryAddEntity =
                new WebCustomAnalysisInteractionHistoryAddEntity();

        webCustomAnalysisInteractionHistoryAddEntity.setAnalysisId(table.getId());
        webCustomAnalysisInteractionHistoryAddEntity.setReleaseCustomId(table.getCustomId());
        webCustomAnalysisInteractionHistoryAddEntity.setAgree(entity.getAgree());
        webCustomAnalysisInteractionHistoryAddEntity.setVeto(entity.getVeto());
        webCustomAnalysisInteractionHistoryAddEntity.setCustomId(entity.getCustomId());
        webCustomAnalysisInteractionHistoryService.add(webCustomAnalysisInteractionHistoryAddEntity);
    }

    /**
     * 计算互动
     *
     * @param table
     * @param entity
     */
    private void calculationInteraction(WebCustomAnalysisTable table, WebCustomAnalysisInteractionEntity entity) {
        if (entity.getAgree() != null) {
            //加赞同
            if (table.getAgreeNum() == null) {
                table.setAgreeNum(0);
            }
            table.setAgreeNum(table.getAgreeNum() + 1);

            //判断是否在同一天
            if (DateUtil.format("yyyy-MM-dd").equals(DateUtil.format("yyyy-MM-dd", table.getAddTime()))) {
                table.setReleaseDayAgreeNum((table.getReleaseDayAgreeNum() == null ? 0 : table.getReleaseDayAgreeNum()) + 1);
            }

        } else {
            //加否决
            if (entity.getVeto() != null) {
                if (table.getVetoNum() == null) {
                    table.setVetoNum(0);
                }
                table.setVetoNum(table.getVetoNum() + 1);
            }

            //判断是否在同一天
            if (DateUtil.format("yyyy-MM-dd").equals(DateUtil.format("yyyy-MM-dd", table.getAddTime()))) {
                table.setReleaseDayVetoNum((table.getReleaseDayVetoNum() == null ? 0 : table.getReleaseDayVetoNum()) + 1);
            }
        }

        table.setTotalInteraction((table.getAgreeNum() == null ? 0 : table.getAgreeNum()) + (table.getVetoNum() == null ? 0 : table.getVetoNum()));
        table.setTotalReleaseDayInteraction((table.getReleaseDayAgreeNum() == null ? 0 :
                table.getReleaseDayAgreeNum()) + (table.getReleaseDayVetoNum() == null ? 0 : table.getReleaseDayVetoNum()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approve(WebCustomAnalysisApproveEntity entity) throws ServiceException {
        WebCustomAnalysisTable table = repository.findFirstById(entity.getId());
        if (table == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        if (StatusConstants.PASSED_STATUS.equals(table.getStatus())) {
            throw ServiceException.exception(Constants.NOT_PERMIT);
        }
        BeanUtils.copyProperties(entity, table);

        repository.save(table);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(WebCustomAnalysisDeleteEntity entity) throws ServiceException {


        List<WebCustomAnalysisTable> tables = repository.findAllByIdIn(entity.getIds());
        if (tables == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }

        //如果是客户进行删除 则判断记录是否是客户的 并且记录不能为已经通过的分享
        if (entity.getCustomId() != null) {
            for (WebCustomAnalysisTable table : tables) {
                if (!table.getCustomId().equals(entity.getCustomId()) || StatusConstants.PASSED_STATUS.equals(table.getStatus())) {
                    throw ServiceException.exception(Constants.NOT_PERMIT);
                }
            }
        }
        repository.delete(tables);
    }

    private void sendManager(WebCustomAnalysisTable table) throws ServiceException {
        if (!StatusConstants.APPLY_STATUS.equals(table.getStatus())) {
            return;
        }

        CustomInfoTable customInfoTable = customInfoRepository.getFirstById(table.getCustomId());

        if (customInfoTable == null) {
            throw ServiceException.exception(Constants.SYSTEM_ERROR);
        }
        SysConfigTable sysConfigTable = sysConfigService.getByCode(ConfigConstants.MANAGER_CUSTOM_ANALYSIS_EMAIL);
        if (sysConfigTable == null) {
            throw new ServiceException(Constants.SYSTEM_ERROR);
        }
        String users = sysConfigTable.getValue();

        if (users == null) {
            throw new ServiceException(Constants.SYSTEM_ERROR);
        }

        //构建map 用于后面邮件模版替换
        Map<String, String> map = new HashMap<>(10);

        map.put(MapConstants.C_ID, customInfoTable.getCId() + "");
        map.put(MapConstants.APPLY_TIME, DateUtil.formatTime(new Date()));
        map.put(MapConstants.DATE_TIME, DateUtil.formatTime(new Date()));
        map.put(MapConstants.EMAIL, customInfoTable.getEmail());

        SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
        sysEmailSendEntity.setSubject("核验审核通知");
        sysEmailSendEntity.setMap(map);
        sysEmailSendEntity.setTemplateName(EmailTemplateConstants.MANAGER_CUSTOM_ANALYSIS);
        sysEmailSendEntity.setUsers(users);
        try {
            emailService.sendEmail(sysEmailSendEntity);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
