package com.xhpc.card.service.impl;

import com.xhpc.card.domain.*;
import com.xhpc.card.mapper.XhpcMessageBoardMapper;
import com.xhpc.card.mapper.XhpcMessageBoardReceiveUserMapper;
import com.xhpc.card.pojo.XhpcMessageBoard;
import com.xhpc.card.pojo.XhpcMessageBoardReceiveUser;
import com.xhpc.card.service.XhpcMessageBoardService;
import com.xhpc.common.api.UserTypeService;
import com.xhpc.common.core.domain.R;
import com.xhpc.common.core.utils.DateUtils;
import com.xhpc.common.redis.service.RedisService;
import com.xhpc.common.security.service.TokenService;
import com.xhpc.common.util.DateUtil;
import com.xhpc.common.util.MyPagingUtil;
import com.xhpc.system.api.domain.SysUser;
import com.xhpc.system.api.model.LoginUser;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * 留言板实现类
 *
 * @author WH
 */
@Service
public class XhpcMessageBoardServiceImpl implements XhpcMessageBoardService {

    @Resource
    TokenService tokenService;
    @Resource
    XhpcMessageBoardMapper messageBoardMapper;
    @Resource
    XhpcMessageBoardReceiveUserMapper xhpcMessageBoardReceiveUserMapper;
    @Resource
    RedisService redisService;
    @Resource
    UserTypeService userTypeService;


