package com.ruoyi.frequency.appmessage.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.code.PublicCommon;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.page.PageResult;
import com.ruoyi.controller.req.MessageReadOrDeleteReq;
import com.ruoyi.enums.message.AppMessageEnums;
import com.ruoyi.enums.user.UserEnums;
import com.ruoyi.frequency.appmessage.entity.AppMessage;
import com.ruoyi.frequency.appmessage.mapper.AppMessageMapper;
import com.ruoyi.frequency.appmessage.model.param.AppMessageParam;
import com.ruoyi.frequency.appmessage.service.AppMessageService;
import com.ruoyi.frequency.customer.entity.Customer;
import com.ruoyi.frequency.customer.mapper.UserMapper;
import com.ruoyi.frequency.customer.service.CustomerService;
import com.ruoyi.frequency.customer.service.UserService;
import com.ruoyi.frequency.sale.entity.Sale;
import com.ruoyi.frequency.sale.service.SaleService;
import com.ruoyi.frequency.store.entity.Store;
import com.ruoyi.frequency.store.service.StoreService;
import com.ruoyi.frequency.userappmessage.entity.UserAppMessage;
import com.ruoyi.frequency.userappmessage.service.UserAppMessageService;
import com.ruoyi.push.service.PushService;
import com.ruoyi.response.ResponseData;
import com.ruoyi.vo.PageBasic;
import com.ruoyi.vo.UserInfo;
import com.ruoyi.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * app端消息Service业务层处理
 *
 * @author liwenlong
 * @date 2023-07-20
 */
@Service
public class AppMessageServiceImpl extends ServiceImpl<AppMessageMapper, AppMessage> implements AppMessageService {
    @Autowired
    private AppMessageMapper appMessageMapper;

    @Autowired
    private UserService userService;

    /**
     * 查询app端消息
     *
     * @param id app端消息主键
     * @return app端消息
     */
    @Override
    public AppMessage selectAppMessageById(Long id) {
        AppMessage appMessage = appMessageMapper.selectAppMessageById(id);

        if (appMessage != null) {
            //查询用户
            if (ObjectUtil.isNotEmpty(appMessage.getUserIds())) {

                Set<UserVo> userVoSet = CollectionUtil.newHashSet();
                Arrays.asList(appMessage.getUserIds().split(",")).stream().forEach(userId -> {
                    userVoSet.add(new UserVo(appMessage.getUserType(), Long.valueOf(userId)));
                });

                Map<UserVo, UserInfo> userVoUserInfoMap = userService.selectUserInfoMap(userVoSet, null);

                appMessage.setUserInfoList(CollectionUtil.newArrayList(userVoUserInfoMap.values()));
            }
        }

        return appMessage;
    }

    /**
     * 查询app端消息列表
     *
     * @param appMessage app端消息
     * @return app端消息
     */
    @Override
    public List<AppMessage> selectAppMessageList(AppMessage appMessage) {
        return appMessageMapper.selectAppMessageList(appMessage);
    }

    /**
     * 新增app端消息
     *
     * @param appMessage app端消息
     * @return 结果
     */
    @Override
    public int insertAppMessage(AppMessage appMessage) {
        //发布消息
        if (ObjectUtil.equal(2, appMessage.getHasRelease())) {
            appMessage.setReleaseTime(new Date());
        }
        appMessageMapper.insert(appMessage);

        //发布消息
        if (ObjectUtil.equal(2, appMessage.getHasRelease())) {
            sendMessage(appMessage);
        }

        return 1;
    }

    /**
     * 修改app端消息
     *
     * @param appMessage app端消息
     * @return 结果
     */
    @Override
    public int updateAppMessage(AppMessage appMessage) {

        //判断消息是否发布
        AppMessage appMessage2 = this.getById(appMessage.getId());

        //发布消息
        if (ObjectUtil.equal(2, appMessage2.getHasRelease())) {
            throw new ServiceException("消息已发布，不能修改");
        }

        appMessage.setUpdateData();
        //发布消息
        if (ObjectUtil.equal(2, appMessage.getHasRelease())) {
            appMessage.setReleaseTime(new Date());
        }

        int i = appMessageMapper.updateAppMessage(appMessage);

        if (i > 0 && ObjectUtil.equal(2, appMessage.getHasRelease())) {
            //发送消息
            sendMessage(appMessage2);
        }
        return i;
    }

