package com.ruoyi.gateway.enhance.service.impl;

import com.ruoyi.common.core.domain.QueryRequest;
import com.ruoyi.common.core.domain.StringConstant;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.gateway.enhance.entity.BlackList;
import com.ruoyi.gateway.enhance.entity.RouteUser;
import com.ruoyi.gateway.enhance.mapper.RouteUserMapper;
import com.ruoyi.gateway.enhance.service.RouteEnhanceCacheService;
import com.ruoyi.gateway.enhance.service.RouteUserService;
import com.ruoyi.gateway.enhance.utils.PageableExecutionUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;
import java.util.Arrays;

/**
 * @author MrBird
 */
@Service
@RequiredArgsConstructor
public class RouteUserServiceImpl implements RouteUserService {

    private final PasswordEncoder passwordEncoder;
    private final RouteEnhanceCacheService routeEnhanceCacheService;
    private RouteUserMapper routeUserMapper;
    private ReactiveMongoTemplate template;

    @Autowired(required = false)
    public void setRouteUserMapper(RouteUserMapper routeUserMapper) {
        this.routeUserMapper = routeUserMapper;
    }

    @Autowired(required = false)
    public void setTemplate(ReactiveMongoTemplate template) {
        this.template = template;
    }

    @Override
    public Mono<RouteUser> create(RouteUser routeUser) {
        routeUser.setCreateTime(DateUtils.formatFullTime(LocalDateTime.now(), DateUtils.YYYY_MM_DD_HH_MM_SS));
        routeUser.setPassword(passwordEncoder.encode(routeUser.getPassword()));
//        routeUser.setCreateTime(DateUtils.formatFullTime(LocalDateTime.now(), DateUtils.YYYY_MM_DD_HH_MM_SS));
        return routeUserMapper.insert(routeUser);
    }

    @Override
    public Mono<RouteUser> update(RouteUser routeUser) {
        return this.routeUserMapper.findById(routeUser.getId())
                .flatMap(u -> {
                    u.setRoles(routeUser.getRoles());
                    return this.routeUserMapper.save(u);
                });
    }

    @Override
    public Flux<RouteUser> delete(String ids) {
        String[] idArray = StringUtils.splitByWholeSeparatorPreserveAllTokens(ids, StringConstant.COMMA);
        return routeUserMapper.deleteByIdIn(Arrays.asList(idArray));
    }

    @Override
    public Mono<RouteUser> findByUsername(String username) {
        return routeUserMapper.findByUsername(username);
    }

    @Override
    public Flux<RouteUser> findPages(QueryRequest request, RouteUser routeUser) {
        Query query = getQuery(routeUser);
        return PageableExecutionUtil.getPages(query, request, RouteUser.class, template);
    }

    @Override
    public Mono<Long> findCount(RouteUser routeUser) {
        Query query = getQuery(routeUser);
        return template.count(query, RouteUser.class);
    }

    @Override
    public Mono<RouteUser> findById(String id) {
        return template.findById(id, RouteUser.class);
    }

    private Query getQuery(RouteUser routeUser) {
        Query query = new Query();
        Criteria criteria = new Criteria();
        if (StringUtils.isNotBlank(routeUser.getUsername())) {
            criteria.and("username").is(routeUser.getUsername());
        }
        query.addCriteria(criteria);
        return query;
    }
}