    /**
     * 将用户发送的信息保存到数据库中
     *
     * @param userMessage 用户发送的信息
     * @author WH
     * @date 2022/1/10 14:17
     * @since version-1.0
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void writeUserMessageToDb(SendMessageToPlatformRequest userMessage) {
        //解析Token，获取用户与平台用户信息
        LoginUser loginUser = tokenService.getLoginUser();
        String userRedisKey = "userMessageValidTime:" + loginUser.getUserType() + ":" + loginUser.getUserid() + ":" + userMessage.getTenantType() + ":" + userMessage.getTenantId();
        //使用Redis判断消息发送是否大于5分钟：
        Object cacheObject = redisService.getCacheObject(userRedisKey);
        String currentTime;
        String platformRedisKey = "PlatformMessageValidTime:" + userMessage.getTenantType() + ":" + userMessage.getTenantId() + ":" + loginUser.getUserType() + ":" + loginUser.getUsername();
        if (cacheObject == null) {
            //设置当前时间
            currentTime = DateUtil.getYyyyMmDdHhMmSs();
            redisService.setCacheObject(userRedisKey, currentTime);
            redisService.expire(userRedisKey, 60 * 5);
            //设置平台RedisKey的有效时间，保证双方时间数据同步
            redisService.setCacheObject(platformRedisKey, currentTime);
            redisService.expire(platformRedisKey, 60 * 5);
            userMessage.setSendMessageTime(currentTime);
            userMessage.setSenderAccount(loginUser.getUsername());
            userMessage.setSenderType(loginUser.getUserType());
            messageBoardMapper.insertUserTimeMessageRecord(userMessage);
            messageBoardMapper.insertUserMessage(userMessage);
            XhpcMessageBoardReceiveUser receiverUser = xhpcMessageBoardReceiveUserMapper.findOneByCondition(userMessage);
            if (receiverUser == null) {
                XhpcMessageBoardReceiveUser xhpcMessageBoardReceiveUser = new XhpcMessageBoardReceiveUser();
                BeanUtils.copyProperties(userMessage, xhpcMessageBoardReceiveUser);
                //发送请求所返回的响应信息
                R<Map<String, Object>> result = userTypeService.getUser(null, loginUser.getUserid(), loginUser.getUserType(), null, userMessage.getTenantId());
                Map<String, Object> userInfo = result.getData();
                if(userInfo !=null && userInfo.get("avatar") !=null){
                    String avatar = (String) userInfo.get("avatar");
                    xhpcMessageBoardReceiveUser.setUserIcon(avatar);
                }
                xhpcMessageBoardReceiveUser.setHaveNewInfo(0);
                xhpcMessageBoardReceiveUserMapper.insertSelective(xhpcMessageBoardReceiveUser);
            } else {
                xhpcMessageBoardReceiveUserMapper.updateHaveNewInfoFiledByUserCondition(userMessage);
                xhpcMessageBoardReceiveUserMapper.setDelFlag(userMessage);
            }
        } else {
            //reset redis key valid time
            redisService.expire(userRedisKey, 60 * 5);
            redisService.expire(platformRedisKey, 60 * 5);
            currentTime = (String) cacheObject;
            userMessage.setSendMessageTime(currentTime);
            //设置用户账号，用户类型
            userMessage.setSenderAccount(loginUser.getUsername());
            userMessage.setSenderType(loginUser.getUserType());
            messageBoardMapper.insertUserMessage(userMessage);
            //向租户显示的列表中添加该用户信息，表示该用户来新消息了，如果列表中已经有该用户了，则只更新状态即可。
            XhpcMessageBoardReceiveUser receiverUser = xhpcMessageBoardReceiveUserMapper.findOneByCondition(userMessage);
            if (receiverUser == null) {
                XhpcMessageBoardReceiveUser xhpcMessageBoardReceiveUser = new XhpcMessageBoardReceiveUser();
                BeanUtils.copyProperties(userMessage, xhpcMessageBoardReceiveUser);
                //发送请求所返回的响应信息
                R<Map<String, Object>> result = userTypeService.getUser(null, loginUser.getUserid(), loginUser.getUserType(), null, userMessage.getTenantId());
                Map<String, Object> userInfo = result.getData();
                if(userInfo !=null && userInfo.get("avatar")!=null){
                    String avatar = (String) userInfo.get("avatar");
                    xhpcMessageBoardReceiveUser.setUserIcon(avatar);
                }
                xhpcMessageBoardReceiveUser.setHaveNewInfo(0);
                xhpcMessageBoardReceiveUserMapper.insertSelective(xhpcMessageBoardReceiveUser);
            } else {
                xhpcMessageBoardReceiveUserMapper.updateHaveNewInfoFiledByUserCondition(userMessage);
                xhpcMessageBoardReceiveUserMapper.setDelFlag(userMessage);
            }
        }
    }

    /**
     * 将平台（租户）发送的信息保存到数据库中
     *
     * @param platformRequest 平台消息
     * @author WH
     * @date 2022/1/11 13:58
     * @since version-1.0
     */
    @Override
    public void platformSendMessageToUser(PlatformSendMessageToUserRequest platformRequest) {

        //获取平台用户信息
        SysUser sysUser = tokenService.getLoginUser().getSysUser();
        //使用redis控制发送时间
        String platformRedisKey = "PlatformMessageValidTime:" + "0:" + sysUser.getTenantId() + ":" + platformRequest.getSenderType() + ":" + platformRequest.getSenderAccount();
        Object cacheObject = redisService.getCacheObject(platformRedisKey);
        String currentTime;
        String userRedisKey = "userMessageValidTime:" + platformRequest.getSenderType() + ":" + platformRequest.getSenderAccount() + ":" + "0:" + sysUser.getTenantId();
        if (cacheObject == null) {
            //设置当前时间
            currentTime = DateUtil.getYyyyMmDdHhMmSs();
            redisService.setCacheObject(platformRedisKey, currentTime);
            redisService.expire(platformRedisKey, 60 * 5);
            //设置用户RedisKey的有效时间，保证双方时间数据同步
            redisService.setCacheObject(userRedisKey, currentTime);
            redisService.expire(userRedisKey, 60 * 5);
            platformRequest.setSendMessageTime(currentTime);
            platformRequest.setTenantId(sysUser.getTenantId());
            platformRequest.setTenantType(0);
            messageBoardMapper.insertPlatformTimeMessageRecord(platformRequest);
            messageBoardMapper.insertPlatformMessage(platformRequest);
        }
        //reset redis key valid time
        redisService.expire(platformRedisKey, 60 * 5);
        redisService.expire(userRedisKey, 60 * 5);
        platformRequest.setSendMessageTime((String) cacheObject);
        platformRequest.setTenantId(sysUser.getTenantId());
        platformRequest.setTenantType(0);
        messageBoardMapper.insertPlatformMessage(platformRequest);
        //往Redis中放置用户未读数量
        String userNotReadCount = "userNotReadMessageCount:" + platformRequest.getSenderType() + ":" + platformRequest.getSenderAccount() + ":" + "0:" + sysUser.getTenantId();
        Object cacheObject1 = redisService.getCacheObject(userNotReadCount);
        if (cacheObject1 == null) {
            redisService.setCacheObject(userNotReadCount, 1);
        } else {
            Integer userNotReadNum = (Integer) cacheObject1 + 1;
            redisService.setCacheObject(userNotReadCount, userNotReadNum);
        }
    }

