<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
	response.setHeader("Pragma", "No-cache");
	response.setHeader("Cache-Control", "no-cache");
	response.setHeader("Expires", "0");
%>

<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>

<!-- 페이지 커스텀 스타일 (fragment) -->
<jsp:include page="fragments/inflowGroupDetailStyle.jsp"/>

<script language="javascript">
var url      ='<c:url value="/onl/admin/inflow/inflowGroupControlMan.json" />';
var url_view ='<c:url value="/onl/admin/inflow/inflowGroupControlMan.view" />';
var isDetail = false;
var interfaceList = [];

function isValid() {
	if ($('input[name=groupName]').val().trim() == "") {
		alert("그룹명을 입력하여 주십시요.");
		$('input[name=groupName]').focus();
		return false;
	}
	return true;
}

function updateThresholdLabel() {
	var timeUnit = $('#thresholdTimeUnit').val();
	var $input = $('#thresholdInput');
	var $unit = $('#thresholdUnit');

	var unitLabels = {
		'': '',
		'SEC': 'req/sec',
		'MIN': 'req/min',
		'HOU': 'req/hour',
		'DAY': 'req/day',
		'MON': 'req/month'
	};

	$unit.text(unitLabels[timeUnit] || 'requests');

	if (timeUnit === '') {
		$input.prop('disabled', true).val('');
		$unit.css('visibility', 'hidden');
	} else {
		$input.prop('disabled', false);
		$unit.css('visibility', 'visible');
	}
}

function init(url, key, callback) {
	// useYn 초기값 설정 (기본: 사용)
	$('#useYn').val('1');
	updateThresholdLabel();

	if (typeof callback === 'function') {
		callback(url, key);
	}
}

function getSelectedTimeUnitText() {
	return $('#thresholdTimeUnit option:selected').text();
}

function detail(url, key) {
	if (!isDetail) return;
	$.ajax({
		type: "POST",
		url: url,
		dataType: "json",
		data: {cmd: 'DETAIL', groupId: key},
		success: function(json) {
			var groupId = json.GROUPID || json.groupId;
			$("input[name=groupId]").val(groupId);
			$("input[name=groupName]").val(json.GROUPNAME || json.groupName);
			$("input[name=thresholdPerSecond]").val(json.THRESHOLDPERSECOND || json.thresholdPerSecond);
			$("input[name=threshold]").val(json.THRESHOLD || json.threshold);
			$("select[name=thresholdTimeUnit]").val(json.THRESHOLDTIMEUNIT || json.thresholdTimeUnit || '');
			var useYnVal = json.USEYN || json.useYn || '1';
			$('#useYn').val(useYnVal);
			$('#useYnToggle').prop('checked', useYnVal === '1');
			$('#useYnLabel').text(useYnVal === '1' ? '사용' : '미사용');
			updateThresholdLabel();

			// 그룹 ID 표시 (수정 화면에서만)
			if (groupId) {
				$('#groupIdDisplay').text(groupId);
				$('#groupIdRow').show();
			}

			// 수정일시 표시
			var modifiedAt = json.MODIFIEDAT || json.modifiedAt;
			if (modifiedAt) {
				$('#modifiedAtText').text(modifiedAt);
				$('#modifiedAtInfo').show();
			}

			interfaceList = [];
			if (json.interfaceList && json.interfaceList.length > 0) {
				$.each(json.interfaceList, function(i, item) {
					interfaceList.push({
						interfaceId: item.interfaceId || item.INTERFACEID,
						interfaceDesc: item.interfaceDesc || item.INTERFACEDESC,
						useYn: item.useYn || item.USEYN || '1'
					});
				});
			}
			renderInterfaceList();
		},
		error: function(e) {
			alert(e.responseText);
		}
	});
}