    /**
     * 批量删除app端消息
     *
     * @param ids 需要删除的app端消息主键
     * @return 结果
     */
    @Override
    public int deleteAppMessageByIds(Long[] ids, Integer delFlag) {
        this.lambdaUpdate().set(AppMessage::getDelFlag, delFlag).in(AppMessage::getId, ids).update();
        return ids.length;
    }

    /**
     * 删除app端消息信息
     *
     * @param id app端消息主键
     * @return 结果
     */
    @Override
    public int deleteAppMessageById(Long id) {
        return appMessageMapper.deleteAppMessageById(id);
    }


    @Override
    public void publish(AppMessageParam appMessageParam) {

        boolean update = this.lambdaUpdate()
                .set(AppMessage::getHasRelease, PublicCommon.Message.发布)
                .set(AppMessage::getReleaseTime, new Date())
                .eq(AppMessage::getId, appMessageParam.getId())
                .eq(AppMessage::getHasRelease, PublicCommon.Message.未发布).update();

        if (update) {
            AppMessage appMessage = this.getById(appMessageParam.getId());
            //发送消息
            sendMessage(appMessage);
        }
    }

    @Autowired
    private UserMapper userMapper;

    @Override
    public List<UserInfo> messageUserPage(AppMessage appMessage) {
        AppMessage appMessage2 = appMessageMapper.selectAppMessageById(appMessage.getId());

        if (appMessage2 == null || ObjectUtil.isEmpty(appMessage2.getUserIds())) {
            return new ArrayList<>();
        }
        Set<UserVo> userVoSet = CollectionUtil.newHashSet();
        Arrays.asList(appMessage2.getUserIds().split(",")).stream().forEach(userId -> {
            userVoSet.add(new UserVo(appMessage2.getUserType(), Long.valueOf(userId)));
        });

        //设计师
        List<Long> customerIds = CollectionUtil.toList();

        //表现师
        List<Long> storeIds = CollectionUtil.toList();

        //销售
        List<Long> saleIds = CollectionUtil.toList();

        //企业
        List<Long> enterpriseIds = CollectionUtil.toList();

        userVoSet.stream().forEach(user -> {
            if (user == null || user.getUserId() == null) {
                return;
            }
            if (user.getUserType() == 1) {
                customerIds.add(user.getUserId());
            } else if (user.getUserType() == 2) {
                storeIds.add(user.getUserId());
            } else if (user.getUserType() == 3) {
                saleIds.add(user.getUserId());
            } else {
                enterpriseIds.add(user.getUserId());
            }
        });

        List<UserInfo> userInfos = userMapper.selectUserInfoList(customerIds, storeIds, saleIds, enterpriseIds, null);

        return userInfos;
    }

    @Autowired
    private CustomerService customerService;

    @Autowired
    private StoreService storeService;

    @Autowired
    private SaleService saleService;

