package cn.reghao.tnb.file.app.zoss.service;

import cn.reghao.jutil.jdk.web.result.Result;
import cn.reghao.tnb.common.util.ConstantId;
import cn.reghao.tnb.file.app.service.StoreConfigService;
import cn.reghao.tnb.file.app.zoss.db.mapper.StoreNodeMapper;
import cn.reghao.tnb.file.app.zoss.db.mapper.UploadChannelMapper;
import cn.reghao.tnb.file.app.zoss.db.mapper.UserNodeMapper;
import cn.reghao.tnb.file.app.zoss.model.dto.NodeAddDto;
import cn.reghao.tnb.file.app.zoss.model.dto.NodeUpdateDto;
import cn.reghao.tnb.file.app.zoss.model.po.StoreNode;
import cn.reghao.tnb.file.app.zoss.model.po.UploadChannel;
import cn.reghao.tnb.file.app.zoss.model.po.UserNode;
import cn.reghao.tnb.common.db.SelectOption;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

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

/**
 * @author reghao
 * @date 2024-02-27 09:49:56
 */
@Slf4j
@Service
public class UserNodeService {
    private final UserNodeMapper userNodeMapper;
    private final StoreNodeMapper storeNodeMapper;
    private final UploadChannelMapper uploadChannelMapper;
    private final StoreConfigService storeConfigService;

    public UserNodeService(UserNodeMapper userNodeMapper, StoreNodeMapper storeNodeMapper,
                           UploadChannelMapper uploadChannelMapper, StoreConfigService storeConfigService) {
        this.userNodeMapper = userNodeMapper;
        this.storeNodeMapper = storeNodeMapper;
        this.uploadChannelMapper = uploadChannelMapper;
        this.storeConfigService = storeConfigService;
    }

    public Result add(NodeAddDto nodeAddDto) {
        int storeNodeId = nodeAddDto.getStoreNodeId();
        int ossUser = storeConfigService.getLocalOssUser();
        UserNode userNode = userNodeMapper.findByCreateByAndStoreNodeId(ossUser, storeNodeId);
        if (userNode != null) {
            return Result.fail("UserNode exist");
        }

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

        userNode = new UserNode(nodeAddDto, ossUser);
        userNodeMapper.save(userNode);
        return Result.success("node added");
    }

    /**
     * 自动初始化 UserNode
     *
     * @param
     * @return
     * @date 2025-10-21 09:41:46
     */
    public void initUserNode() {
        userNodeMapper.findAll();

        int ossUser = storeConfigService.getLocalOssUser();
        if (ossUser == ConstantId.ANONYMOUS_USER_ID) {
            log.error("ossUser not exist, initUserNode failed...");
            return;
        }

        StoreNode storeNode = storeNodeMapper.findFirstStore();
        if (storeNode == null) {
            log.error("StoreNode not exist, initUserNode failed...");
            return;
        }

        int storeNodeId = storeNode.getId();
        String domain = ConstantId.OSS_DOMAIN;
        String secretKey = "";
        String referer = "";
        UserNode userNode = new UserNode(storeNodeId, domain, secretKey, referer, ossUser);
        userNodeMapper.save(userNode);
    }

    public void updateUserNode(NodeUpdateDto nodeUpdateDto) {
        userNodeMapper.updateUserNode(nodeUpdateDto);
    }

    public Result delete(int id) {
        UserNode userNode = userNodeMapper.findById(id);
        if (userNode != null) {
            int userNodeId = userNode.getId();
            int ossUser = storeConfigService.getLocalOssUser();
            List<UploadChannel> uploadChannels = uploadChannelMapper.findByCreateByAndUserNodeId(ossUser, userNodeId);
            if (!uploadChannels.isEmpty()) {
                return Result.fail("UploadChannel exists");
            }

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

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

    public List<UserNode> getUserNodes(int loginUser) {
        List<UserNode> list = userNodeMapper.findByCreateBy(loginUser);
        list.forEach(userNode -> {
            int storeNodeId = userNode.getStoreNodeId();
            StoreNode storeNode = storeNodeMapper.findById(storeNodeId);
            String nodeAddr = storeNode.getNodeAddr();
            userNode.setStoreNodeAddr(nodeAddr);
        });

        return list;
    }

    public UserNode getUserNode(int userNodeId) {
        return userNodeMapper.findById(userNodeId);
    }

    public UserNode getUserNodeByDomain(String domain) {
        return userNodeMapper.findByDomain(domain);
    }

    public String getDomain(int channelCode, int loginUser) {
        UploadChannel uploadChannel = uploadChannelMapper.findByCreateByAndChannelCode(loginUser, channelCode);
        int userNodeId = uploadChannel.getUserNodeId();
        UserNode userNode = userNodeMapper.findById(userNodeId);
        return userNode.getDomain();
    }

    public StoreNode getStoreNode(int userNodeId) {
        UserNode userNode = userNodeMapper.findById(userNodeId);
        return storeNodeMapper.findById(userNode.getStoreNodeId());
    }

    public StoreNode getStoreNodeByChannel(int channelCode, int owner) throws Exception {
        UploadChannel uploadChannel = uploadChannelMapper.findByCreateByAndChannelCode(owner, channelCode);
        if (uploadChannel == null) {
            String errMsg = String.format("channel_code %s not exist", channelCode);
            throw new Exception(errMsg);
        }

        UserNode userNode = userNodeMapper.findById(uploadChannel.getUserNodeId());
        return storeNodeMapper.findById(userNode.getStoreNodeId());
    }

    public StoreNode getStoreNodeByDomain(String domain) {
        UserNode userNode = userNodeMapper.findByDomain(domain);
        int storeNodeId = userNode.getStoreNodeId();
        return storeNodeMapper.findById(storeNodeId);
    }

    public List<SelectOption> getNodeKeyValues(long createBy) {
        return userNodeMapper.findByCreateBy(createBy).stream().map(userNode -> {
            String userNodeDomain = userNode.getDomain();
            return new SelectOption(userNodeDomain, ""+userNode.getId());
        }).collect(Collectors.toList());
    }
}