function renderInterfaceList() {
	var container = $('#interfaceListContainer');
	container.empty();

	var activeCount = interfaceList.filter(function(item) {
		return item.useYn === '1' || item.useYn === undefined;
	}).length;
	$('#interfaceCountNum').text(interfaceList.length);
	if (interfaceList.length > 0 && activeCount === interfaceList.length) {
		$('#interfaceActiveLabel').html('<strong>전체 활성</strong>');
	} else {
		$('#interfaceActiveLabel').html('활성 <strong id="interfaceActiveNum">' + activeCount + '</strong>개');
	}

	if (interfaceList.length === 0) {
		container.html('<tr class="interface-empty-row" id="interfaceEmpty"><td colspan="3" class="interface-empty"><i class="material-icons">inbox</i> 매핑된 API가 없습니다</td></tr>');
		return;
	}

	$.each(interfaceList, function(i, item) {
		var useYn = item.useYn !== undefined ? item.useYn : '1';
		var checked = useYn === '1' ? 'checked' : '';
		var row = '<tr data-id="' + item.interfaceId + '">' +
			'<td class="col-id">' + item.interfaceId + '</td>' +
			'<td class="col-desc">' + (item.interfaceDesc || '-') + '</td>' +
			'<td class="col-action">' +
				'<label class="mini-toggle" title="사용여부">' +
					'<input type="checkbox" class="interface-use-toggle" data-id="' + item.interfaceId + '" ' + checked + ' />' +
					'<span class="mini-toggle-slider"></span>' +
				'</label>' +
				'<button type="button" class="btn-icon btn-delete-item" data-id="' + item.interfaceId + '" title="삭제">' +
					'<i class="material-icons">close</i>' +
				'</button>' +
			'</td>' +
			'</tr>';
		container.append(row);
	});
}

function getInterfaceListJson() {
	var gridData = [];
	$.each(interfaceList, function(i, item) {
		gridData.push({
			interfaceId: item.interfaceId,
			useYn: item.useYn !== undefined ? item.useYn : '1'
		});
	});
	return JSON.stringify(gridData);
}

// 인터페이스 선택 모달 관련
var ifModalState = {
	data: [],
	page: 1,
	pageSize: 10,
	totalCount: 0,
	selectedItem: null
};

function openIfModal() {
	ifModalState.page = 1;
	ifModalState.selectedItem = null;
	$('#ifSearchInput').val('');
	$('#ifModal').fadeIn(200, function() {
		$('#ifSearchInput').focus();
	});
	$(document.activeElement).blur();
	loadIfList();
}

function closeIfModal() {
	$('#ifModal').fadeOut(200);
}

function loadIfList() {
	var searchName = $('#ifSearchInput').val();
	$.ajax({
		type: "POST",
		url: url,
		dataType: "json",
		data: {
			cmd: 'INTERFACE_LIST',
			searchName: searchName,
			page: ifModalState.page,
			rows: ifModalState.pageSize
		},
		success: function(json) {
			ifModalState.data = json.rows || [];
			ifModalState.totalCount = json.records || 0;
			renderIfTable();
			renderIfPagination();
		},
		error: function(e) {
			alert(e.responseText);
		}
	});
}

function renderIfTable() {
	var tbody = $('#ifTableBody');
	tbody.empty();

	if (ifModalState.data.length === 0) {
		tbody.html('<tr><td colspan="2" class="if-table-empty">검색 결과가 없습니다</td></tr>');
		return;
	}

	$.each(ifModalState.data, function(i, item) {
		var interfaceId = item.INTERFACEID || item.interfaceId;
		var interfaceDesc = item.INTERFACEDESC || item.interfaceDesc || '-';
		var row = $('<tr data-id="' + interfaceId + '" data-desc="' + interfaceDesc + '">' +
			'<td class="col-id">' + interfaceId + '</td>' +
			'<td>' + interfaceDesc + '</td>' +
			'</tr>');
		tbody.append(row);
	});

	// 행 클릭 이벤트
	tbody.find('tr').on('click', function() {
		tbody.find('tr').removeClass('selected');
		$(this).addClass('selected');
		ifModalState.selectedItem = {
			interfaceId: $(this).data('id'),
			interfaceDesc: $(this).data('desc')
		};
	});

	// 더블클릭으로 바로 선택
	tbody.find('tr').on('dblclick', function() {
		ifModalState.selectedItem = {
			interfaceId: $(this).data('id'),
			interfaceDesc: $(this).data('desc')
		};
		selectInterface();
	});
}