    /**
     * 根据用户条件，查询指定的数据库中的记录
     *
     * @param userQueryCondition 用户传入的条件
     * @return 用户在数据库中发送的记录
     * @author WH
     * @date 2022/1/12 15:30
     * @since version-1.0
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public QueryUserMassageResponse queryUserMessage(UserQueryCondition userQueryCondition) {
        //完善条件集合
        LoginUser loginUser = tokenService.getLoginUser();
        userQueryCondition.setSenderAccount(loginUser.getUsername());
        userQueryCondition.setSenderType(loginUser.getUserType());
        String nextTimeStr = null;
        if ("".equals(userQueryCondition.getSendMessageTime()) || userQueryCondition.getSendMessageTime() == null || "null".equals(userQueryCondition.getSendMessageTime())) {
            userQueryCondition.setSendMessageTime(DateUtil.getYyyyMmDdHhMmSs());
            //查询用户是否有数据，即查询该用户的所有时间记录（有时间记录表示该用户发送过信息）
            List<XhpcMessageBoard> allTimeRecords = messageBoardMapper.selectTimeRecords(userQueryCondition);
            QueryUserMassageResponse queryUserMassageResponse = new QueryUserMassageResponse();
            if (allTimeRecords.size() == 0) {
                return queryUserMassageResponse;
            }
            //获取最后一个时间记录，将其减去一个月，放入查询条件中
            XhpcMessageBoard xhpcMessageBoard = allTimeRecords.get(allTimeRecords.size() - 1);
            Date finalTime = xhpcMessageBoard.getSendMessageTime();
            userQueryCondition.setSendMessageTime(DateUtils.parseDateToStr(finalTime));
            Calendar finalTimeCalendar = DateUtil.getCalendar(finalTime);
            finalTimeCalendar.add(Calendar.MONTH, -1);
            Date nextTime = finalTimeCalendar.getTime();
            nextTimeStr = DateUtils.parseDateToStr(nextTime);
        } else {
            //如果有值过来，说明有之前的记录，计算上一个月的值，作为查询条件，并返回
            String sendMessageTimeStr = userQueryCondition.getSendMessageTime();
            Date sendMessageTimeDate = DateUtils.parseDate(sendMessageTimeStr);
            Calendar nextTimeCalendar = DateUtil.getCalendar(sendMessageTimeDate);
            nextTimeCalendar.add(Calendar.MONTH, -1);
            Date nextTime = nextTimeCalendar.getTime();
            nextTimeStr = DateUtils.parseDateToStr(nextTime);
        }
        //根据用户信息中所保存的时间，与上个月时间进行区间查询
        List<XhpcMessageBoard> aMonthRecords = messageBoardMapper.selectBy(userQueryCondition, nextTimeStr);
        //如果没有数据，则返回空实体类对象
        QueryUserMassageResponse response = new QueryUserMassageResponse();
        if (aMonthRecords.isEmpty()) {
            return response;
        }
        List<Long> messageIdList = new ArrayList<>();
        for (int index = 0; index <= aMonthRecords.size() - 1; index++) {
            Long messageId = aMonthRecords.get(index).getMessageId();
            messageIdList.add(messageId);
        }
        //设置查询出来的记录为已读状态，然后再查询，保证查询出来的是否有新信息状态被改变
        messageBoardMapper.setUserReadedStatus(messageIdList);
        aMonthRecords = messageBoardMapper.selectBy(userQueryCondition, nextTimeStr);
        //封装数据
        ArrayList<QueryUserMassageResponse.DataDTO> dataDTOS = new ArrayList<>();
        for (XhpcMessageBoard aMonthRecord : aMonthRecords) {
            QueryUserMassageResponse.DataDTO dataDTO = new QueryUserMassageResponse.DataDTO();
            BeanUtils.copyProperties(aMonthRecord, dataDTO);
            dataDTO.setSendMessageTime(DateUtils.parseDateToStr(aMonthRecord.getSendMessageTime()));
            dataDTOS.add(dataDTO);
        }
        //处理下次查询时间
        response.setNextQueryTime(nextTimeStr);
        response.setData(dataDTOS);
        //获取redis中用户未读信息数量，将其置为null
        String userNotReadCount = "userNotReadMessageCount:" + userQueryCondition.getSenderType() + ":" + userQueryCondition.getSenderAccount() + ":" + "0:" + userQueryCondition.getTenantId();
        Object cacheObject = redisService.getCacheObject(userNotReadCount);
        if (cacheObject != null) {
            redisService.deleteObject(userNotReadCount);
        }
        return response;
    }

    /**
     * 根据租户id和租户类型查询指定的租户头像
     *
     * @param tenantId   租户id
     * @param tenantType 租户类型
     * @return 头像地址
     * @author WH
     * @date 2022/1/13 18:30
     * @since version-1.0
     */
    @Override
    public String returnPlatformAvatar(String tenantId, Integer tenantType) {

        SysUser sysUser = tokenService.getLoginUser().getSysUser();
        String avatar = sysUser.getAvatar();
        if (avatar == null) {
            return "https://xhpc-bucket1.oss-cn-hangzhou.aliyuncs.com/avatar/logo.png";
        } else {
            return avatar;
        }
    }

