package ink.wgink.module.instantmessage.service.impl;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.interfaces.user.IUserBaseService;
import ink.wgink.module.instantmessage.dao.INoticeDao;
import ink.wgink.module.instantmessage.pojo.dtos.NoticeDTO;
import ink.wgink.module.instantmessage.pojo.pos.NoticePO;
import ink.wgink.module.instantmessage.pojo.vos.NoticeSendVO;
import ink.wgink.module.instantmessage.pojo.vos.NoticeVO;
import ink.wgink.module.instantmessage.service.INoticeService;
import ink.wgink.module.instantmessage.websocket.pojo.body.CountNeedToDealWithBody;
import ink.wgink.pojo.ListPage;
import ink.wgink.pojo.dtos.user.UserDTO;
import ink.wgink.pojo.result.SuccessResultList;
import ink.wgink.util.UUIDUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * When you feel like quitting. Think about why you started
 * 当你想要放弃的时候，想想当初你为何开始
 *
 * @ClassName: NoticeServiceImpl
 * @Description: 消息通知
 * @Author: wanggeng
 * @Date: 2021/3/29 4:36 下午
 * @Version: 1.0
 */
@Service
public class NoticeServiceImpl extends DefaultBaseService implements INoticeService {

    @Autowired
    private INoticeDao noticeDao;
    @Autowired
    private IUserBaseService userBaseService;

    @Override
    public void save(UserDTO userDTO, NoticeVO.Notice notice, boolean isSend) throws Exception {
        if (userDTO == null) {
            return;
        }
        if (StringUtils.isBlank(notice.getSystem())) {
            return;
        }
        if (StringUtils.isBlank(notice.getServiceId())) {
            return;
        }
        List<NoticePO> noticePOs = listPO(notice.getSystem(), notice.getModule(), notice.getMenu(), notice.getServiceId(), userDTO.getUserId());
        if (!noticePOs.isEmpty()) {
            LOG.debug("通知已经存在");
            return;
        }
        Map<String, Object> params = getHashMap(16);
        params.put("noticeId", UUIDUtil.getUUID());
        params.put("userId", userDTO.getUserId());
        params.put("userName", userDTO.getUserName());
        params.put("userUsername", userDTO.getUserUsername());
        params.put("noticeTitle", notice.getTitle());
        params.put("noticeMsg", notice.getMsg());
        params.put("noticeTarget", notice.getTarget());
        params.put("noticeSystem", notice.getSystem());
        params.put("noticeModule", notice.getModule());
        params.put("noticeMenu", notice.getMenu());
        params.put("noticeServiceId", notice.getServiceId());
        params.put("isSend", isSend ? 1 : 0);
        params.put("isHandle", 0);
        setSaveInfoByUserId(params, "1");
        noticeDao.save(params);
    }

    @Override
    public void updateHandleStatus(String userId, CountNeedToDealWithBody countNeedToDealWithBody) {
        if (StringUtils.isBlank(countNeedToDealWithBody.getSystem())) {
            return;
        }
        if (StringUtils.isBlank(countNeedToDealWithBody.getServiceId())) {
            return;
        }
        Map<String, Object> params = getHashMap(6);
        params.put("isHandle", 1);
        params.put("noticeSystem", countNeedToDealWithBody.getSystem());
        params.put("noticeServiceId", countNeedToDealWithBody.getServiceId());
        setUpdateInfoByUserId(params, userId);
        noticeDao.updateHandle(params);
    }

    @Override
    public void updateSendStatus(String noticeId, int isSend) {
        Map<String, Object> params = getHashMap(4);
        params.put("noticeId", noticeId);
        params.put("isSend", isSend);
        setUpdateInfoByUserId(params, "1");
        noticeDao.updateSend(params);
    }

    @Override
    public NoticePO getPO(Map<String, Object> params) {
        return noticeDao.getPO(params);
    }

    @Override
    public NoticePO getPO(String serviceId, String userId) {
        Map<String, Object> params = getHashMap(4);
        params.put("noticeServiceId", serviceId);
        params.put("userId", userId);
        return getPO(params);
    }

    @Override
    public NoticePO getPO(String system, String serviceId, String userId) {
        Map<String, Object> params = getHashMap(6);
        params.put("noticeSystem", system);
        params.put("noticeServiceId", serviceId);
        params.put("userId", userId);
        return getPO(params);
    }

    @Override
    public NoticePO getPO(String system, String module, String serviceId, String userId) {
        Map<String, Object> params = getHashMap(8);
        params.put("noticeSystem", system);
        params.put("noticeModule", module);
        params.put("noticeServiceId", serviceId);
        params.put("userId", userId);
        return getPO(params);
    }