function renderIfPagination() {
	var totalPages = Math.ceil(ifModalState.totalCount / ifModalState.pageSize);
	var currentPage = ifModalState.page;

	$('#ifTotalCount').text(ifModalState.totalCount);

	// 이전/다음 버튼
	$('#ifPrevBtn').prop('disabled', currentPage <= 1);
	$('#ifNextBtn').prop('disabled', currentPage >= totalPages);

	// 페이지 번호
	var pageNumContainer = $('#ifPageNum');
	pageNumContainer.empty();

	if (totalPages <= 0) return;

	var startPage = Math.max(1, currentPage - 2);
	var endPage = Math.min(totalPages, startPage + 4);
	if (endPage - startPage < 4) {
		startPage = Math.max(1, endPage - 4);
	}

	for (var i = startPage; i <= endPage; i++) {
		var activeClass = (i === currentPage) ? ' active' : '';
		var btn = $('<button type="button" class="if-page-btn' + activeClass + '">' + i + '</button>');
		btn.data('page', i);
		pageNumContainer.append(btn);
	}

	// 페이지 번호 클릭
	pageNumContainer.find('.if-page-btn').on('click', function() {
		ifModalState.page = $(this).data('page');
		ifModalState.selectedItem = null;
		loadIfList();
	});
}

// 탭 전환 기능
function switchTab(tabName) {
	$('.detail-tab').removeClass('active');
	$('.detail-tab[data-tab="' + tabName + '"]').addClass('active');
	$('.tab-content').removeClass('active');
	$('#tab' + tabName.charAt(0).toUpperCase() + tabName.slice(1) + 'Content').addClass('active');

	if (tabName === 'status' && isDetail) {
		loadBucketStatus();
	}
}

// 버킷 현황 조회
function loadBucketStatus() {
	var groupId = $('input[name=groupId]').val();
	if (!groupId) return;

	$('#bucketServerList').html('<div class="bucket-empty-msg"><i class="material-icons">hourglass_empty</i>조회 중...</div>');

	$.ajax({
		type: 'POST',
		url: url,
		data: { cmd: 'LIST_BUCKET_STATUS', groupId: groupId },
		dataType: 'json',
		success: function(result) {
			renderBucketStatus(result.servers || []);
			$('#lastRefreshTime').text(formatDateTime(new Date()));
		},
		error: function(e) {
			$('#bucketServerList').html('<div class="bucket-empty-msg bucket-error-msg"><i class="material-icons">error_outline</i>조회 실패: ' + e.statusText + '</div>');
		}
	});
}