    /**
     * 平台用户查询哪些用户发留言了的列表
     *
     * @param param query list condition
     * @return 发了信息的用户列表
     * @author WH
     * @date 2022/1/14 11:25
     * @since version-1.0
     */
    @Override
    public QueryUserListResponse queryUserList(QueryUserListRequest param) throws Exception {
        //计算分页索引
        int startIndex = MyPagingUtil.calculateStartIndex(param.getCurrentPage(), param.getItems());
        param.setCurrentPage(startIndex);
        //查询用户列表
        SysUser receiverInfo = tokenService.getLoginUser().getSysUser();
        param.setTenantId(receiverInfo.getTenantId());
        param.setTenantType(0);
        QueryUserListResponse queryUserListResponse = new QueryUserListResponse();
        //查询出该租户拥有的所有用户列表
        List<XhpcMessageBoardReceiveUser> userList = xhpcMessageBoardReceiveUserMapper.findAllBy(param);
        if (userList.isEmpty()) {
            return queryUserListResponse;
        }
        List<QueryUserListResponse.DataDTO> dataDtoList = new ArrayList<>();
        for (XhpcMessageBoardReceiveUser receiveUser : userList) {
            QueryUserListResponse.DataDTO dataDTO = new QueryUserListResponse.DataDTO();
            BeanUtils.copyProperties(receiveUser, dataDTO);
            dataDTO.setUserAccount(receiveUser.getSenderAccount());
            dataDTO.setUserType(receiveUser.getSenderType());
            dataDtoList.add(dataDTO);
        }
        queryUserListResponse.setData(dataDtoList);
        //获取该租户总共有多少个用户给他发送了留言
        Long totalUserNumber = xhpcMessageBoardReceiveUserMapper.totalUserNumber(param);
        queryUserListResponse.setTotalItems(totalUserNumber);
        return queryUserListResponse;
    }

