package com.eactive.eai.manage.inflow;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Service;

import com.eactive.eai.common.inflow.CustomGroupBucket;
import com.eactive.eai.common.inflow.InflowControlManager;
import com.eactive.eai.common.inflow.InflowGroupVO;

@Service
public class InflowGroupBucketService {

    public GroupBucketStatusDTO getGroupBucketStatus(String groupId) {
        InflowControlManager manager = InflowControlManager.getInstance();

        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) {
        try {
            InflowControlManager manager = InflowControlManager.getInstance();
            Field field = InflowControlManager.class.getDeclaredField("groupBucketList");
            field.setAccessible(true);
            @SuppressWarnings("unchecked")
            Map<String, CustomGroupBucket> groupBucketList =
                (Map<String, CustomGroupBucket>) field.get(manager);
            return groupBucketList.get(groupId);
        } catch (Exception e) {
            return null;
        }
    }

    public List<GroupBucketStatusDTO> getAllGroupBucketStatus() {
        InflowControlManager manager = InflowControlManager.getInstance();
        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;
    }
}