function formatDateTime(date) {
	var h = date.getHours();
	var m = date.getMinutes();
	var s = date.getSeconds();
	return (h < 10 ? '0' + h : h) + ':' + (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
}

function renderBucketStatus(servers) {
	var container = $('#bucketServerList');
	container.empty();

	if (servers.length === 0) {
		container.html('<div class="bucket-empty-msg"><i class="material-icons">dns</i>등록된 서버가 없습니다</div>');
		$('#bucketSummary').hide();
		return;
	}

	// 전체 합산 계산
	var onlineCount = 0;
	var perSecondCapacity = 0;
	var thresholdCapacity = 0;
	var thresholdTimeUnit = '';

	$.each(servers, function(i, server) {
		if (server.status === 'online' && server.data && server.data.buckets) {
			onlineCount++;
			$.each(server.data.buckets, function(j, bucket) {
				if (bucket.type === 'perSecond') {
					perSecondCapacity += bucket.capacity || 0;
				} else if (bucket.type === 'threshold') {
					thresholdCapacity += bucket.capacity || 0;
					if (!thresholdTimeUnit) thresholdTimeUnit = bucket.timeUnit;
				}
			});
		}
	});

	// 요약 영역 표시
	if (onlineCount > 0) {
		$('#summaryInstanceCount').html(onlineCount + '<span class="unit">개</span>');

		var configPerSecond = parseInt($('input[name=thresholdPerSecond]').val()) || 0;
		var configThreshold = parseInt($('input[name=threshold]').val()) || 0;

		if (configPerSecond > 0) {
			$('#summaryPerSecond').html(formatNumber(perSecondCapacity) + '<span class="unit">req/sec</span>');
			$('#summaryPerSecondCalc').text(formatNumber(configPerSecond) + ' × ' + onlineCount + ' 인스턴스');
			$('#summaryPerSecondWrap').show();
		} else {
			$('#summaryPerSecondWrap').hide();
		}

		if (configThreshold > 0) {
			var timeUnitLabel = getTimeUnitText(thresholdTimeUnit);
			$('#summaryThreshold').html(formatNumber(thresholdCapacity) + '<span class="unit">req/' + timeUnitLabel + '</span>');
			$('#summaryThresholdCalc').text(formatNumber(configThreshold) + ' × ' + onlineCount + ' 인스턴스');
			$('#summaryThresholdWrap').show();
		} else {
			$('#summaryThresholdWrap').hide();
		}

		// 활성 API 정보 표시
		var activeApis = interfaceList.filter(function(item) {
			return item.useYn === '1' || item.useYn === undefined;
		});
		$('#summaryActiveApi').html(activeApis.length + '<span class="unit">개</span>');
		if (activeApis.length > 0) {
			var apiIds = activeApis.map(function(item) { return item.interfaceId; });
			var displayText = apiIds.length <= 3 ? apiIds.join(', ') : apiIds.slice(0, 3).join(', ') + ' 외 ' + (apiIds.length - 3) + '개';
			$('#summaryActiveApiList').text(displayText);
		} else {
			$('#summaryActiveApiList').text('');
		}

		$('#bucketSummary').show();
	} else {
		$('#bucketSummary').hide();
	}

	$.each(servers, function(i, server) {
		var statusClass = server.status || 'offline';
		var statusText = { online: '정상', offline: '오프라인', no_data: '데이터 없음' };

		var card = '<div class="bucket-server-card">' +
			'<div class="bucket-server-header">' +
				'<div>' +
					'<span class="bucket-server-name">' + server.serverName + '</span> ' +
					'<span class="bucket-server-ip">' + server.serverIp + ':' + server.serverPort + '</span>' +
				'</div>' +
				'<span class="bucket-server-status ' + statusClass + '">' + (statusText[statusClass] || statusClass) + '</span>' +
			'</div>' +
			'<div class="bucket-server-body">' + renderBucketBody(server) + '</div>' +
		'</div>';
		container.append(card);
	});
}

function renderBucketBody(server) {
	if (server.status === 'offline') {
		return '<div class="bucket-error-msg">' + (server.message || '서버 연결 실패') + '</div>';
	}
	if (server.status === 'no_data') {
		return '<div class="bucket-empty-msg" style="padding:10px;"><i class="material-icons" style="font-size:18px;">info_outline</i> ' + (server.message || '그룹이 로드되지 않음') + '</div>';
	}

	var data = server.data;
	if (!data || !data.buckets || data.buckets.length === 0) {
		return '<div class="bucket-empty-msg" style="padding:10px;">버킷 정보 없음</div>';
	}

	var html = '<div class="bucket-info-grid">';
	$.each(data.buckets, function(j, bucket) {
		var typeLabel = bucket.type === 'perSecond' ? '초당 임계치' : '추가 임계치';
		var timeUnitText = getTimeUnitText(bucket.timeUnit);
		var usagePercent = bucket.usagePercent || 0;
		var progressClass = usagePercent < 50 ? 'low' : (usagePercent < 80 ? 'medium' : 'high');

		html += '<div class="bucket-card">' +
			'<div class="bucket-card-header">' +
				'<span class="bucket-type">' + typeLabel + '</span>' +
				'<span class="bucket-type-badge">' + timeUnitText + '</span>' +
			'</div>' +
			'<div class="bucket-progress-wrap">' +
				'<div class="bucket-progress-bar">' +
					'<div class="bucket-progress-fill ' + progressClass + '" style="width:' + usagePercent + '%"></div>' +
				'</div>' +
			'</div>' +
			'<div class="bucket-stats">' +
				'<span>사용량: <span class="bucket-stats-value">' + usagePercent.toFixed(1) + '%</span></span>' +
				'<span>잔여: <span class="bucket-stats-value">' + formatNumber(bucket.availableTokens) + '</span> / ' + formatNumber(bucket.capacity) + '</span>' +
			'</div>' +
		'</div>';
	});
	html += '</div>';
	return html;
}

function getTimeUnitText(timeUnit) {
	var units = { SEC: '초', MIN: '분', HOU: '시간', DAY: '일', MON: '월' };
	return units[timeUnit] || timeUnit || '-';
}

function formatNumber(num) {
	if (num === undefined || num === null) return '-';
	return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}

function selectInterface() {
	if (!ifModalState.selectedItem) {
		alert('API를 선택하여 주십시오.');
		return;
	}

	var newId = String(ifModalState.selectedItem.interfaceId);

	// 현재 화면 내 중복 체크
	var exists = interfaceList.some(function(item) {
		return String(item.interfaceId) === newId;
	});

	if (exists) {
		alert('이미 추가된 API입니다.');
		return;
	}

	// 서버에 다른 그룹 등록 여부 체크
	var groupId = $('input[name=groupId]').val();
	$.ajax({
		type: 'POST',
		url: url,
		data: { cmd: 'LIST_CHECK_DUPLICATE', interfaceId: newId, groupId: groupId },
		dataType: 'json',
		async: false,
		success: function(result) {
			if (result.duplicate) {
				showAlert('<strong>' + newId + '</strong> API는<br/><strong>[' + result.groupName + ']</strong> 그룹에 이미 등록되어 있습니다.', {
					type: 'warning',
					title: '중복 등록 불가'
				});
			} else {
				interfaceList.push(ifModalState.selectedItem);
				renderInterfaceList();
				closeIfModal();
			}
		},
		error: function() {
			showAlert('중복 체크 중 오류가 발생했습니다.', { type: 'error' });
		}
	});
}

$(document).ready(function() {
	var returnUrl = getReturnUrlForReturn();
	var key = "${param.groupId}";
	if (key != "" && key != "null") {
		isDetail = true;
	}

	init(url, key, detail);

	$('#thresholdTimeUnit').on('change', function() {
		updateThresholdLabel();
	});

	// 사용여부 토글 변경 시 hidden 값 및 라벨 업데이트
	$('#useYnToggle').on('change', function() {
		var isChecked = $(this).is(':checked');
		$('#useYn').val(isChecked ? '1' : '0');
		$('#useYnLabel').text(isChecked ? '사용' : '미사용');
	});

	// 인터페이스 삭제 버튼 (동적 요소이므로 위임)
	$(document).on('click', '.btn-delete-item', function() {
		var id = $(this).data('id');
		interfaceList = interfaceList.filter(function(item) {
			return item.interfaceId !== id;
		});
		renderInterfaceList();
	});

	// 인터페이스 사용여부 토글 (동적 요소이므로 위임)
	$(document).on('change', '.interface-use-toggle', function() {
		var id = $(this).data('id');
		var useYn = $(this).is(':checked') ? '1' : '0';
		$.each(interfaceList, function(i, item) {
			if (item.interfaceId === id) {
				item.useYn = useYn;
			}
		});
		// 활성 건수 업데이트
		var activeCount = interfaceList.filter(function(item) {
			return item.useYn === '1' || item.useYn === undefined;
		}).length;
		if (interfaceList.length > 0 && activeCount === interfaceList.length) {
			$('#interfaceActiveLabel').html('<strong>전체 활성</strong>');
		} else {
			$('#interfaceActiveLabel').html('활성 <strong id="interfaceActiveNum">' + activeCount + '</strong>개');
		}
	});

	$("#btn_modify").click(function() {
		$(this).blur();
		if (!isValid()) return;

		var confirmMsg = isDetail ? '변경사항을 저장하시겠습니까?' : '새 그룹을 등록하시겠습니까?';
		showConfirm(confirmMsg, {
			title: '저장 확인',
			confirmText: '저장',
			onConfirm: function() {
				var postData = $('#ajaxForm').serializeArray();
				if (isDetail) {
					postData.push({name: "cmd", value: "UPDATE"});
				} else {
					postData.push({name: "cmd", value: "INSERT"});
				}

				postData.push({name: "interfaceListJson", value: getInterfaceListJson()});

				var isInsert = !isDetail;
				$.ajax({
					type: "POST",
					url: url,
					data: postData,
					success: function(args) {
						if (isInsert) {
							// 신규 등록 시 목록으로 이동
							showAlert("<%= localeMessage.getString("common.saveMsg") %>", {
								type: 'success',
								title: '저장 완료',
								onClose: function() {
									goNav(returnUrl);
								}
							});
						} else {
							// 수정 시 현재 화면 유지
							showAlert("<%= localeMessage.getString("common.saveMsg") %>", {
								type: 'success',
								title: '저장 완료'
							});
						}
					},
					error: function(e) {
						showAlert(e.responseText, { type: 'error' });
					}
				});
			}
		});
	});

	$("#btn_delete").click(function() {
		$(this).blur();
		var groupName = $('input[name=groupName]').val();
		showConfirm('<strong>[' + groupName + ']</strong> 그룹을 삭제하시겠습니까?<br/><span style="color:#999;font-size:11px;">매핑된 API 정보도 함께 삭제됩니다.</span>', {
			type: 'error',
			title: '삭제 확인',
			confirmText: '삭제',
			onConfirm: function() {
				$.ajax({
					type: "POST",
					url: url,
					data: {cmd: 'DELETE', groupId: $('input[name=groupId]').val()},
					success: function(args) {
						showAlert("<%= localeMessage.getString("common.deleteMsg") %>", {
							type: 'success',
							title: '삭제 완료',
							onClose: function() {
								goNav(returnUrl);
							}
						});
					},
					error: function(e) {
						showAlert(e.responseText, { type: 'error' });
					}
				});
			}
		});
	});

	$("#btn_previous").click(function() {
		goNav(returnUrl);
	});

	// 인터페이스 추가 버튼 → 모달 열기
	$("#btn_popup_interface").click(function() {
		openIfModal();
	});

	// 인터페이스 선택 모달 이벤트
	$(".if-modal-close, #ifCancelBtn").click(function() {
		closeIfModal();
	});
	$("#ifModal").click(function(e) {
		if (e.target === this) closeIfModal();
	});
	$("#ifSearchBtn").click(function() {
		ifModalState.page = 1;
		ifModalState.selectedItem = null;
		loadIfList();
	});
	$("#ifSearchInput").keydown(function(e) {
		if (e.keyCode === 13) {
			e.preventDefault();
			$("#ifSearchBtn").click();
		}
	});
	$("#ifSelectBtn").click(function() {
		selectInterface();
	});
	$("#ifPrevBtn").click(function() {
		if (ifModalState.page > 1) {
			ifModalState.page--;
			ifModalState.selectedItem = null;
			loadIfList();
		}
	});
	$("#ifNextBtn").click(function() {
		var totalPages = Math.ceil(ifModalState.totalCount / ifModalState.pageSize);
		if (ifModalState.page < totalPages) {
			ifModalState.page++;
			ifModalState.selectedItem = null;
			loadIfList();
		}
	});

	buttonControl(isDetail);
	titleControl(isDetail);

	// 탭 전환 이벤트
	$('.detail-tab').click(function() {
		var tabName = $(this).data('tab');
		switchTab(tabName);
	});

	// 현황 탭 표시 (상세 조회 시에만)
	if (isDetail) {
		$('#tabStatus').show();
	}

	// 버킷 새로고침 버튼
	$('#btn_refresh_bucket').click(function() {
		loadBucketStatus();
	});

	// 도움말 모달
	$("#btn_help").click(function() {
		$(document.activeElement).blur();
		$("#helpModal").fadeIn(200);
	});
	$(".help-modal-close, .help-modal-overlay").click(function(e) {
		if (e.target === this) {
			$("#helpModal").fadeOut(200);
		}
	});
	$(document).keydown(function(e) {
		if (e.keyCode === 27) {
			$("#helpModal").fadeOut(200);
			$("#ifModal").fadeOut(200);
		}
	});
});
</script>
</head>
<body>
	<div class="right_box">
		<div class="content_top">
			<ul class="path">
				<li><a href="#">${rmsMenuPath}</a></li>
			</ul>
		</div>
		<div class="content_middle" id="content_middle">
			<div class="search_wrap">
				<button type="button" class="cssbtn" id="btn_help"><i class="material-icons">help_outline</i> 도움말</button>
				<button type="button" class="cssbtn" id="btn_delete" level="W" status="DETAIL"><i class="material-icons">delete</i> <%= localeMessage.getString("button.delete") %></button>
				<button type="button" class="cssbtn" id="btn_modify" level="W" status="DETAIL,NEW"><i class="material-icons">save</i> <%= localeMessage.getString("button.save") %></button>
				<button type="button" class="cssbtn" id="btn_previous"><i class="material-icons">arrow_back</i> <%= localeMessage.getString("button.previous") %></button>
			</div>
			<div class="title-wrap">
				<div class="title">유량제어 그룹 관리<span class="tooltip">유량제어 그룹 관리</span></div>
				<span id="modifiedAtInfo" class="modified-badge" style="display:none;">
					<i class="material-icons">update</i><span id="modifiedAtText">-</span>
				</span>
			</div>

			<!-- 탭 네비게이션 -->
			<div class="detail-tabs" id="detailTabs">
				<button type="button" class="detail-tab active" data-tab="config">
					<i class="material-icons">settings</i> 설정
				</button>
				<button type="button" class="detail-tab" data-tab="status" id="tabStatus" style="display:none;">
					<i class="material-icons">analytics</i> 현황
				</button>
			</div>

			<!-- 설정 탭 -->
			<div class="tab-content active" id="tabConfigContent">
			<form id="ajaxForm">
				<input type="hidden" name="groupId" />
				<input type="hidden" name="useYn" id="useYn" value="1" />

				<!-- 기본 정보 -->
				<table class="form-table">
					<colgroup>
						<col style="width:120px" />
						<col />
					</colgroup>
					<tbody>
						<tr id="groupIdRow" style="display:none;">
							<th>그룹 ID</th>
							<td><span id="groupIdDisplay" style="font-family:Consolas, monospace; font-size:12px; color:#666;"></span></td>
						</tr>
						<tr>
							<th>그룹명 <span style="color:red">*</span></th>
							<td><input type="text" name="groupName" style="width:300px" /></td>
						</tr>
						<tr>
							<th>사용여부</th>
							<td>
								<div class="toggle-wrap">
									<label class="ios-toggle">
										<input type="checkbox" id="useYnToggle" checked />
										<span class="ios-toggle-slider"></span>
									</label>
									<span class="toggle-label" id="useYnLabel">사용</span>
								</div>
							</td>
						</tr>
					</tbody>
				</table>

				<!-- 유량제어 설정 -->
				<span class="section-label">유량제어 설정</span>
				<table class="form-table">
					<colgroup>
						<col style="width:120px" />
						<col />
					</colgroup>
					<tbody>
						<tr>
							<th>
								초당 임계치
								<span class="hint-icon"><i class="material-icons">help_outline</i>
									<span class="hint-bubble">1초 단위의 순간 트래픽 제한입니다. 매 초마다 설정한 건수만큼 토큰이 리필되며, 초과 시 요청이 거부됩니다.</span>
								</span>
							</th>
							<td>
								<div class="threshold-group">
									<input type="number" name="thresholdPerSecond" placeholder="0" />
									<span class="unit">req/sec</span>
								</div>
							</td>
						</tr>
						<tr>
							<th>
								추가 임계치
								<span class="hint-icon"><i class="material-icons">help_outline</i>
									<span class="hint-bubble">장시간 누적 트래픽 제한입니다. 시간단위를 선택하면 해당 주기마다 토큰이 리필됩니다.</span>
								</span>
							</th>
							<td>
								<div class="threshold-group">
									<select name="thresholdTimeUnit" id="thresholdTimeUnit" class="styled-select">
										<option value="">미사용</option>
										<option value="MIN">분 (MIN)</option>
										<option value="HOU">시간 (HOU)</option>
										<option value="DAY">일 (DAY)</option>
										<option value="MON">월 (MON)</option>
									</select>
									<input type="number" name="threshold" id="thresholdInput" placeholder="0" />
									<span class="unit" id="thresholdUnit">requests</span>
								</div>
							</td>
						</tr>
					</tbody>
				</table>

				<!-- API 매핑 -->
				<span class="section-label">API 매핑</span>
				<div class="interface-header">
					<span class="interface-count">매핑된 API <strong id="interfaceCountNum">0</strong>개 (<span id="interfaceActiveLabel">활성 <strong id="interfaceActiveNum">0</strong>개</span>)</span>
					<button type="button" class="cssbtn" id="btn_popup_interface"><i class="material-icons">add</i> 추가</button>
				</div>
				<div class="interface-list-wrap">
					<table class="interface-list-table">
						<colgroup>
							<col class="col-id" />
							<col class="col-desc" />
							<col class="col-action" />
						</colgroup>
						<thead>
							<tr>
								<th><%= localeMessage.getString("eaiMessage.eaiSvcName")%></th>
								<th>설명</th>
								<th>관리</th>
							</tr>
						</thead>
						<tbody id="interfaceListContainer">
							<tr class="interface-empty-row" id="interfaceEmpty">
								<td colspan="3" class="interface-empty"><i class="material-icons">inbox</i> 매핑된 API가 없습니다</td>
							</tr>
						</tbody>
					</table>
				</div>
			</form>
			</div><!-- /tabConfigContent -->

			<!-- 현황 탭 -->
			<div class="tab-content" id="tabStatusContent">
				<div class="bucket-status-wrap">
					<div class="bucket-refresh-bar">
						<span class="last-refresh">마지막 갱신: <span id="lastRefreshTime">-</span></span>
						<button type="button" class="cssbtn" id="btn_refresh_bucket"><i class="material-icons">refresh</i> 새로고침</button>
					</div>

					<!-- 전체 합산 요약 -->
					<div class="bucket-summary" id="bucketSummary" style="display:none;">
						<div class="bucket-summary-title"><i class="material-icons">functions</i> 전체 인스턴스 합산</div>
						<div class="bucket-summary-grid">
							<div class="bucket-summary-item">
								<span class="bucket-summary-label">활성 인스턴스</span>
								<span class="bucket-summary-value" id="summaryInstanceCount">0<span class="unit">개</span></span>
							</div>
							<div class="bucket-summary-item" id="summaryPerSecondWrap">
								<span class="bucket-summary-label">초당 임계치 (전체)</span>
								<span class="bucket-summary-value" id="summaryPerSecond">0<span class="unit">req/sec</span></span>
								<span class="bucket-summary-sub" id="summaryPerSecondCalc"></span>
							</div>
							<div class="bucket-summary-item" id="summaryThresholdWrap">
								<span class="bucket-summary-label">추가 임계치 (전체)</span>
								<span class="bucket-summary-value" id="summaryThreshold">0<span class="unit">req</span></span>
								<span class="bucket-summary-sub" id="summaryThresholdCalc"></span>
							</div>
							<div class="bucket-summary-item">
								<span class="bucket-summary-label">적용 API</span>
								<span class="bucket-summary-value" id="summaryActiveApi">0<span class="unit">개</span></span>
								<span class="bucket-summary-sub" id="summaryActiveApiList"></span>
							</div>
						</div>
					</div>

					<div class="bucket-server-list" id="bucketServerList">
						<div class="bucket-empty-msg">
							<i class="material-icons">hourglass_empty</i>
							버킷 현황을 조회하려면 새로고침 버튼을 클릭하세요
						</div>
					</div>
				</div>
			</div><!-- /tabStatusContent -->

		</div>
	</div>

	<!-- 인터페이스 선택 모달 (fragment) -->
	<jsp:include page="fragments/inflowGroupInterfaceModal.jsp"/>

	<!-- 도움말 모달 (fragment) -->
	<jsp:include page="fragments/inflowGroupHelpModal.jsp"/>
</body>
</html>
