package com.tanpu.community.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tanpu.common.util.JsonUtil;
import com.tanpu.common.uuid.UuidGenHelper;
import com.tanpu.community.api.enums.DeleteTagEnum;
import com.tanpu.community.api.enums.NotificationTypeEnum;
import com.tanpu.community.dao.entity.NotificationForwardDO;
import com.tanpu.community.dao.entity.NotificationLikeDO;
import com.tanpu.community.dao.entity.community.NotificationEntity;
import com.tanpu.community.dao.mapper.community.NotificationMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

@Service
public class NotificationService {

    @Resource
    private NotificationMapper notificationMapper;

    @Autowired
    private UuidGenHelper uuidGenHelper;


    public void insert(String operatorId,String notifierId,NotificationTypeEnum type,String targetId,String content){
        NotificationEntity entity = NotificationEntity.builder().operatorId(operatorId)
                .notificationId(uuidGenHelper.getUuidStr())
                .notifiedUserId(notifierId)
                .messageType(type.getCode())
                .content(content)
                .operatorId(operatorId)
                .targetId(targetId)
                .build();
        insert(entity);
    }

    public void insert(String operatorId, String notifierId, NotificationTypeEnum type, String targetId, String content
            , LocalDateTime createTime){
        NotificationEntity entity = NotificationEntity.builder().operatorId(operatorId)
                .notificationId(uuidGenHelper.getUuidStr())
                .notifiedUserId(notifierId)
                .messageType(type.getCode())
                .content(content)
                .operatorId(operatorId)
                .targetId(targetId)
                .createTime(createTime)
                .updateTime(createTime)
                .build();
        insert(entity);
    }


    public void insertForward(String operatorId,String notifierId,String themeId,String topicId,String text){
        NotificationForwardDO forwardDO = NotificationForwardDO.builder().topicId(topicId).content(text).build();
        NotificationEntity entity = NotificationEntity.builder().operatorId(operatorId)
                .notificationId(uuidGenHelper.getUuidStr())
                .notifiedUserId(notifierId)
                .messageType(NotificationTypeEnum.LIKE.getCode())
                .content(JsonUtil.toJson(forwardDO))
                .operatorId(operatorId)
                .targetId(themeId)
                .build();
        insert(entity);

    }


    public void insertLike(String operatorId,String notifierId,String targetId){
        NotificationEntity entity = notificationMapper.selectOne(new LambdaQueryWrapper<NotificationEntity>()
                .eq(NotificationEntity::getMessageType, NotificationTypeEnum.LIKE.getCode())
                .eq(NotificationEntity::getTargetId,targetId)
                .eq(NotificationEntity::getNotifiedUserId, notifierId));
        if (entity!=null){
            NotificationLikeDO notificationLikeDO = JsonUtil.toBean(entity.getContent(), NotificationLikeDO.class);
            notificationLikeDO.addItem(operatorId);

            entity.setContent(JsonUtil.toJson(notificationLikeDO));
            notificationMapper.updateById(entity);
        }else {
            NotificationLikeDO notificationLikeDO = new NotificationLikeDO();
            notificationLikeDO.addItem(operatorId);
            NotificationEntity build = NotificationEntity.builder().operatorId(operatorId)
                    .notificationId(uuidGenHelper.getUuidStr())
                    .messageType(NotificationTypeEnum.LIKE.getCode())
                    .notifiedUserId(notifierId)
                    .content(JsonUtil.toJson(notificationLikeDO))
                    .targetId(targetId)
                    .operatorId(operatorId)
                    .build();
            insert(build);
        }

    }

    @Transactional
    public void insert(NotificationEntity entity){
        notificationMapper.insert(entity);
    }


    public NotificationEntity queryById(String notificationId){
        return notificationMapper.selectOne(new LambdaQueryWrapper<NotificationEntity>()
                .eq(NotificationEntity::getNotificationId,notificationId));
    }


    public List<NotificationEntity> query(String userId, Integer type, String lastId, Integer pageSize){
        LambdaQueryWrapper<NotificationEntity> queryWrapper = new LambdaQueryWrapper<NotificationEntity>()
                .eq(NotificationEntity::getNotifiedUserId, userId)
                .last("limit " + pageSize);


        if (StringUtils.isNotBlank(lastId)){
            NotificationEntity lastOne = notificationMapper.selectOne(new LambdaQueryWrapper<NotificationEntity>()
                    .eq(NotificationEntity::getNotificationId, lastId));
            queryWrapper.lt(NotificationEntity::getUpdateTime, lastOne.getCreateTime());
        }
        if (!NotificationTypeEnum.ALL.getCode().equals(type)){
            queryWrapper.eq(NotificationEntity::getMessageType,type);
        }
        return notificationMapper.selectList(queryWrapper);
    }


    public void truncate() {
        notificationMapper.delete(new LambdaQueryWrapper<NotificationEntity>()
                .eq(NotificationEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode()));
    }

    public void insertLike(String operatorId, String notifierId, String targetId, LocalDateTime updateTime){
        NotificationEntity entity = notificationMapper.selectOne(new LambdaQueryWrapper<NotificationEntity>()
                .eq(NotificationEntity::getMessageType, NotificationTypeEnum.LIKE.getCode())
                .eq(NotificationEntity::getTargetId,targetId)
                .eq(NotificationEntity::getNotifiedUserId, notifierId));
        if (entity!=null){
            NotificationLikeDO notificationLikeDO = JsonUtil.toBean(entity.getContent(), NotificationLikeDO.class);
            notificationLikeDO.addItem(operatorId);

            entity.setContent(JsonUtil.toJson(notificationLikeDO));
            entity.setUpdateTime(updateTime);
            notificationMapper.updateById(entity);
        }else {
            NotificationLikeDO notificationLikeDO = new NotificationLikeDO();
            notificationLikeDO.addItem(operatorId);
            NotificationEntity build = NotificationEntity.builder().operatorId(operatorId)
                    .notificationId(uuidGenHelper.getUuidStr())
                    .messageType(NotificationTypeEnum.LIKE.getCode())
                    .notifiedUserId(notifierId)
                    .content(JsonUtil.toJson(notificationLikeDO))
                    .targetId(targetId)
                    .operatorId(operatorId)
                    .createTime(updateTime)
                    .updateTime(updateTime)
                    .build();
            insert(build);
        }

    }
}