    /**
     * 平台查询用户发送过来的信息，与用户查看它自己的信息的代码逻辑一致
     *
     * @param userQueryCondition 要查询的用户的信息
     * @return 返回用户与平台用户的一个月的聊天记录
     * @author WH
     * @date 2022/1/16 15:39
     * @since version-1.0
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public QueryUserMassageResponse platformQueryMessage(UserQueryCondition userQueryCondition) {
        //完善条件集合
        SysUser sysUser = tokenService.getLoginUser().getSysUser();
        userQueryCondition.setTenantId(sysUser.getTenantId());
        userQueryCondition.setTenantType(0);
        String nextTimeStr = null;
        if ("".equals(userQueryCondition.getSendMessageTime()) || userQueryCondition.getSendMessageTime() == null || "null".equals(userQueryCondition.getSendMessageTime())) {
            userQueryCondition.setSendMessageTime(DateUtil.getYyyyMmDdHhMmSs());
            //查询用户是否有数据，即查询该用户的所有时间记录（有时间记录表示该用户发送过信息）
            List<XhpcMessageBoard> allTimeRecords = messageBoardMapper.selectTimeRecords(userQueryCondition);
            QueryUserMassageResponse queryUserMassageResponse = new QueryUserMassageResponse();
            if (allTimeRecords.isEmpty()) {
                return queryUserMassageResponse;
            }
            //获取最后一个时间记录，将其减去一个月，放入查询条件中
            XhpcMessageBoard xhpcMessageBoard = allTimeRecords.get(allTimeRecords.size() - 1);
            Date finalTime = xhpcMessageBoard.getSendMessageTime();
            userQueryCondition.setSendMessageTime(DateUtils.parseDateToStr(finalTime));
            Calendar finalTimeCalendar = DateUtil.getCalendar(finalTime);
            finalTimeCalendar.add(Calendar.MONTH, -1);
            Date nextTime = finalTimeCalendar.getTime();
            nextTimeStr = DateUtils.parseDateToStr(nextTime);
        } else {
            //如果有值过来，说明有之前的记录，计算上一个月的值，作为查询条件，并返回
            String sendMessageTimeStr = userQueryCondition.getSendMessageTime();
            Date sendMessageTimeDate = DateUtils.parseDate(sendMessageTimeStr);
            Calendar nextTimeCalendar = DateUtil.getCalendar(sendMessageTimeDate);
            nextTimeCalendar.add(Calendar.MONTH, -1);
            Date nextTime = nextTimeCalendar.getTime();
            nextTimeStr = DateUtils.parseDateToStr(nextTime);
        }
        //根据用户信息中所保存的时间，与上个月时间进行区间查询
        List<XhpcMessageBoard> aMonthRecords = messageBoardMapper.selectBy(userQueryCondition, nextTimeStr);
        //如果没有数据，则返回空实体类对象
        QueryUserMassageResponse response = new QueryUserMassageResponse();
        if (aMonthRecords.isEmpty()) {
            return response;
        }
        List<Long> messageIdList = new ArrayList<>();
        for (int index = 0; index <= aMonthRecords.size() - 1; index++) {
            Long messageId = aMonthRecords.get(index).getMessageId();
            messageIdList.add(messageId);
        }
        //设置查询出来的记录为已读状态，然后再查询，保证查询出来的信息状态被改变
        messageBoardMapper.setUserReadedStatus(messageIdList);
        aMonthRecords = messageBoardMapper.selectBy(userQueryCondition, nextTimeStr);
        //消除后台留言板红点
        xhpcMessageBoardReceiveUserMapper.updateHaveNewInfoIsNull(userQueryCondition);
        //封装数据
        ArrayList<QueryUserMassageResponse.DataDTO> dataDTOS = new ArrayList<>();
        for (XhpcMessageBoard aMonthRecord : aMonthRecords) {
            QueryUserMassageResponse.DataDTO dataDTO = new QueryUserMassageResponse.DataDTO();
            BeanUtils.copyProperties(aMonthRecord, dataDTO);
            dataDTO.setSendMessageTime(DateUtils.parseDateToStr(aMonthRecord.getSendMessageTime()));
            dataDTOS.add(dataDTO);
        }
        //处理下次查询时间
        response.setNextQueryTime(nextTimeStr);
        response.setData(dataDTOS);
        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteListUser(UserInfo userInfo) {

        SysUser sysUser = tokenService.getLoginUser().getSysUser();
        userInfo.setTenantId(sysUser.getTenantId());
        userInfo.setTenantType(0);
        UserQueryCondition userQueryCondition = new UserQueryCondition();
        BeanUtils.copyProperties(userInfo, userQueryCondition);
        userQueryCondition.setSenderType(userInfo.getUserType());
        userQueryCondition.setSenderAccount(userInfo.getUserAccount());
        xhpcMessageBoardReceiveUserMapper.updateDelFlag(userQueryCondition);

    }

}
