package cn.skcks.matrix.v2.services.user;

import cn.skcks.matrix.v2.orm.mybatis.dynamic.mapper.UserDynamicSqlSupport;
import cn.skcks.matrix.v2.orm.mybatis.dynamic.mapper.UserMapper;
import cn.skcks.matrix.v2.orm.mybatis.dynamic.model.User;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shardingsphere.transaction.annotation.ShardingSphereTransactionType;
import org.mybatis.dynamic.sql.SqlBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

@Slf4j
@Service
@AllArgsConstructor
public class UserServiceImpl implements UserService {
    private final UserMapper userMapper;

    public PageInfo<User> getUsers(int page, int size){
        PageInfo<User> pageInfo;

        try(Page<User> userPage = PageHelper.startPage(page,size)){
            pageInfo = userPage.doSelectPageInfo(()-> userMapper.select(u->u.orderBy(UserDynamicSqlSupport.id.descending())));
        }

        List<User> users = pageInfo.getList();
        log.info("共 {} 条, 每页 {} 条, 第 {}/{} 页, {} 条数据",
                pageInfo.getTotal(),
                pageInfo.getPageSize(),
                pageInfo.getPageNum(),
                pageInfo.getPages(),
                users.size());

        return pageInfo;
    }

    @Nullable
    @Override
    public User getUser(String account) {
        if(!exist(account,account)){
            return null;
        }

        List<User> users = userMapper.select(u->u.where(UserDynamicSqlSupport.userName, SqlBuilder.isEqualToWhenPresent(account))
                .or(UserDynamicSqlSupport.email,SqlBuilder.isEqualToWhenPresent(account)));

        if(users.size() != 1){
            return null;
        }

        return users.get(0);
    }

    public boolean exist(String userName,String email){
        if(StringUtils.isBlank(userName) && StringUtils.isBlank(email)){
            return false;
        }

        Optional<User> user = userMapper.selectOne(u->u.where(UserDynamicSqlSupport.userName, SqlBuilder.isEqualToWhenPresent(userName))
                .or(UserDynamicSqlSupport.email,SqlBuilder.isEqualToWhenPresent(email))
                .limit(1));
        return user.isPresent();
    }

    public boolean exist(String userId){
        if(StringUtils.isBlank(userId)){
            return false;
        }

        Optional<User> user = userMapper.selectOne(u-> u.where(UserDynamicSqlSupport.id,SqlBuilder.isEqualTo(Long.valueOf(userId)))
                .limit(1));
        return user.isPresent();
    }

    @Override
    @Transactional
    @ShardingSphereTransactionType
    public boolean add(User... users) {
        return userMapper.insertMultiple(Arrays.asList(users)) > 0;
    }

    @Override
    @Transactional
    @ShardingSphereTransactionType
    public boolean add(User user) {
        return userMapper.insert(user) > 0;
    }

    @Override
    public boolean update(User user) {
        if(user.getId() == null){
            return false;
        }
        return userMapper.updateByPrimaryKey(user) > 0;
    }
}
