package com.eactive.eai.manage.inflow;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Service;

import com.eactive.eai.common.inflow.AbstractInflowControlManager;
import com.eactive.eai.common.inflow.CustomGroupBucket;
import com.eactive.eai.common.inflow.InflowControlUtil;
import com.eactive.eai.common.inflow.InflowGroupVO;

@Service
public class InflowGroupBucketService {

    public GroupBucketStatusDTO getGroupBucketStatus(String groupId) {
        AbstractInflowControlManager manager = InflowControlUtil.getInflowControlManager();

        InflowGroupVO groupVo = manager.getGroupInflowThreshold(groupId);
        if (groupVo == null) {
            return null;
        }

        GroupBucketStatusDTO dto = new GroupBucketStatusDTO();
        dto.setGroupId(groupId);
        dto.setGroupName(groupVo.getGroupName());
        dto.setActivate(groupVo.isActivate());

        List<GroupBucketStatusDTO.BucketInfo> buckets = new ArrayList<>();

        // CustomGroupBucket에서 직접 토큰 조회
        CustomGroupBucket customGroupBucket = getCustomGroupBucket(groupId);

        // perSecond bucket
        if (groupVo.getThresholdPerSecond() > 0) {
            long capacity = groupVo.getThresholdPerSecond();
            long available = capacity;
            if (customGroupBucket != null) {
                long tokens = customGroupBucket.getPerSecondAvailableTokens();
                if (tokens >= 0) {
                    available = Math.min(tokens, capacity);
                }
            }
            buckets.add(new GroupBucketStatusDTO.BucketInfo(
                "perSecond",
                capacity,
                available,
                "SEC"
            ));
        }

        // threshold bucket
        if (groupVo.getThreshold() > 0) {
            long capacity = groupVo.getThreshold();
            long available = capacity;
            if (customGroupBucket != null) {
                long tokens = customGroupBucket.getThresholdAvailableTokens();
                if (tokens >= 0) {
                    available = Math.min(tokens, capacity);
                }
            }
            buckets.add(new GroupBucketStatusDTO.BucketInfo(
                "threshold",
                capacity,
                available,
                groupVo.getThresholdTimeUnit()
            ));
        }

        dto.setBuckets(buckets);
        return dto;
    }

    public CustomGroupBucket getCustomGroupBucket(String groupId) {
        return InflowControlUtil.getInflowControlManager().getGroupBucket(groupId);
    }

    public List<GroupBucketStatusDTO> getAllGroupBucketStatus() {
        AbstractInflowControlManager manager = InflowControlUtil.getInflowControlManager();
        String[] groupIds = manager.getGroupAllKeys();

        List<GroupBucketStatusDTO> result = new ArrayList<>();
        for (String groupId : groupIds) {
            GroupBucketStatusDTO dto = getGroupBucketStatus(groupId);
            if (dto != null) {
                result.add(dto);
            }
        }
        return result;
    }
}
