package cn.reghao.oss.console.app.service;

import cn.reghao.jutil.jdk.result.Result;
import cn.reghao.oss.console.account.service.UserContext;
import cn.reghao.oss.console.app.db.repository.StoreNodeRepository;
import cn.reghao.oss.console.app.db.repository.UploadChannelRepository;
import cn.reghao.oss.console.app.db.repository.UserNodeRepository;
import cn.reghao.oss.console.app.model.dto.UserNodeDto;
import cn.reghao.oss.console.app.model.po.StoreNode;
import cn.reghao.oss.console.app.model.po.UploadChannel;
import cn.reghao.oss.console.app.model.po.UserNode;
import cn.reghao.oss.console.app.model.vo.UserNodeVO;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author reghao
 * @date 2024-02-27 09:49:56
 */
@Service
public class UserNodeService {
    private final UserNodeRepository userNodeRepository;
    private final StoreNodeRepository storeNodeRepository;
    private final UploadChannelRepository uploadChannelRepository;

    public UserNodeService(UserNodeRepository userNodeRepository, StoreNodeRepository storeNodeRepository,
                           UploadChannelRepository uploadChannelRepository) {
        this.userNodeRepository = userNodeRepository;
        this.storeNodeRepository = storeNodeRepository;
        this.uploadChannelRepository = uploadChannelRepository;
    }

    public Result add(UserNodeDto userNodeDto) {
        int nodeId = userNodeDto.getNodeId();
        Integer userId = UserContext.getUserId();
        UserNode userNode = userNodeRepository.findByUserIdAndNodeId(userId, nodeId);
        if (userNode != null) {
            return Result.fail("UserNode exist");
        }

        StoreNode storeNode = storeNodeRepository.findById(nodeId);
        if (storeNode == null) {
            return Result.success("StoreNode not exist");
        }

        userNode = new UserNode(userNodeDto, userId);
        userNodeRepository.save(userNode);
        return Result.success("node added");
    }

    public Result delete(int id) {
        UserNode userNode = userNodeRepository.findById(id);
        if (userNode != null) {
            int nodeId = userNode.getNodeId();
            int userId = UserContext.getUserId();
            List<UploadChannel> uploadChannels = uploadChannelRepository.findByNodeIdAndCreateBy(nodeId, userId);
            if (!uploadChannels.isEmpty()) {
                return Result.fail("UploadChannel exists");
            }

            userNodeRepository.delete(userNode);
            return Result.success();
        }

        return Result.fail("UserNode not exists");
    }

    public List<UserNode> getByUserId(int userId) {
        return userNodeRepository.findByUserId(userId);
    }

    public StoreNode getByDomain(String domain) {
        UserNode userNode = userNodeRepository.findByDomain(domain);
        int id = userNode.getNodeId();
        return storeNodeRepository.findById(id);
    }

    public List<StoreNode> getUserStoreNodes() {
        int loginUser = UserContext.getUserId();
        List<UserNode> list = userNodeRepository.findByUserId(loginUser);
        if (list.isEmpty()) {
            return Collections.emptyList();
        }

        List<Integer> nodeIds = list.stream().map(UserNode::getNodeId).collect(Collectors.toList());
        return storeNodeRepository.findAllById(nodeIds);
    }

    public List<UserNodeVO> getUserStoreNodes1() {
        int loginUser = UserContext.getUserId();
        List<UserNode> list = userNodeRepository.findByUserId(loginUser);
        if (list.isEmpty()) {
            return Collections.emptyList();
        }

        return list.stream()
                .map(userNode -> {
                    int nodeId = userNode.getNodeId();
                    StoreNode storeNode = storeNodeRepository.findById(nodeId);
                    String nodeAddr = storeNode.getNodeAddr();
                    String domain = userNode.getDomain();
                    return new UserNodeVO(nodeId, nodeId, nodeAddr, domain);
                })
                .collect(Collectors.toList());
    }

    public UserNode getUserNode(int nodeId, int loginUser) {
        return userNodeRepository.findByUserIdAndNodeId(loginUser, nodeId);
    }
}
