package com.mmc.iuav.user.service.impl;

import com.mmc.iuav.page.PageResult;
import com.mmc.iuav.response.ResultBody;
import com.mmc.iuav.response.ResultEnum;
import com.mmc.iuav.user.dao.MessageDao;
import com.mmc.iuav.user.dao.UserServiceDao;
import com.mmc.iuav.user.dao.dronepilot.PilotCertificationDao;
import com.mmc.iuav.user.entity.*;
import com.mmc.iuav.user.feign.PaymentAppApi;
import com.mmc.iuav.user.model.qo.MessageQO;
import com.mmc.iuav.user.model.qo.MessageUserQO;
import com.mmc.iuav.user.model.vo.*;
import com.mmc.iuav.user.model.vo.userpoints.ChangeUserPointVO;
import com.mmc.iuav.user.service.MessageService;
import com.mmc.iuav.user.service.userpoints.UserPointsService;
import com.mmc.iuav.user.util.ScheduledTaskUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class MessageServiceImpl implements MessageService {

    @Autowired
    private MessageDao messageDao;

    @Autowired
    private UserServiceDao userServiceDao;

    @Autowired
    private ScheduledTaskUtil scheduledTaskUtil;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private UserPointsService userPointsService;

    @Autowired
    private PilotCertificationDao pilotCertificationDao;

    @Qualifier("com.mmc.iuav.user.feign.PaymentAppApi")
    @Autowired
    private PaymentAppApi paymentAppApi;

    @Override
    public ResultBody insertSystemMessage(SystemMessageVO messageVO) {
        SystemMessageDO systemMessageDO = new SystemMessageDO(messageVO);
        if(messageDao.insertSystemMessage(systemMessageDO) != 0){
            return ResultBody.success("消息发布成功");
        }
        return ResultBody.error("消息发布失败");
    }

    @Override
    public ResultBody selectSystemMessageById(Integer id) {
        return ResultBody.success(messageDao.selectSystemMessageById(id));
    }

    @Override
    public PageResult selectAllSystemMessage(MessageQO messageQO) {
        int count = messageDao.countSystemMessage();
        if (count == 0) {
            return PageResult.buildPage(messageQO.getPageNo(), messageQO.getPageSize(), count);
        }
        Integer pageNo = messageQO.getPageNo();
        messageQO.buildCurrentPage();
        List<SystemMessageDO> messageList = messageDao.selectAllSystemMessage(messageQO);
        return PageResult.buildPage(pageNo, messageQO.getPageSize(), count, messageList);
    }
    @Override
    public ResultBody removeMessage(Integer id) {
        if(messageDao.removeMessage(id) != 0){
            messageDao.removeReceiverMessageByMessageId(id);
            return ResultBody.success("删除成功");
        }
        return ResultBody.error("删除失败");
    }
    @Override
    public PageResult selectAllSystemMessageByReceive(Integer userId, MessageQO messageQO) {
        if(userId == null){
            ResultBody.error("未登录");
        }
        int count = messageDao.countSystemMessage();
        if (count == 0) {
            return PageResult.buildPage(messageQO.getPageNo(), messageQO.getPageSize(), count);
        }
        Integer pageNo = messageQO.getPageNo();
        messageQO.buildCurrentPage();
        List<SystemMessageDO> messagesDO = new ArrayList<>();
        List<SystemMessageDO> messages = messageDao.selectAllSystemMessage(messageQO);
        for (SystemMessageDO message : messages) {
            if(messageDao.selectReceiverMessage(userId, message.getId()) != 0){
                // 已读
                message.setRead(true);
            }
            // 读过但是已经删除
            if(messageDao.selectReceiverMessageByDel(userId, message.getId()) != 0){
                continue;
            }
            messagesDO.add(message);
        }
        return PageResult.buildPage(pageNo, messageQO.getPageSize(), count, messagesDO);
    }

    @Override
    public ResultBody showSystemMessageByUser(Integer userId, Integer messageId) {
        if(userId == null){
            ResultBody.error("未登录");
        }
        SystemMessageDO message = messageDao.selectSystemMessageById(messageId);
        if(message == null){
            return ResultBody.success(message);
        }
        //没有读过,查看之后标为已读
        if(messageDao.selectReceiverMessage(userId, messageId) == 0){
            messageDao.insertReceiverMessage(userId,messageId);
        }
        message.setRead(true);
        // 读过但是已经删除
        if(messageDao.selectReceiverMessageByDel(userId, message.getId()) != 0){
            message = null;
        }
        return ResultBody.success(message);
    }

    @Override
    public ResultBody removeMessageByUser(Integer userId, Integer messageId) {
        if(messageDao.removeReceiverMessage(userId, messageId) != 0){
            return ResultBody.success("删除成功");
        }
        return ResultBody.error("删除失败");
    }

    @Override
    public ResultBody insertUserMessage(UserMessageVO messageVO,Integer senderUserId) {
        UserMessageDO userMessageDO = new UserMessageDO(messageVO);
        if(senderUserId == null){
            return ResultBody.success("消息发送失败,请先登录");
        }
        redisTemplate.setValueSerializer(RedisSerializer.json());
        String s = redisTemplate.opsForValue().get("Message" + senderUserId);
        if(s == null || s == ""){
            return ResultBody.error("请先花费积分购买聊天时长");
        }
        userMessageDO.setSenderUserId(senderUserId);
        if(messageDao.insertUserMessage(userMessageDO) != 0){
            UserAccountDO userAccount = userServiceDao.getUserAccountById(userMessageDO.getReceiverUserId());
            UserDO userDO = userAccount.buildUserDO();
            if(scheduledTaskUtil.check(userDO.getUserAccountId()) == 1){
                scheduledTaskUtil.create(userDO);
            }
            if(messageDao.isUserMessageLog(userMessageDO.getReceiverUserId(), userMessageDO.getSenderUserId()) == null){
                UserMessageLogDO userMessageLogDO = new UserMessageLogDO();
                userMessageLogDO.setSenderUserId(userMessageDO.getSenderUserId());
                userMessageLogDO.setReceiverUserId(userMessageDO.getReceiverUserId());
                messageDao.insertUserMessageLog(userMessageLogDO);
            }
            Integer logId = messageDao.isUserMessageLog(userMessageDO.getSenderUserId(),userMessageDO.getReceiverUserId());
            if(logId == null){
                UserMessageLogDO userMessageLogDO = new UserMessageLogDO();
                userMessageLogDO.setSenderUserId(userMessageDO.getReceiverUserId());
                userMessageLogDO.setReceiverUserId(userMessageDO.getSenderUserId());
                userMessageLogDO.setMessageCount(1);
                messageDao.insertUserMessageLog(userMessageLogDO);
            }else {
                messageDao.updateUserMessageLog(logId);
            }
            return ResultBody.success("消息发送成功");
        }
        return ResultBody.error("消息发送失败");
    }

    /**
     * 查看用户是否购买聊天时长
     *
     * @param UserId
     * @return {@link ResultBody}
     */
    @Override
    public ResultBody isPurchaseTime(Integer UserId) {
        redisTemplate.setValueSerializer(RedisSerializer.json());
        String s = redisTemplate.opsForValue().get("Message" + UserId);
        if(s == null || s == ""){
            return ResultBody.error(ResultEnum.NO_CHAT_ERROR);
        }
        Long seconds  = redisTemplate.getExpire("Message" + UserId, TimeUnit.SECONDS);
        return ResultBody.success(seconds);
    }

    @Override
    public PageResult selectUserMessage(MessageUserQO messageQO,Integer senderUserId) {
        scheduledTaskUtil.destroy(senderUserId);
        int count = messageDao.countUserMessage(messageQO.getReceiverUserId(),senderUserId);
        if (count == 0) {
            return PageResult.buildPage(messageQO.getPageNo(), messageQO.getPageSize(), count);
        }
        Integer pageNo = messageQO.getPageNo();
        messageQO.buildCurrentPage();
        List<UserMessageDO> messageList = messageDao.selectUserMessage(messageQO,senderUserId);
//        Integer logId = messageDao.isUserMessageLog(senderUserId,messageQO.getReceiverUserId());
//        if(logId != null){
//            messageDao.updateUserMessageCount(logId);
//        }
        Integer logId2 = messageDao.isUserMessageLog(messageQO.getReceiverUserId(),senderUserId);
        if(logId2 != null){
            messageDao.updateUserMessageCount(logId2);
        }
        return PageResult.buildPage(pageNo, messageQO.getPageSize(), count, messageList);
    }

    @Override
    public ResultBody selectUserList(Integer senderUserId) {
        List<UserDO> userAccountDOList = new ArrayList<>();
        List<UserMessageLogDO> list = messageDao.selectUserList(senderUserId);
        for (UserMessageLogDO userMessageLogDO : list) {
            UserAccountDO userAccount = userServiceDao.getUserAccountById(userMessageLogDO.getReceiverUserId());
            UserDO userDO = userAccount.buildUserDO();
            userDO.setUnreadCount(userMessageLogDO.getMessageCount());
            UserMessageDO userMessageDO = messageDao.selectEndUserMessage(userMessageLogDO.getReceiverUserId(), senderUserId);
            if(userMessageDO.getContent() != null){
                userDO.setEndMessage(userMessageDO.getContent());
            }else {
                userDO.setEndMessage(userMessageDO.getImgUrl());
            }
            userDO.setCreateTime(userMessageDO.getCreateTime());
            userAccountDOList.add(userDO);
        }
        // 使用 Collections.sort() 方法和自定义的比较器进行排序
        Collections.sort(userAccountDOList, Comparator.comparing(UserDO::getCreateTime).reversed());
        return ResultBody.success(userAccountDOList);
    }

    @Override
    public ResultBody removeUserMessage(Integer id) {
        UserMessageDO userMessageDO = messageDao.selectUserMessageById(id);
        Date createTime = userMessageDO.getCreateTime();
        String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(createTime);
        if(isOverThreeMinutes(time)){
            return ResultBody.error("消息发送已经超过三分钟，撤回失败");
        }
        if(messageDao.removeUserMessage(id) != 0){
            Integer logId = messageDao.isUserMessageLog(userMessageDO.getSenderUserId(),userMessageDO.getReceiverUserId());
            if(logId != null){
                messageDao.removeUserMessageCount(logId);
            }
            return ResultBody.success("消息撤回成功已撤回");
        }
        return ResultBody.error("消息撤回失败");
    }

    @Override
    public ResultBody removeUser(Integer senderUserId, Integer receiverUserId) {
        Integer logId = messageDao.isUserMessageLog(receiverUserId,senderUserId);
        if(logId != null){
            messageDao.removeUserMessageLog(logId);
            return ResultBody.success("删除成功");
        }
        return ResultBody.error("删除失败");
    }

//    @Override
//    public ResultBody purchaseTime(Integer userAccountId, MessageTimeVO messageTimeVO, String token) {
//        if(messageTimeVO.getId() == null){
//            return ResultBody.error("聊天类型不能传递为空");
//        }
//        MessageTimeVO messageTimeVO1 = messageDao.selectUserMessageTimeType(messageTimeVO.getId());
//        if(messageTimeVO.getMoney() != null && messageTimeVO.getMoney().compareTo(BigDecimal.ZERO) > 0){
//            // 微信支付购买聊天时长
//            OrderRequestParamsVO orderRequestParamsVO = new OrderRequestParamsVO();
//            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
//            String content = "WT" + sdf.format(new Date());
//            orderRequestParamsVO.setOrderNo(content);
//            orderRequestParamsVO.setDescription("购买聊天时长");
//            BigDecimal money = messageTimeVO1.getMoney();
//            BigDecimal amountInFen = money.multiply(new BigDecimal("100")).setScale(0, RoundingMode.DOWN);
//            orderRequestParamsVO.setAmount(amountInFen.intValue());
//            orderRequestParamsVO.setOrderPort(5);
//            // 扣除金额
//            Map map = paymentAppApi.orderPay(orderRequestParamsVO, token);
//
//        }else if(messageTimeVO.getPoints() > 0){
//            ChangeUserPointVO changeUserPointVO = new ChangeUserPointVO();
//            changeUserPointVO.setUserAccountId(userAccountId);
//            changeUserPointVO.setChangePoint(-messageTimeVO1.getPoints());
//            changeUserPointVO.setChangeType(8);
//            ResultBody resultBody = userPointsService.change(changeUserPointVO);
//            if (!"200".equals(resultBody.getCode())) {
//                return resultBody;
//            }
//        }else{
//            return ResultBody.error("请选择积分购买或者微信支付，不能同时为空");
//        }
//        // 增加聊天时长
//        String timeValue = redisTemplate.opsForValue().get("Message" + userAccountId);
//        if (timeValue == null || timeValue.equals("")) {
//            redisTemplate.setValueSerializer(RedisSerializer.json());
//            redisTemplate.opsForValue().set("Message" + userAccountId, userAccountId.toString(), messageTimeVO1.getChatDuration() * 24 * 60 * 60, TimeUnit.SECONDS);
//            return ResultBody.success("成功购买"+messageTimeVO1.getChatDuration()+"天聊天功能");
//        }
//        Long remainingTime = redisTemplate.getExpire("Message" + userAccountId, TimeUnit.SECONDS);
//        if (remainingTime != null && remainingTime >= 0) {
//            long newTime = remainingTime + (messageTimeVO1.getChatDuration() * 24 * 60 * 60); // 转换为毫秒后加上七天的毫秒数
//            redisTemplate.opsForValue().set("Message" + userAccountId, userAccountId.toString(), newTime, TimeUnit.SECONDS);
//        }
//        return ResultBody.success("成功购买"+messageTimeVO1.getChatDuration()+"天聊天功能");
//    }
    @Override
    public ResultBody purchaseTimeByWechat(Integer userAccountId, Integer id) {
        if(id == null){
            return ResultBody.error("聊天类型不能传递为空");
        }
        MessageTimeVO messageTimeVO1 = messageDao.selectUserMessageTimeType(id);
        // 增加聊天时长
        String timeValue = redisTemplate.opsForValue().get("Message" + userAccountId);
        if (timeValue == null || timeValue.equals("")) {
            redisTemplate.setValueSerializer(RedisSerializer.json());
            redisTemplate.opsForValue().set("Message" + userAccountId, userAccountId.toString(), messageTimeVO1.getChatDuration() * 24 * 60 * 60, TimeUnit.SECONDS);
            return ResultBody.success("成功购买"+messageTimeVO1.getChatDuration()+"天聊天功能");
        }
        Long remainingTime = redisTemplate.getExpire("Message" + userAccountId, TimeUnit.SECONDS);
        if (remainingTime != null && remainingTime >= 0) {
            long newTime = remainingTime + (messageTimeVO1.getChatDuration() * 24 * 60 * 60); // 转换为毫秒后加上七天的毫秒数
            redisTemplate.opsForValue().set("Message" + userAccountId, userAccountId.toString(), newTime, TimeUnit.SECONDS);
        }
        return ResultBody.success("成功购买"+messageTimeVO1.getChatDuration()+"天聊天功能");
    }
    @Override
    public ResultBody purchaseTimeByPoints(Integer userAccountId, MessageTimePointsVO messageTimeVO) {
        if(messageTimeVO.getId() == null){
            return ResultBody.error("聊天类型不能传递为空");
        }
        MessageTimeVO messageTimeVO1 = messageDao.selectUserMessageTimeType(messageTimeVO.getId());
        ChangeUserPointVO changeUserPointVO = new ChangeUserPointVO();
        changeUserPointVO.setUserAccountId(userAccountId);
        changeUserPointVO.setChangePoint(-messageTimeVO1.getPoints());
        changeUserPointVO.setChangeType(8);
        ResultBody resultBody = userPointsService.change(changeUserPointVO);
        if (!"200".equals(resultBody.getCode())) {
            return resultBody;
        }
        // 增加聊天时长
        String timeValue = redisTemplate.opsForValue().get("Message" + userAccountId);
        if (timeValue == null || timeValue.equals("")) {
            redisTemplate.setValueSerializer(RedisSerializer.json());
            redisTemplate.opsForValue().set("Message" + userAccountId, userAccountId.toString(), messageTimeVO1.getChatDuration() * 24 * 60 * 60, TimeUnit.SECONDS);
            return ResultBody.success("成功购买"+messageTimeVO1.getChatDuration()+"天聊天功能");
        }
        Long remainingTime = redisTemplate.getExpire("Message" + userAccountId, TimeUnit.SECONDS);
        if (remainingTime != null && remainingTime >= 0) {
            long newTime = remainingTime + (messageTimeVO1.getChatDuration() * 24 * 60 * 60); // 转换为毫秒后加上七天的毫秒数
            redisTemplate.opsForValue().set("Message" + userAccountId, userAccountId.toString(), newTime, TimeUnit.SECONDS);
        }
        return ResultBody.success("成功购买"+messageTimeVO1.getChatDuration()+"天聊天功能");
    }
    @Override
    public ResultBody listTimeType() {
        List<MessageTimeVO> messageTimeVOS = messageDao.listTimeType();
        return ResultBody.success(messageTimeVOS);
    }

    @Override
    public ResultBody updateTimeType(MessageTimeVO messageTimeVO) {
        messageDao.updateTimeType(messageTimeVO);
        return ResultBody.success();
    }

    @Override
    public ResultBody insertTimeType(MessageTimeVO messageTimeVO) {
        messageDao.insertTimeType(messageTimeVO);
        return ResultBody.success();
    }

    @Override
    public Integer timeTypeById(Integer id,Integer userId) {

        boolean isPilot = pilotCertificationDao.pilotAuditStatus(userId)==1;
        if(isPilot) {
            id = 4;
        }
        MessageTimeVO messageTimeVO1 = messageDao.selectUserMessageTimeType(id);
        BigDecimal money = messageTimeVO1.getMoney();
        BigDecimal amountInFen = money.multiply(new BigDecimal("100")).setScale(0, RoundingMode.DOWN);
        return amountInFen.intValue();
    }

    public static boolean isOverThreeMinutes(String createTime) {
        // 定义日期时间格式化对象
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 将字符串格式的时间转换为 LocalDateTime 对象
        LocalDateTime createDateTime = LocalDateTime.parse(createTime, formatter);
        // 计算当前时间与创建时间的时间差（单位：秒）
        long secondsDiff = ChronoUnit.SECONDS.between(createDateTime, LocalDateTime.now());
        // 如果时间差大于 180 秒（即三分钟），返回 true
        return secondsDiff > 180;
    }
}