    @Override
    public NoticePO getPO(String system, String module, String menu, String serviceId, String userId) {
        Map<String, Object> params = getHashMap(10);
        params.put("noticeSystem", system);
        params.put("noticeModule", module);
        params.put("noticeMenu", menu);
        params.put("noticeServiceId", serviceId);
        params.put("userId", userId);
        return getPO(params);
    }

    @Override
    public List<NoticePO> listPO(Map<String, Object> params) {
        return noticeDao.listPO(params);
    }

    @Override
    public List<NoticePO> listPO(String serviceId, String userId) {
        Map<String, Object> params = getHashMap(4);
        params.put("noticeServiceId", serviceId);
        params.put("userId", userId);
        return listPO(params);
    }

    @Override
    public List<NoticePO> listPO(String system, String serviceId, String userId) {
        Map<String, Object> params = getHashMap(6);
        params.put("noticeSystem", system);
        params.put("noticeServiceId", serviceId);
        params.put("userId", userId);
        return listPO(params);
    }

    @Override
    public List<NoticePO> listPO(String system, String module, String serviceId, String userId) {
        Map<String, Object> params = getHashMap(8);
        params.put("noticeSystem", system);
        params.put("noticeModule", module);
        params.put("noticeServiceId", serviceId);
        params.put("userId", userId);
        return listPO(params);
    }

    @Override
    public List<NoticePO> listPO(String system, String module, String menu, String serviceId, String userId) {
        Map<String, Object> params = getHashMap(10);
        params.put("noticeSystem", system);
        params.put("noticeModule", module);
        params.put("noticeMenu", menu);
        params.put("noticeServiceId", serviceId);
        params.put("userId", userId);
        return listPO(params);
    }

    @Override
    public List<CountNeedToDealWithBody> listNoticeCount(String userId, CountNeedToDealWithBody countNeedToDealWithBody) {
        List<CountNeedToDealWithBody> noticeCounts = new ArrayList<>();
        Map<String, Object> params = getHashMap(10);
        params.put("userId", userId);
        params.put("isHandle", 0);
        if (StringUtils.isBlank(countNeedToDealWithBody.getSystem())) {
            // 系统为空，按系统统计
            List<String> systems = listSystems(userId);
            for (String system : systems) {
                params.put("noticeSystem", system);
                CountNeedToDealWithBody systemCount = new CountNeedToDealWithBody();
                systemCount.setSystem(system);
                systemCount.setCount(count(params));
                noticeCounts.add(systemCount);
            }
        } else if (StringUtils.isBlank(countNeedToDealWithBody.getModule())) {
            // 模块为空，按模块统计
            List<String> modules = listModules(userId, countNeedToDealWithBody.getSystem());
            params.put("noticeSystem", countNeedToDealWithBody.getSystem());
            for (String module : modules) {
                CountNeedToDealWithBody systemCount = new CountNeedToDealWithBody();
                systemCount.setSystem(countNeedToDealWithBody.getSystem());
                systemCount.setModule(module);
                params.put("noticeModule", module);
                systemCount.setCount(count(params));
                noticeCounts.add(systemCount);
            }
        } else if (StringUtils.isBlank(countNeedToDealWithBody.getMenu())) {
            // 菜单为空，按菜单统计
            List<String> menus = listMenus(userId, countNeedToDealWithBody.getSystem(), countNeedToDealWithBody.getModule());
            params.put("noticeSystem", countNeedToDealWithBody.getSystem());
            params.put("noticeModule", countNeedToDealWithBody.getModule());
            for (String menu : menus) {
                CountNeedToDealWithBody systemCount = new CountNeedToDealWithBody();
                systemCount.setSystem(countNeedToDealWithBody.getSystem());
                systemCount.setModule(countNeedToDealWithBody.getModule());
                systemCount.setMenu(menu);
                params.put("noticeMenu", menu);
                systemCount.setCount(count(params));
                noticeCounts.add(systemCount);
            }
        } else {
            // 都不为空，具体菜单数量
            CountNeedToDealWithBody systemCount = new CountNeedToDealWithBody();
            systemCount.setSystem(countNeedToDealWithBody.getSystem());
            systemCount.setModule(countNeedToDealWithBody.getModule());
            systemCount.setMenu(countNeedToDealWithBody.getMenu());
            params.put("noticeSystem", countNeedToDealWithBody.getSystem());
            params.put("noticeModule", countNeedToDealWithBody.getModule());
            params.put("noticeModule", countNeedToDealWithBody.getModule());
            params.put("noticeMenu", countNeedToDealWithBody.getMenu());
            systemCount.setCount(count(params));
            noticeCounts.add(systemCount);
        }
        return noticeCounts;
    }