    private void sendMessage(AppMessage entity) {

        List<UserVo> sendUserList = new ArrayList<>();

        switch (entity.getUserType()) {
            case -1:
                List<Customer> customers = customerService.list(new QueryWrapper<Customer>().lambda()
                        .eq(Customer::getCloseMessage, PublicCommon.Message.未关闭)
                        .ne(Customer::getDelFlag, PublicCommon.删除));
                if (customers.size() > 0) {
                    customers.stream().forEach(s -> {
                        sendUserList.add(new UserVo(UserEnums.customer.getCode(), s.getId()));
                    });
                }

                List<Store> stores = storeService.list(new QueryWrapper<Store>().lambda()
                        .eq(Store::getCloseMessage, PublicCommon.Message.未关闭)
                        .ne(Store::getDelFlag, PublicCommon.删除));
                if (stores.size() > 0) {
                    stores.stream().forEach(s -> {
                        sendUserList.add(new UserVo(UserEnums.store.getCode(), s.getId()));
                    });
                }

                List<Sale> sales = saleService.list(new QueryWrapper<Sale>().lambda()
                        .eq(Sale::getCloseMessage, PublicCommon.Message.未关闭)
                        .ne(Sale::getDelFlag, PublicCommon.删除));
                if (sales.size() > 0) {
                    sales.stream().forEach(s -> {
                        sendUserList.add(new UserVo(UserEnums.sale.getCode(), s.getId()));
                    });
                }

                break;
            case 1:
                //推送是否关闭;1 不关闭2  关闭
                LambdaQueryWrapper<Customer> ne1 = new QueryWrapper<Customer>().lambda()
                        .eq(Customer::getCloseMessage, PublicCommon.Message.未关闭)
                        .ne(Customer::getDelFlag, PublicCommon.删除);

                if (ObjectUtil.isNotEmpty(entity.getUserIds())) {
                    ne1.in(Customer::getId, entity.getUserIds().split(","));
                }

                customers = customerService.list(ne1);
                if (!customers.isEmpty()) {
                    customers.stream().forEach(s -> {
                        sendUserList.add(new UserVo(UserEnums.customer, s.getId()));
                    });
                }

                break;
            case 2:

                LambdaQueryWrapper<Store> ne = new QueryWrapper<Store>().lambda()
                        .eq(Store::getCloseMessage, PublicCommon.Message.未关闭)
                        .ne(Store::getDelFlag, PublicCommon.删除);

                if (ObjectUtil.isNotEmpty(entity.getUserIds())) {
                    ne.in(Store::getId, entity.getUserIds().split(","));
                }

                List<Store> stores2 = storeService.list(ne);
                if (stores2.size() > 0) {
                    stores2.stream().forEach(s -> {
                        sendUserList.add(new UserVo(UserEnums.store.getCode(), s.getId()));
                    });
                }

                break;
            case 3:

                LambdaQueryWrapper<Sale> queryWrapper = new QueryWrapper<Sale>().lambda()
                        .eq(Sale::getCloseMessage, PublicCommon.Message.未关闭)
                        .ne(Sale::getDelFlag, PublicCommon.删除);
                if (ObjectUtil.isNotEmpty(entity.getUserIds())) {
                    queryWrapper.in(Sale::getId, entity.getUserIds().split(","));
                }
                List<Sale> sales2 = saleService.list(queryWrapper);
                if (sales2.size() > 0) {
                    sales2.stream().forEach(s -> {
                        sendUserList.add(new UserVo(UserEnums.sale.getCode(), s.getId()));
                    });
                }

                break;

            default:
                throw new IllegalStateException("Unexpected value: " + entity.getUserType());
        }
        //推送消息
        sendThreadMessage(sendUserList, entity.getTitle(), entity.getContent(), entity.getId());
    }


    @Autowired
    private PushService pushService;

    //    @Async("sendToAlias")
    public void sendThreadMessage(List<UserVo> sendUserList, String title, String content, Long messageId) {
        if (sendUserList.size() > 0) {
            sendUserList.stream().forEach(s -> {
                //推送
                pushService.push(s, title, content, s.getUserId(), messageId, AppMessageEnums.APP_MESSAGE);
            });
        }

    }


    @Override
    public Integer systemMessageCount(UserVo userVo) {

        //未读的系统消息数量
        Integer systemMessageCount = baseMapper.messageCenter(userVo);

        return systemMessageCount;
    }

    @Override
    public AppMessage systemMessageNew(UserVo userVo) {
        AppMessage appMessage = baseMapper.systemMessageNew(userVo);

        return appMessage;
    }

    @Autowired
    private UserAppMessageService userAppMessageService;

    @Override
    public ResponseData messagePage(UserVo userVo, PageBasic req) {

        Page<AppMessage> appMessagePage = baseMapper.messagePage(new Page<>(req.getPageNo(), req.getPageSize()), null, userVo);
        if (appMessagePage.getRecords().size() > 0) {
            //系统消息
            List<UserAppMessage> userAppMessages = new ArrayList<>();

            for (AppMessage appMessage : appMessagePage.getRecords()) {
                //组装消息
                userAppMessages = assembleUserMessage(null, appMessage, userVo, userAppMessages);
            }

            if (userAppMessages.size() > 0) {
                userAppMessageService.saveBatch(userAppMessages);
            }
        }
        return ResponseData.success(new PageResult<>(appMessagePage));
    }

    @Override
    public ResponseData appMessageReadOrDelete(MessageReadOrDeleteReq req, UserVo userVo) {
        //查询消息
        List<AppMessage> appMessageList = baseMapper.messagePage(req.getIds(), userVo);

        if (appMessageList.size() == 0) {
            return ResponseData.success();
        }
        //添加用户系统信息集合
        List<UserAppMessage> addUserAppMessages = new ArrayList<>();

        //添加用户系统信息需要删除的集合
        List<Long> userMessageIds = new ArrayList<>();

        for (AppMessage appMessage : appMessageList) {
            if (ObjectUtil.isNotEmpty(appMessage.getUserAppMessageId())) {
                userMessageIds.add(appMessage.getUserAppMessageId());
                continue;
            }
            //组装消息
            addUserAppMessages = assembleUserMessage(req.getType(), appMessage, userVo, addUserAppMessages);
        }

        // 异步添加消息
        if (CollectionUtil.isNotEmpty(addUserAppMessages)) {
            addUserAppMessage(addUserAppMessages);
        }

        //修改已存在用户系统消息记录
        if (CollectionUtil.isNotEmpty(userMessageIds)) {
            deleteOrRead(req, userVo, userMessageIds);
        }

        return ResponseData.success();
    }

