package cn.quantgroup.xyqb.service.user.impl;

import cn.quantgroup.tech.db.DSType;
import cn.quantgroup.tech.db.TargetDataSource;
import cn.quantgroup.xyqb.entity.UserAttached;
import cn.quantgroup.xyqb.repository.IUserAttachedRepository;
import cn.quantgroup.xyqb.service.user.UserCenterService;
import cn.quantgroup.xyqb.util.EmojiUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * Created by 11 on 2017/3/22.
 */
@Slf4j
@Service
public class UserCenterServiceImpl implements UserCenterService {

    @Autowired
    private IUserAttachedRepository userAttachedRepository;

    @Override
    @TargetDataSource(type = DSType.SLAVE)//查询从库
//    @Cacheable(value = "userAttachedCache", key = "'xyqbUserAttached' + #userId", unless = "#result == null", cacheManager = "cacheManager")
    public UserAttached searchUserAttachedByUserId(long userId) {
        return userAttachedRepository.findByUserId(userId);
    } 

    @Override
    public List<UserAttached> searchUserAttachedListByUserId(List<Long> userIds) {
        return userAttachedRepository.findByUserIdIn(userIds);
    }

    @Override
    @CacheEvict(value = "userAttachedCache", key = "'xyqbUserAttached' + #userId", cacheManager = "cacheManager")
    public UserAttached saveUserAvatar(long userId, String avatar) {
        UserAttached userAttached = userAttachedRepository.findByUserId(userId);
        if(Objects.isNull(userAttached)){
            userAttached = createUserAttached(userId, avatar, null);
        }
        if(!Objects.equals(avatar, userAttached.getAvatar())){
            userAttached.setAvatar(avatar);
            userAttached = userAttachedRepository.save(userAttached);
        }
        return userAttached;
    }

    @Override
    @CacheEvict(value = "userAttachedCache", key = "'xyqbUserAttached' + #userId", cacheManager = "cacheManager")
    public UserAttached saveUserNick(long userId, String nick) {
        UserAttached userAttached = userAttachedRepository.findByUserId(userId);
        // 替换所有,UTF-8编码时4字节的Emoji表情字符
        nick = EmojiUtil.filterUnicode4(nick);
        if(Objects.isNull(userAttached)){
            userAttached = createUserAttached(userId, null, nick);
        }
        if(!Objects.equals(nick, userAttached.getNick())){
            userAttached.setNick(nick);
            try {
                userAttached = userAttachedRepository.save(userAttached);
            }catch (ConstraintViolationException e){
                // Sql唯一约束异常（诱因是Form重复提交，因为该操作是幂等的，故此不需额外处理，可返回成功）
                log.error("Sql约束异常[uni_idx_user_id]重复提交Form是幂等操作，不影响处理结果", e);
            }
        }
        return userAttached;
    }

    /**
     * 创建用户附加信息实体
     *
     * @param userId - 用户主键
     * @param avatar - 头像url地址
     * @param nick - 昵称
     * @return
     */
    private synchronized UserAttached createUserAttached(Long userId, String avatar, String nick) {
        UserAttached userAttached = userAttachedRepository.findByUserId(userId);
        // 更新实例
        userAttached = Optional.ofNullable(userAttached).orElse(new UserAttached());
        userAttached.setUserId(userId);
        if(StringUtils.isBlank(userAttached.getAvatar())){
            userAttached.setAvatar(avatar);
        }
        if(StringUtils.isBlank(userAttached.getNick())){
            userAttached.setNick(nick);
        }
        return userAttachedRepository.save(userAttached);
    }
}
