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

import cn.reghao.jutil.jdk.converter.ByteConverter;
import cn.reghao.jutil.jdk.converter.ByteType;
import cn.reghao.oss.console.app.model.dto.ChannelProcessDto;
import cn.reghao.oss.api.dto.ObjectChannel;
import cn.reghao.oss.console.account.service.UserContext;
import cn.reghao.oss.console.app.db.repository.UploadChannelRepository;
import cn.reghao.oss.console.app.model.dto.ChannelScopeDto;
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.UploadChannelVo;
import org.springframework.stereotype.Service;

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

/**
 * @author reghao
 * @date 2024-02-23 15:14:53
 */
@Service
public class UploadChannelService {
    private final ByteConverter byteConverter = new ByteConverter();
    private final UploadChannelRepository uploadChannelRepository;
    private final UserNodeService userNodeService;

    public UploadChannelService(UploadChannelRepository uploadChannelRepository, UserNodeService userNodeService) {
        this.uploadChannelRepository = uploadChannelRepository;
        this.userNodeService = userNodeService;
    }

    public void updateScope(ChannelScopeDto channelScopeDto) {
        int id = channelScopeDto.getId();
        int newScope = channelScopeDto.getNewScope();
        UploadChannel uploadChannel = uploadChannelRepository.findById(id);
        if (uploadChannel != null) {
            int currentScope = uploadChannel.getScope();
            if (currentScope != newScope) {
                uploadChannel.setScope(newScope);
                uploadChannelRepository.save(uploadChannel);
            }
        }
    }

    public void updateSeturl(ChannelProcessDto channelProcessDto) {
        int id = channelProcessDto.getId();
        UploadChannel uploadChannel = uploadChannelRepository.findById(id);
        if (uploadChannel != null) {
            boolean seturl = channelProcessDto.getSeturl();
            boolean current = uploadChannel.getSeturl();
            if (seturl != current) {
                uploadChannel.setSeturl(seturl);
                uploadChannelRepository.save(uploadChannel);
            }
        }
    }

    public List<UploadChannelVo> getUploadChannels() {
        int loginUser = UserContext.getUserId();
        List<UploadChannel> page = uploadChannelRepository.findByCreateBy(loginUser);
        List<UploadChannelVo> list = page.stream().map(uploadChannel -> {
            long maxSize = uploadChannel.getMaxSize();
            String maxSizeStr = byteConverter.convert(ByteType.Bytes, maxSize);
            UserNode userNode = userNodeService.getUserNode(uploadChannel.getNodeId(), loginUser);
            String bindDomain = userNode.getDomain();
            return new UploadChannelVo(uploadChannel, maxSizeStr, bindDomain);
        }).collect(Collectors.toList());

        //return new PageImpl<>(list, pageRequest, 1000);
        return list;
    }

    public UploadChannel getUploadChannel(int id) {
        return uploadChannelRepository.findById(id);
    }

    public UploadChannel getByChannelIdAndCreateBy(int channelId, int createBy) {
        return uploadChannelRepository.findByChannelIdAndCreateBy(channelId, createBy);
    }

    public ObjectChannel getObjectChannelByChannelId(int channelId, int createBy) {
        UploadChannel uploadChannel = uploadChannelRepository.findByChannelIdAndCreateBy(channelId, createBy);
        return getObjectChannel(uploadChannel);
    }

    public ObjectChannel getObjectChannel(UploadChannel uploadChannel) {
        int channelId = uploadChannel.getChannelId();
        String name = uploadChannel.getName();
        String channelPrefix = uploadChannel.getPrefix();
        long maxSize = uploadChannel.getMaxSize();
        int fileType = uploadChannel.getFileType();
        boolean seturl = uploadChannel.getSeturl();
        int scope = uploadChannel.getScope();
        int createBy = uploadChannel.getCreateBy();

        UserNode userNode = userNodeService.getUserNode(uploadChannel.getNodeId(), createBy);
        String domain = userNode.getDomain();
        return new ObjectChannel(channelId, name, channelPrefix, maxSize, fileType, seturl, scope, domain, createBy);
    }

    public StoreNode getStoreNodeByChannelId(int loginUser, int channelId) throws Exception {
        UploadChannel uploadChannel = uploadChannelRepository.findByChannelIdAndCreateBy(channelId, loginUser);
        if (uploadChannel == null) {
            String errMsg = String.format("channel_id %s not exist", channelId);
            throw new Exception(errMsg);
        }

        UserNode userNode = userNodeService.getUserNode(uploadChannel.getNodeId(), uploadChannel.getCreateBy());
        String domain = userNode.getDomain();
        String ossUrl = String.format("//%s", domain);
        long maxSize = uploadChannel.getMaxSize();

        StoreNode storeNode = userNodeService.getByDomain(domain);
        if (storeNode == null) {
            String errMsg = String.format("store_node %s not exist", domain);
            throw new Exception(errMsg);
        }

        return storeNode;
    }

    public List<UploadChannel> getByNodeIdAndUserId(int nodeId, int userId) {
        return uploadChannelRepository.findByNodeIdAndCreateBy(nodeId, userId);
    }

    public List<UploadChannel> getByDomainAndCreateBy(String domain, int createBy) {
        StoreNode storeNode = userNodeService.getByDomain(domain);
        int nodeId = storeNode.getId();
        return getByNodeIdAndUserId(nodeId, createBy);
    }
}
