package cn.reghao.tnb.account.app.db.repository;

import cn.reghao.jutil.jdk.db.Page;
import cn.reghao.tnb.account.api.dto.AccountAvatar;
import cn.reghao.tnb.account.api.dto.AccountInfo;
import cn.reghao.tnb.account.app.db.mapper.UserAccountMapper;
import cn.reghao.tnb.account.app.db.mapper.UserRegistryMapper;
import cn.reghao.tnb.account.app.model.dto.AccountDetail;
import cn.reghao.tnb.account.app.model.po.UserAccount;
import cn.reghao.tnb.account.app.model.po.UserRegistry;
import cn.reghao.tnb.message.api.constant.NotifyType;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;

/**
 * @author reghao
 * @date 2023-06-01 14:12:40
 */
@Repository
public class AccountRepository {
    private final int pageSize = 100;
    private final UserAccountMapper userAccountMapper;
    private final UserRegistryMapper userRegistryMapper;

    public AccountRepository(UserAccountMapper userAccountMapper, UserRegistryMapper userRegistryMapper) {
        this.userAccountMapper = userAccountMapper;
        this.userRegistryMapper = userRegistryMapper;
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveAccount(UserAccount userAccount) {
        userAccountMapper.save(userAccount);
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveAccounts(List<UserAccount> userAccounts) {
        userAccountMapper.saveAll(userAccounts);
    }

    @CacheEvict(cacheNames = "tnb:account:info", key = "#userId")
    public void updateUserScreenName(long userId, String screenName) {
        userAccountMapper.updateUserScreenName(userId, screenName);
    }

    @CacheEvict(cacheNames = "tnb:account:info", key = "#userId")
    public void updateUserAvatar(long userId, String avatarUrl) {
        userAccountMapper.updateUserAvatar(userId, avatarUrl);
    }

    public AccountDetail getUserDetailByEmail(String email) {
        return userAccountMapper.findByEmail1(email);
    }

    public AccountDetail getUserDetailByMobile(String email) {
        return userAccountMapper.findByMobile1(email);
    }

    public Long getMaxUserId() {
        return userAccountMapper.findMaxUserId();
    }

    public UserAccount findByEmail(int type, String email) {
        if (type == NotifyType.email.getValue()) {
            return userAccountMapper.findByEmail(email);
        }

        return userAccountMapper.findByMobile(email);
    }

    public Long getUserId(String username) {
        return userAccountMapper.findUserIdByUsername(username);
    }

    @Cacheable(cacheNames = "tnb:account:info", key = "#userId", unless = "#result == null")
    public AccountInfo getAccountInfo(long userId) {
        AccountInfo accountInfo = userAccountMapper.findAccountInfo(userId);
        return accountInfo;
    }

    public List<AccountInfo> getAccountInfos(List<Long> userIds) {
        return userAccountMapper.findAccountInfos(userIds);
    }

    public List<AccountAvatar> getAccountAvatars(List<Long> userIds) {
        if (userIds.isEmpty()) {
            return Collections.emptyList();
        }

        return userAccountMapper.findAccountAvatars(userIds);
    }

    public AccountInfo getAccountInfoByMobile(String mobile) {
        AccountInfo accountInfo = userAccountMapper.findAccountInfoByMobile(mobile);
        return accountInfo;
    }

    public AccountInfo getAccountInfoByUsername(String username) {
        AccountInfo accountInfo = userAccountMapper.findAccountInfoByUsername(username);
        return accountInfo;
    }

    public int countByScreenName(String screenName) {
        int total = userAccountMapper.countByScreenName(screenName);
        return total;
    }

    public List<AccountInfo> getPageByScreenName(String screenName, int pageNumber) {
        Page page1 = new Page(pageNumber, pageSize);
        List<AccountInfo> list = userAccountMapper.findScreenNameByPage(page1, screenName);
        return list;
    }

    public UserAccount getUserAccount(long userId) {
        return userAccountMapper.findByUserId(userId);
    }

    public UserRegistry getUserRegistry() {
        List<UserRegistry> list = userRegistryMapper.findAll();
        if (list.isEmpty()) {
            userRegistryMapper.save(new UserRegistry());
        }

        return userRegistryMapper.findAll().get(0);
    }

    public void updateUserRegistry() {
        UserRegistry userRegistry = getUserRegistry();
        userRegistryMapper.update(userRegistry);
    }
}