    /**
     * 修改
     *
     * @param req
     * @param userVo
     * @param userMessageIds
     */
    private void deleteOrRead(MessageReadOrDeleteReq req, UserVo userVo, List<Long> userMessageIds) {
        //1 标记已读 2 删除消息
        switch (req.getType()) {
            case 1:
                userAppMessageService.lambdaUpdate().set(UserAppMessage::getIsRead, PublicCommon.Message.已读)
                        .eq(UserAppMessage::getUserType, userVo.getUserType())
                        .eq(UserAppMessage::getUserId, userVo.getUserId())
                        .eq(UserAppMessage::getIsRead, PublicCommon.Message.未读)
                        .in(UserAppMessage::getId, userMessageIds).update();
                break;
            case 2:
                userAppMessageService.lambdaUpdate().set(UserAppMessage::getIsShow, PublicCommon.Message.清空)
                        .set(UserAppMessage::getIsRead, PublicCommon.Message.已读)
                        .eq(UserAppMessage::getUserType, userVo.getUserType())
                        .eq(UserAppMessage::getUserId, userVo.getUserId())
                        .eq(UserAppMessage::getIsShow, PublicCommon.Message.未清空)
                        .in(UserAppMessage::getId, userMessageIds).update();
                break;

            default:
                throw new IllegalStateException("Unexpected value: " + req.getType());
        }

    }

    @Async("addUserAppMessage")
    public void addUserAppMessage(List<UserAppMessage> addUserAppMessages) {
        userAppMessageService.saveBatch(addUserAppMessages);

    }

    /**
     * 组装系统用户消息
     *
     * @param appMessage
     * @param userVo
     * @param userAppMessages
     * @return
     */
    private List<UserAppMessage> assembleUserMessage(Integer type, AppMessage appMessage, UserVo userVo, List<UserAppMessage> userAppMessages) {

        if (ObjectUtil.isNotEmpty(appMessage.getUserAppMessageId())) {
            return userAppMessages;
        }

        //组装用户系统消息
        UserAppMessage userAppMessage = new UserAppMessage()
                .setUserId(userVo.getUserId())
                .setUserType(userVo.getUserType())
                .setMessageId(appMessage.getId());

        if (ObjectUtil.isNotEmpty(type)) {
            switch (type) {
                case 1:
                    userAppMessage.setIsRead(PublicCommon.Message.已读);
                    break;
                case 2:
                    userAppMessage.setIsRead(PublicCommon.Message.已读)
                            .setIsShow(PublicCommon.Message.清空);
                    break;
                default:
                    throw new IllegalStateException("Unexpected value: " + type);
            }
        }
        userAppMessages.add(userAppMessage);
        return userAppMessages;

    }

    @Override
    public void addAppMessage(UserVo userVo, Long objectId, AppMessageEnums appMessageEnums) {

        //组装用户系统消息
        AppMessage appMessage = new AppMessage()
                .setMessageType(2)//消息类型 1 群体 2 个人
                .setHasRelease(PublicCommon.Message.发布)
                .setIsSystem(2)//1 平台发布 2 系统生成
                .setReleaseTime(new Date())
                .setUserIds(userVo.getUserId().toString())
                .setUserType(userVo.getUserType())
                .setTitle(appMessageEnums.getTitle())
                .setContent(appMessageEnums.getContent());

        this.save(appMessage);

        //推送
        pushService.push(userVo, objectId, appMessage.getId(), appMessageEnums);
    }

    @Override
    public ResponseData<AppMessage> messageDetail(Long id, UserVo userVo) {
        AppMessage appMessage = baseMapper.messageDetail(id, userVo);

        //已读
        userAppMessageService.lambdaUpdate().set(UserAppMessage::getIsRead, PublicCommon.Message.已读)
                .eq(UserAppMessage::getUserType, userVo.getUserType())
                .eq(UserAppMessage::getUserId, userVo.getUserId())
                .eq(UserAppMessage::getIsRead, PublicCommon.Message.未读)
                .eq(UserAppMessage::getId, appMessage.getUserAppMessageId()).update();

        return ResponseData.success(appMessage);
    }
}