    @Override
    public Integer count(Map<String, Object> params) {
        Integer count = noticeDao.count(params);
        return count == null ? 0 : count;
    }

    @Override
    public void deleteByServiceIds(List<String> serviceIds) {
        Map<String, Object> params = getHashMap(2);
        params.put("serviceIds", serviceIds);
        noticeDao.delete(params);
    }

    @Override
    public void remove(List<String> noticeIds) {
        Map<String, Object> params = getHashMap(2);
        params.put("noticeIds", noticeIds);
        setUpdateInfo(params);
        noticeDao.remove(params);
    }

    @Override
    public List<NoticePO> listPO(List<String> serviceIds) {
        Map<String, Object> params = getHashMap(2);
        params.put("serviceIds", serviceIds);
        return listPO(params);
    }

    @Override
    public List<NoticeDTO> list(Map<String, Object> params) {
        return noticeDao.list(params);
    }

    @Override
    public SuccessResultList<List<NoticeDTO>> listPage(ListPage page) {
        PageHelper.startPage(page.getPage(), page.getRows());
        List<NoticeDTO> noticeDTOs = list(page.getParams());
        PageInfo<NoticeDTO> pageInfo = new PageInfo<>(noticeDTOs);
        return new SuccessResultList<>(noticeDTOs, pageInfo.getPageNum(), pageInfo.getTotal());
    }

    @Override
    public void notice(NoticeSendVO noticeSendVO) throws Exception {
        String noticeUserIdsString = noticeSendVO.getNoticeUserIds();
        List<String> noticeUserIds = Arrays.asList(noticeUserIdsString.split("\\_"));
        NoticeVO.Notice notice = new NoticeVO.Notice();
        notice.setUserIds(noticeUserIds);
    }

    @Override
    public List<NoticePO> listPOByDate(String date) {
        Map<String, Object> params = getHashMap(2);
        params.put("date", date);
        return listPO(params);
    }

    @Override
    public List<NoticePO> listPOByStartTimeAndEndTime(String startTime, String endTime) {
        Map<String, Object> params = getHashMap(4);
        params.put("startTime", startTime);
        params.put("endTime", endTime);
        return listPO(params);
    }

    @Override
    public List<NoticePO> listPOByUserIdAndIsSend(String userId, int isSend) {
        Map<String, Object> params = getHashMap(4);
        params.put("userId", userId);
        params.put("isSend", isSend);
        return listPO(params);
    }

    /**
     * 系统列表
     *
     * @param userId
     * @return
     */
    private List<String> listSystems(String userId) {
        Map<String, Object> params = getHashMap(2);
        params.put("userId", userId);
        return noticeDao.listSystems(params);
    }

    /**
     * 模块列表
     *
     * @param userId
     * @return
     */
    private List<String> listModules(String userId, String noticeSystem) {
        Map<String, Object> params = getHashMap(4);
        params.put("userId", userId);
        params.put("noticeSystem", noticeSystem);
        return noticeDao.listModules(params);
    }

    /**
     * 菜单列表
     *
     * @param userId
     * @return
     */
    private List<String> listMenus(String userId, String noticeSystem, String noticeModule) {
        Map<String, Object> params = getHashMap(6);
        params.put("userId", userId);
        params.put("noticeSystem", noticeSystem);
        params.put("noticeModule", noticeModule);
        return noticeDao.listMenus(params);
    }

    /**
     * 设置用户
     *
     * @param noticeDTOs
     */
    private void setUser(List<NoticeDTO> noticeDTOs) {
        if (noticeDTOs.isEmpty()) {
            return;
        }
        Set<String> userIdSet = new HashSet<>();
        for (NoticeDTO noticeDTO : noticeDTOs) {
            userIdSet.add(noticeDTO.getUserId());
        }
        List<UserDTO> userDTOs = userBaseService.listByUserIds(new ArrayList<>(userIdSet));
        if (userDTOs.isEmpty()) {
            return;
        }
        for (NoticeDTO noticeDTO : noticeDTOs) {
            for (UserDTO userDTO : userDTOs) {
                if (StringUtils.equals(noticeDTO.getUserId(), userDTO.getUserId())) {
                    noticeDTO.setUserName(userDTO.getUserName());
                    break;
                }
            }
        }
    }

}
