@extends('layouts.app')

@section('title', 'API Explorer')

@section('content')
{{-- hx-boost 네비게이션에서도 스타일이 적용되도록 content 안에 포함 --}}
<style>
    /* 3-Panel 레이아웃 */
    .api-explorer {
        display: grid;
        grid-template-columns: 280px 1fr 1fr;
        height: calc(100vh - 120px);
        gap: 0;
    }

    /* 사이드바 */
    .api-sidebar {
        border-right: 1px solid #e5e7eb;
        display: flex;
        flex-direction: column;
        overflow: hidden;
    }

    .api-sidebar-header {
        padding: 1rem;
        border-bottom: 1px solid #e5e7eb;
        flex-shrink: 0;
    }

    .api-sidebar-content {
        flex: 1;
        overflow-y: auto;
    }

    /* 요청/응답 패널 */
    .api-request-panel,
    .api-response-panel {
        display: flex;
        flex-direction: column;
        overflow: hidden;
    }

    .api-request-panel {
        border-right: 1px solid #e5e7eb;
    }

    .panel-header {
        padding: 1rem;
        border-bottom: 1px solid #e5e7eb;
        flex-shrink: 0;
    }

    .panel-content {
        flex: 1;
        overflow-y: auto;
        padding: 1rem;
    }

    /* HTTP 메서드 배지 */
    .method-badge {
        display: inline-flex;
        align-items: center;
        padding: 0.125rem 0.5rem;
        font-size: 0.75rem;
        font-weight: 600;
        border-radius: 0.25rem;
        text-transform: uppercase;
    }

    .method-get { background: #dcfce7; color: #166534; }
    .method-post { background: #dbeafe; color: #1e40af; }
    .method-put { background: #fef3c7; color: #92400e; }
    .method-patch { background: #ffedd5; color: #9a3412; }
    .method-delete { background: #fee2e2; color: #991b1b; }

    /* 상태 코드 */
    .status-2xx { color: #16a34a; }
    .status-3xx { color: #2563eb; }
    .status-4xx { color: #ca8a04; }
    .status-5xx { color: #dc2626; }

    /* 엔드포인트 아이템 */
    .endpoint-item {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        padding: 0.5rem 1rem;
        cursor: pointer;
        transition: background-color 0.15s;
    }

    .endpoint-item:hover {
        background: #f3f4f6;
    }

    .endpoint-item.active {
        background: #eff6ff;
        border-left: 3px solid #3b82f6;
    }

    .endpoint-path {
        flex: 1;
        font-size: 0.875rem;
        color: #374151;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* 태그 그룹 */
    .tag-group {
        margin-bottom: 0.5rem;
    }

    .tag-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 0.5rem 1rem;
        font-weight: 600;
        font-size: 0.75rem;
        text-transform: uppercase;
        color: #6b7280;
        cursor: pointer;
    }

    .tag-header:hover {
        background: #f9fafb;
    }

    /* JSON 에디터 */
    .json-editor {
        width: 100%;
        min-height: 200px;
        font-family: 'Monaco', 'Menlo', monospace;
        font-size: 0.875rem;
        padding: 0.75rem;
        border: 1px solid #e5e7eb;
        border-radius: 0.375rem;
        resize: vertical;
    }

    /* 리사이즈 핸들 */
    .resize-handle {
        width: 4px;
        background: transparent;
        cursor: col-resize;
        transition: background-color 0.15s;
    }

    .resize-handle:hover {
        background: #3b82f6;
    }

    /* 반응형 */
    @media (max-width: 1280px) {
        .api-explorer {
            grid-template-columns: 250px 1fr;
        }

        .api-response-panel {
            display: none;
        }
    }

    @media (max-width: 768px) {
        .api-explorer {
            grid-template-columns: 1fr;
            grid-template-rows: auto 1fr;
        }

        .api-sidebar {
            max-height: 40vh;
        }
    }
</style>

    <!-- 페이지 헤더 -->
    <div class="flex justify-between items-center mb-4">
        <div>
            <h1 class="text-2xl font-bold text-gray-800">API Explorer</h1>
            <p class="text-sm text-gray-500">OpenAPI 기반 API 테스트 도구</p>
        </div>
        <div class="flex items-center gap-3">
            <!-- 환경 선택 -->
            <select id="environment-select" class="px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500">
                @foreach($environments as $env)
                    <option value="{{ $env->id }}"
                            data-base-url="{{ $env->base_url }}"
                            data-api-key="{{ $env->decrypted_api_key }}"
                            data-auth-token="{{ $env->decrypted_auth_token }}"
                            {{ $env->is_default ? 'selected' : '' }}>
                        {{ $env->name }}
                    </option>
                @endforeach
            </select>

            <!-- 인증 버튼 -->
            <button onclick="DevToolsAuth.openModal()" class="px-3 py-2 border border-gray-300 rounded-lg text-sm hover:bg-gray-50 flex items-center gap-2" title="인증 설정">
                <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z" />
                </svg>
                <span id="auth-status" class="dev-tools-auth-status text-gray-500">인증 필요</span>
            </button>

            <!-- 히스토리 버튼 -->
            <button onclick="toggleHistoryDrawer()" class="p-2 text-gray-600 hover:bg-gray-100 rounded-lg" title="히스토리">
                <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
                </svg>
            </button>

            <!-- API 사용 현황 버튼 -->
            <a href="{{ route('dev-tools.api-explorer.usage') }}" class="p-2 text-gray-600 hover:bg-gray-100 rounded-lg" title="API 사용 현황">
                <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
                </svg>
            </a>

            <!-- 설정 버튼 -->
            <button onclick="openSettingsModal()" class="p-2 text-gray-600 hover:bg-gray-100 rounded-lg" title="설정">
                <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
                </svg>
            </button>
        </div>
    </div>

    <!-- 3-Panel 레이아웃 -->
    <div class="api-explorer bg-white rounded-lg shadow-sm overflow-hidden">
        <!-- 사이드바: API 목록 -->
        <div class="api-sidebar">
            <div class="api-sidebar-header">
                <!-- 검색 (클라이언트 사이드 필터링) -->
                <input type="text"
                       id="search-input"
                       placeholder="API 검색..."
                       class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
                       oninput="filterEndpoints()"
                       autocomplete="off">

                <!-- 메서드 필터 -->
                <div id="method-filters" class="flex flex-wrap gap-1 mt-2">
                    @foreach(['GET', 'POST', 'PUT', 'PATCH', 'DELETE'] as $method)
                        <label class="inline-flex items-center cursor-pointer">
                            <input type="checkbox" value="{{ $method }}" class="hidden method-filter" onchange="toggleMethodFilter(this)">
                            <span class="method-badge method-{{ strtolower($method) }} opacity-40 hover:opacity-100 transition-opacity">
                                {{ $method }}
                            </span>
                        </label>
                    @endforeach
                </div>
            </div>

            <div class="api-sidebar-content" id="endpoint-list">
                @include('dev-tools.api-explorer.partials.sidebar', [
                    'endpointsByTag' => $endpoints,
                    'bookmarks' => $bookmarks
                ])
            </div>
        </div>

        <!-- 요청 패널 -->
        <div class="api-request-panel" id="request-panel">
            <div class="panel-header">
                <h3 class="font-semibold text-gray-700">요청</h3>
            </div>
            <div class="panel-content">
                <div class="text-center text-gray-400 py-12">
                    <svg class="w-12 h-12 mx-auto mb-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
                    </svg>
                    <p>왼쪽에서 API를 선택하세요</p>
                </div>
            </div>
        </div>

        <!-- 응답 패널 -->
        <div class="api-response-panel" id="response-panel">
            <div class="panel-header flex items-center justify-between">
                <h3 class="font-semibold text-gray-700">응답</h3>
                <div id="response-meta" class="text-sm text-gray-500"></div>
            </div>
            <div class="panel-content">
                <div id="response-content" class="text-center text-gray-400 py-12">
                    <svg class="w-12 h-12 mx-auto mb-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
                    </svg>
                    <p>API를 실행하면 응답이 여기에 표시됩니다</p>
                </div>
            </div>
        </div>
    </div>

    {{-- 인증 모달: 전역 레이아웃(app.blade.php)에서 포함 --}}

    <!-- 히스토리 서랍 (오버레이) -->
    <div id="history-drawer" class="fixed inset-y-0 right-0 w-96 bg-white shadow-xl transform translate-x-full transition-transform duration-300 z-50">
        <div class="h-full flex flex-col">
            <div class="p-4 border-b flex items-center justify-between">
                <h3 class="font-semibold text-gray-700">요청 히스토리</h3>
                <div class="flex items-center gap-2">
                    <button onclick="clearHistory()" class="text-sm text-red-600 hover:text-red-700">전체 삭제</button>
                    <button onclick="toggleHistoryDrawer()" class="p-1 hover:bg-gray-100 rounded">
                        <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
                        </svg>
                    </button>
                </div>
            </div>
            <div id="history-content" class="flex-1 overflow-y-auto">
                <!-- HTMX로 로드 -->
            </div>
        </div>
    </div>
    <div id="history-overlay" class="fixed inset-0 bg-black bg-opacity-25 hidden z-40" onclick="toggleHistoryDrawer()"></div>
@endsection

@push('scripts')
{{-- 인증 스크립트: 전역 레이아웃(app.blade.php)에서 포함 --}}

<script>
    // 전체 엔드포인트 데이터 (클라이언트 사이드 필터링용)
    const allEndpoints = @json($endpoints->flatten(1)->values());
    const bookmarkedEndpoints = @json($bookmarks->map(fn($b) => $b->endpoint . '|' . $b->method)->toArray());
    let activeMethodFilters = [];

    // 현재 선택된 엔드포인트
    let currentEndpoint = null;

    // 마지막 요청/응답 데이터 (재전송, AI 분석용)
    let lastRequestData = null;
    let lastResponseData = null;

    // 메서드 필터 토글
    function toggleMethodFilter(checkbox) {
        const badge = checkbox.nextElementSibling;
        const method = checkbox.value;

        if (checkbox.checked) {
            badge.classList.remove('opacity-40');
            if (!activeMethodFilters.includes(method)) {
                activeMethodFilters.push(method);
            }
        } else {
            badge.classList.add('opacity-40');
            activeMethodFilters = activeMethodFilters.filter(m => m !== method);
        }

        filterEndpoints();
    }

    // 클라이언트 사이드 필터링
    function filterEndpoints() {
        const searchQuery = document.getElementById('search-input').value.toLowerCase().trim();

        // 필터링
        let filtered = allEndpoints.filter(endpoint => {
            // 메서드 필터
            if (activeMethodFilters.length > 0 && !activeMethodFilters.includes(endpoint.method)) {
                return false;
            }

            // 검색어 필터
            if (searchQuery) {
                const searchTargets = [
                    endpoint.path || '',
                    endpoint.summary || '',
                    endpoint.description || '',
                    endpoint.operationId || '',
                    ...(endpoint.tags || [])
                ].map(s => s.toLowerCase());

                return searchTargets.some(target => target.includes(searchQuery));
            }

            return true;
        });

        // 태그별 그룹핑
        const grouped = {};
        filtered.forEach(endpoint => {
            const tag = endpoint.tags?.[0] || '기타';
            if (!grouped[tag]) grouped[tag] = [];
            grouped[tag].push(endpoint);
        });

        renderSidebar(grouped);
    }

    // 태그명 한글 매핑
    const tagNameMap = {
        // 인증/사용자
        'Auth': '인증',
        'User': '사용자',
        'Admin-Users': '관리자-사용자',
        'UserInvitation': '사용자 초대',
        'UserRole': '사용자 역할',
        'Member': '회원',

        // 결재
        'Approvals': '결재',
        'Approval Forms': '결재 양식',
        'Approval Lines': '결재선',

        // 조직
        'Tenant': '테넌트',
        'Tenant.Fields': '테넌트 필드',
        'Tenant.Option Groups': '테넌트 옵션그룹',
        'Tenant.Option Values': '테넌트 옵션값',
        'Tenant.Profiles': '테넌트 프로필',
        'TenantStatField': '테넌트 통계필드',
        'Menu': '메뉴',
        'Role': '역할',
        'RolePermission': '역할 권한',
        'Permission': '권한',
        'Department': '부서',

        // 품목/제품
        'Product': '제품',
        'Items': '품목',
        'Items BOM': '품목 BOM',
        'Items Files': '품목 파일',
        'ItemMaster': '품목마스터',
        'ItemMaster-Relationships': '품목마스터 관계',
        'Category': '카테고리',
        'Category-Fields': '카테고리 필드',
        'Category-Logs': '카테고리 로그',
        'Category-Templates': '카테고리 템플릿',
        'Classification': '분류',

        // 설계/BOM
        'Model': '모델',
        'ModelVersion': '모델 버전',
        'BomTemplate': 'BOM 템플릿',
        'Design BOM': '설계 BOM',
        'Design Audit': '설계 감사',
        'BOM Calculation': 'BOM 계산',

        // 견적/주문
        'Estimate': '견적',
        'Quote': '견적서',
        'Plans': '플랜',

        // 거래처
        'Client': '거래처',
        'ClientGroup': '거래처 그룹',
        'Sites': '현장',

        // 재무/회계
        'Account': '계정',
        'BankAccounts': '계좌',
        'Cards': '카드',
        'Deposits': '입금',
        'Withdrawals': '출금',
        'Sales': '매출',
        'Purchases': '매입',
        'Payments': '결제',
        'TaxInvoices': '세금계산서',
        'BadDebt': '악성채권',
        'Pricing': '단가',
        'Loans': '대출',

        // HR
        'Employees': '직원',
        'Attendances': '근태',
        'Leaves': '휴가',
        'Payrolls': '급여',
        'WorkSettings': '근무설정',

        // 파일/게시판
        'Files': '파일',
        'Folder': '폴더',
        'Board': '게시판',
        'Post': '게시글',
        'Popup': '팝업',

        // 설정
        'Settings - Common Codes': '설정 - 공통코드',
        'Settings - Fields': '설정 - 필드',
        'NotificationSetting': '알림설정',
        'BarobillSettings': '바로빌설정',
        'Subscriptions': '구독',

        // 시스템
        'Dashboard': '대시보드',
        'Reports': '리포트',
        'AI Reports': 'AI 리포트',
        'Push': '푸시',
        'Internal': '내부',
        'API Key 인증': 'API Key 인증',

        'default': '기타'
    };

    // 태그명 한글로 변환 (한글명 (English) 형식)
    function getKoreanTagName(tag) {
        const koreanName = tagNameMap[tag];
        if (koreanName && koreanName !== tag) {
            return `${koreanName} (${tag})`;
        }
        return tag;
    }

    // 사이드바 렌더링 (즐겨찾기 포함)
    function renderSidebar(groupedEndpoints) {
        const container = document.getElementById('endpoint-list');
        const tags = Object.keys(groupedEndpoints).sort();

        let html = '';

        // 즐겨찾기 섹션 (메서드 필터 적용)
        const bookmarkedItems = allEndpoints.filter(ep => {
            const key = ep.path + '|' + ep.method;
            if (!bookmarkedEndpoints.includes(key)) return false;

            // 메서드 필터 적용
            if (activeMethodFilters.length > 0 && !activeMethodFilters.includes(ep.method)) {
                return false;
            }

            // 검색어 필터 적용
            const searchQuery = document.getElementById('search-input').value.toLowerCase().trim();
            if (searchQuery) {
                const searchTargets = [
                    ep.path || '',
                    ep.summary || '',
                    ep.description || '',
                    ep.operationId || '',
                    ...(ep.tags || [])
                ].map(s => s.toLowerCase());
                return searchTargets.some(target => target.includes(searchQuery));
            }

            return true;
        });

        if (bookmarkedItems.length > 0) {
            html += `
                <div class="border-b border-gray-200 pb-2 mb-2">
                    <div class="tag-header">
                        <span class="flex items-center gap-2">
                            <svg class="w-4 h-4 text-yellow-500" fill="currentColor" viewBox="0 0 20 20">
                                <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"/>
                            </svg>
                            즐겨찾기 (${bookmarkedItems.length})
                        </span>
                    </div>
                    <div class="space-y-0.5">
            `;

            bookmarkedItems.forEach(endpoint => {
                html += `
                    <div class="endpoint-item" data-operation-id="${endpoint.operationId}" onclick="selectEndpoint('${endpoint.operationId}', this)">
                        <span class="method-badge method-${endpoint.method.toLowerCase()}">
                            ${endpoint.method}
                        </span>
                        <span class="endpoint-path" title="${escapeHtml(endpoint.summary || endpoint.path)}">
                            ${escapeHtml(endpoint.path)}
                        </span>
                        <button onclick="event.stopPropagation(); toggleBookmark('${escapeHtml(endpoint.path)}', '${endpoint.method}', this)"
                                class="text-yellow-500 hover:text-yellow-600">
                            <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
                                <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"/>
                            </svg>
                        </button>
                    </div>
                `;
            });

            html += `
                    </div>
                </div>
            `;
        }

        // 검색/필터 결과가 없는 경우
        if (tags.length === 0 && bookmarkedItems.length === 0) {
            container.innerHTML = `
                <div class="text-center text-gray-400 py-8">
                    <svg class="w-8 h-8 mx-auto mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                    </svg>
                    <p class="text-sm">검색 결과가 없습니다</p>
                </div>
            `;
            return;
        }

        // 태그별 그룹
        tags.forEach(tag => {
            const endpoints = groupedEndpoints[tag];
            const tagSlug = tag.toLowerCase().replace(/[^a-z0-9]/g, '-');
            const koreanTag = getKoreanTagName(tag);

            html += `
                <div class="tag-group">
                    <div class="tag-header" onclick="toggleTagGroup('${tagSlug}')">
                        <span class="flex items-center gap-2">
                            <svg class="w-4 h-4 text-gray-400 transition-transform rotate-90" id="chevron-${tagSlug}" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
                            </svg>
                            ${escapeHtml(koreanTag)}
                        </span>
                        <span class="text-xs text-gray-400">${endpoints.length}</span>
                    </div>
                    <div id="tag-${tagSlug}" class="space-y-0.5">
            `;

            endpoints.forEach(endpoint => {
                const isBookmarked = bookmarkedEndpoints.includes(endpoint.path + '|' + endpoint.method);
                const bookmarkClass = isBookmarked ? 'text-yellow-500' : 'text-gray-400';

                html += `
                    <div class="endpoint-item" data-operation-id="${endpoint.operationId}" onclick="selectEndpoint('${endpoint.operationId}', this)">
                        <span class="method-badge method-${endpoint.method.toLowerCase()}">
                            ${endpoint.method}
                        </span>
                        <span class="endpoint-path" title="${escapeHtml(endpoint.summary || endpoint.path)}">
                            ${escapeHtml(endpoint.path)}
                        </span>
                        <button onclick="event.stopPropagation(); toggleBookmark('${escapeHtml(endpoint.path)}', '${endpoint.method}', this)"
                                class="${bookmarkClass} hover:text-yellow-500">
                            <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
                                <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"/>
                            </svg>
                        </button>
                    </div>
                `;
            });

            html += `
                    </div>
                </div>
            `;
        });

        container.innerHTML = html;
    }

    // 환경 설정
    function getSelectedEnvironment() {
        const select = document.getElementById('environment-select');
        const option = select.options[select.selectedIndex];
        return {
            id: select.value,
            name: option.text,
            baseUrl: option.dataset.baseUrl,
            apiKey: option.dataset.apiKey,
            authToken: option.dataset.authToken
        };
    }

    // 엔드포인트 선택
    function selectEndpoint(operationId, element) {
        // 활성 상태 변경
        document.querySelectorAll('.endpoint-item').forEach(el => el.classList.remove('active'));
        element.classList.add('active');

        // 요청 패널 로드
        htmx.ajax('GET', `/dev-tools/api-explorer/endpoints/${operationId}`, {
            target: '#request-panel',
            swap: 'innerHTML'
        });
    }

    // 엔드포인트 선택 (path와 method로 검색) - 즐겨찾기용
    function selectEndpointByPath(path, method, element) {
        const endpoint = allEndpoints.find(ep => ep.path === path && ep.method === method);
        if (endpoint) {
            selectEndpoint(endpoint.operationId, element);
        } else {
            showToast('해당 API를 찾을 수 없습니다.', 'error');
        }
    }

    // API 실행
    async function executeApi(event) {
        event.preventDefault();

        const form = event.target;
        const formData = new FormData(form);
        const env = getSelectedEnvironment();

        // 필수값 밸리데이션
        const requiredFields = form.querySelectorAll('[required]');
        const missingFields = [];
        requiredFields.forEach(field => {
            const value = field.value?.trim();
            if (!value) {
                const label = field.closest('div')?.querySelector('label')?.textContent?.replace('*', '').trim()
                            || field.name.replace('path_', '').replace('query_', '');
                missingFields.push(label);
                field.classList.add('border-red-500', 'bg-red-50');
            } else {
                field.classList.remove('border-red-500', 'bg-red-50');
            }
        });

        if (missingFields.length > 0) {
            showToast(`필수값을 입력해주세요: ${missingFields.join(', ')}`, 'error');
            return;
        }

        // 요청 데이터 구성
        const method = formData.get('method');
        let url = env.baseUrl + formData.get('endpoint');

        // 경로 파라미터 치환
        const pathParams = {};
        formData.forEach((value, key) => {
            if (key.startsWith('path_')) {
                const paramName = key.replace('path_', '');
                pathParams[paramName] = value;
                url = url.replace(`{${paramName}}`, value);
            }
        });

        // 쿼리 파라미터
        const queryParams = {};
        formData.forEach((value, key) => {
            if (key.startsWith('query_') && value) {
                queryParams[key.replace('query_', '')] = value;
            }
        });

        // 헤더
        const headers = {
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        };
        if (env.apiKey) {
            headers['X-API-KEY'] = env.apiKey;
        }
        if (env.authToken) {
            headers['Authorization'] = 'Bearer ' + env.authToken;
        }

        // 바디
        let body = null;
        const bodyText = formData.get('body');
        if (bodyText) {
            try {
                body = JSON.parse(bodyText);
            } catch (e) {
                showToast('JSON 형식이 올바르지 않습니다.', 'error');
                return;
            }
        }

        // 로딩 표시
        const submitBtn = form.querySelector('button[type="submit"]');
        const originalText = submitBtn.innerHTML;
        submitBtn.innerHTML = '<svg class="w-5 h-5 animate-spin" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path></svg> 실행 중...';
        submitBtn.disabled = true;

        // 인증 정보 구성 (공유 인증 모듈 사용)
        const authPayload = DevToolsAuth.getAuthPayload();

        // 마지막 요청 데이터 저장 (재전송, AI 분석용)
        lastRequestData = {
            method: method,
            url: url,
            endpoint: formData.get('endpoint'),
            headers: headers,
            query: queryParams,
            body: body,
            environment: env.name,
            authPayload: authPayload
        };

        try {
            const response = await fetch('{{ route("dev-tools.api-explorer.execute") }}', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-TOKEN': '{{ csrf_token() }}'
                },
                body: JSON.stringify({
                    method: method,
                    url: url,
                    headers: headers,
                    query: queryParams,
                    body: body,
                    environment: env.name,
                    ...authPayload
                })
            });

            const result = await response.json();
            displayResponse(result);

        } catch (error) {
            displayResponse({
                status: 0,
                headers: {},
                body: { error: true, message: error.message },
                duration_ms: 0
            });
        } finally {
            submitBtn.innerHTML = originalText;
            submitBtn.disabled = false;
        }
    }

    // 응답 표시
    function displayResponse(result) {
        const meta = document.getElementById('response-meta');
        const content = document.getElementById('response-content');

        // 마지막 응답 데이터 저장
        lastResponseData = result;

        // 응답 컨테이너 스타일 변경 (가운데 정렬 → 왼쪽 정렬)
        content.className = 'text-left';

        // 오류 여부 판단
        const isError = result.status >= 400 || result.status === 0;

        // 메타 정보
        const statusClass = result.status >= 200 && result.status < 300 ? 'status-2xx' :
                           result.status >= 300 && result.status < 400 ? 'status-3xx' :
                           result.status >= 400 && result.status < 500 ? 'status-4xx' :
                           result.status >= 500 ? 'status-5xx' : 'text-gray-500';

        meta.innerHTML = `
            <span class="${statusClass} font-semibold">${result.status || 'Error'}</span>
            <span class="mx-2">·</span>
            <span>${result.duration_ms}ms</span>
        `;

        // 본문 (유니코드/슬래시 이스케이프 처리)
        const bodyStr = formatJsonBody(result.body);

        // 오류 시 액션 버튼
        const errorActions = isError ? `
            <div class="flex items-center gap-2 p-3 bg-red-50 border border-red-200 rounded-lg mb-4">
                <svg class="w-5 h-5 text-red-500 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
                </svg>
                <span class="text-sm text-red-700 flex-1">요청이 실패했습니다 (${result.status || 'Error'})</span>
                <button onclick="copyForAiAnalysis()" class="px-3 py-1.5 text-xs bg-purple-600 hover:bg-purple-700 text-white rounded flex items-center gap-1.5 transition">
                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/>
                    </svg>
                    AI 분석
                </button>
                <button onclick="retryLastRequest()" class="px-3 py-1.5 text-xs bg-blue-600 hover:bg-blue-700 text-white rounded flex items-center gap-1.5 transition">
                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
                    </svg>
                    재전송
                </button>
            </div>
        ` : '';

        content.innerHTML = `
            <div class="space-y-4 text-left">
                ${errorActions}
                <!-- 헤더 -->
                <div class="text-left">
                    <h4 class="text-sm font-medium text-gray-700 mb-2 text-left">응답 헤더</h4>
                    <div class="bg-gray-50 rounded p-3 text-xs font-mono overflow-x-auto text-left">
                        ${Object.entries(result.headers || {}).map(([k, v]) =>
                            `<div class="text-left"><span class="text-gray-500">${k}:</span> ${Array.isArray(v) ? v.join(', ') : v}</div>`
                        ).join('')}
                    </div>
                </div>

                <!-- 본문 -->
                <div class="text-left">
                    <div class="flex items-center justify-between mb-2">
                        <h4 class="text-sm font-medium text-gray-700 text-left">응답 본문</h4>
                        <button onclick="copyToClipboard(this.dataset.content)" data-content="${encodeURIComponent(bodyStr)}"
                                class="text-xs text-blue-600 hover:text-blue-700">
                            복사
                        </button>
                    </div>
                    <pre class="bg-gray-900 text-gray-100 rounded p-3 text-xs font-mono overflow-x-auto max-h-96 text-left whitespace-pre-wrap">${escapeHtml(bodyStr)}</pre>
                </div>
            </div>
        `;
    }

    // 히스토리 서랍 토글
    function toggleHistoryDrawer() {
        const drawer = document.getElementById('history-drawer');
        const overlay = document.getElementById('history-overlay');

        if (drawer.classList.contains('translate-x-full')) {
            drawer.classList.remove('translate-x-full');
            overlay.classList.remove('hidden');

            // 히스토리 로드
            htmx.ajax('GET', '{{ route("dev-tools.api-explorer.history.index") }}', {
                target: '#history-content',
                swap: 'innerHTML'
            });
        } else {
            drawer.classList.add('translate-x-full');
            overlay.classList.add('hidden');
        }
    }

    // 히스토리 삭제
    async function clearHistory() {
        if (!confirm('모든 히스토리를 삭제하시겠습니까?')) return;

        await fetch('{{ route("dev-tools.api-explorer.history.clear") }}', {
            method: 'DELETE',
            headers: {
                'X-CSRF-TOKEN': '{{ csrf_token() }}'
            }
        });

        document.getElementById('history-content').innerHTML =
            '<div class="text-center text-gray-400 py-8">히스토리가 없습니다.</div>';
    }

    // 히스토리에서 요청 로드
    async function loadFromHistory(historyId) {
        try {
            // 1. 히스토리 데이터 가져오기
            const response = await fetch(`/dev-tools/api-explorer/history/${historyId}/replay`, {
                method: 'POST',
                headers: {
                    'X-CSRF-TOKEN': '{{ csrf_token() }}'
                }
            });

            if (!response.ok) {
                showToast('히스토리를 불러올 수 없습니다.', 'error');
                return;
            }

            const historyData = await response.json();

            // 2. 해당 endpoint와 method로 allEndpoints에서 API 찾기
            const matchedEndpoint = allEndpoints.find(ep =>
                ep.path === historyData.endpoint && ep.method === historyData.method
            );

            if (!matchedEndpoint) {
                // API 스펙에서 찾을 수 없는 경우 (삭제된 API 등)
                showToast('해당 API를 찾을 수 없습니다. 스펙이 변경되었을 수 있습니다.', 'error');
                toggleHistoryDrawer();
                return;
            }

            // 3. 해당 엔드포인트 패널 로드 (HTMX)
            const panelUrl = `/dev-tools/api-explorer/endpoints/${matchedEndpoint.operationId}`;

            // 패널 로드 후 데이터 채우기를 위해 pending 데이터 저장
            window.pendingHistoryData = historyData;

            // HTMX로 패널 로드
            htmx.ajax('GET', panelUrl, {
                target: '#request-panel',
                swap: 'innerHTML'
            }).then(() => {
                // 패널 로드 완료 후 데이터 채우기
                setTimeout(() => {
                    fillFormFromHistory(window.pendingHistoryData);
                    window.pendingHistoryData = null;
                }, 100); // DOM 렌더링 대기
            });

            // 4. 사이드바에서 해당 API 활성화
            const endpointItems = document.querySelectorAll('.endpoint-item');
            endpointItems.forEach(item => {
                item.classList.remove('active');
                if (item.dataset.operationId === matchedEndpoint.operationId) {
                    item.classList.add('active');
                }
            });

            // 5. 히스토리 드로어 닫기
            toggleHistoryDrawer();
            showToast('히스토리가 로드되었습니다.');

        } catch (error) {
            console.error('히스토리 로드 오류:', error);
            showToast('히스토리 로드 중 오류가 발생했습니다.', 'error');
        }
    }

    // 히스토리 데이터로 폼 채우기
    function fillFormFromHistory(data) {
        if (!data) return;

        const form = document.querySelector('#request-panel form');
        if (!form) return;

        // Path 파라미터 채우기 (endpoint에서 추출)
        // 예: /api/v1/users/{id} 에서 {id} 부분
        const pathRegex = /\{([^}]+)\}/g;
        const endpoint = data.endpoint;
        let match;
        const pathValues = {};

        // endpoint 패턴과 실제 경로를 비교하여 path 파라미터 값 추출
        const currentEndpointInput = form.querySelector('[name="endpoint"]');
        if (currentEndpointInput) {
            const pattern = currentEndpointInput.value;
            const patternParts = pattern.split('/');
            const endpointParts = endpoint.split('/');

            patternParts.forEach((part, index) => {
                if (part.startsWith('{') && part.endsWith('}')) {
                    const paramName = part.slice(1, -1);
                    if (endpointParts[index]) {
                        pathValues[paramName] = endpointParts[index];
                    }
                }
            });

            // Path 파라미터 입력 필드에 값 채우기
            Object.entries(pathValues).forEach(([key, value]) => {
                const input = form.querySelector(`[name="path_${key}"]`);
                if (input) input.value = value;
            });
        }

        // Request Body 채우기
        if (data.body) {
            const bodyTextarea = form.querySelector('[name="body"]');
            if (bodyTextarea) {
                const bodyContent = typeof data.body === 'string'
                    ? data.body
                    : JSON.stringify(data.body, null, 2);
                bodyTextarea.value = bodyContent;
            }
        }

        // Query 파라미터는 히스토리에 별도 저장되지 않으므로 생략
        // (필요시 endpoint URL에서 파싱하여 채울 수 있음)
    }

    // 즐겨찾기 토글 (새로고침 없이 로컬 상태 업데이트)
    async function toggleBookmark(endpoint, method, button) {
        const response = await fetch('{{ route("dev-tools.api-explorer.bookmarks.toggle") }}', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-CSRF-TOKEN': '{{ csrf_token() }}'
            },
            body: JSON.stringify({ endpoint, method })
        });

        const result = await response.json();
        const key = endpoint + '|' + method;

        if (result.action === 'added') {
            // 즐겨찾기 추가
            if (!bookmarkedEndpoints.includes(key)) {
                bookmarkedEndpoints.push(key);
            }
        } else {
            // 즐겨찾기 제거
            const index = bookmarkedEndpoints.indexOf(key);
            if (index > -1) {
                bookmarkedEndpoints.splice(index, 1);
            }
        }

        // 현재 필터 상태 유지하면서 사이드바 다시 렌더링
        filterEndpoints();
    }

    // 유틸리티

    // JSON 본문 포맷팅 (들여쓰기 적용 + \xXX UTF-8 바이트 디코딩)
    function formatJsonBody(body) {
        if (!body) return '';

        try {
            // 문자열이면 JSON 파싱 시도
            let obj = typeof body === 'string' ? JSON.parse(body) : body;

            // JSON.stringify 전에 객체 내 문자열의 \xXX 시퀀스 디코딩
            obj = decodeHexEscapes(obj);

            // JSON으로 다시 포맷팅 (들여쓰기 포함)
            return JSON.stringify(obj, null, 2);
        } catch (e) {
            // JSON이 아닌 경우 그대로 반환
            return typeof body === 'string' ? body : JSON.stringify(body, null, 2);
        }
    }

    // 객체 내 문자열의 \xXX UTF-8 바이트 시퀀스를 재귀적으로 디코딩
    function decodeHexEscapes(obj) {
        if (typeof obj === 'string') {
            // \xXX 패턴을 UTF-8로 디코딩
            return obj.replace(/((?:\\x[0-9a-fA-F]{2})+)/g, (match) => {
                try {
                    const hexPairs = match.match(/\\x([0-9a-fA-F]{2})/g);
                    if (!hexPairs) return match;
                    const bytes = hexPairs.map(h => parseInt(h.substring(2), 16));
                    return new TextDecoder('utf-8').decode(new Uint8Array(bytes));
                } catch (e) {
                    return match;
                }
            });
        }
        if (Array.isArray(obj)) {
            return obj.map(item => decodeHexEscapes(item));
        }
        if (obj && typeof obj === 'object') {
            const result = {};
            for (const key in obj) {
                result[key] = decodeHexEscapes(obj[key]);
            }
            return result;
        }
        return obj;
    }

    function escapeHtml(text) {
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }

    function copyToClipboard(content) {
        navigator.clipboard.writeText(decodeURIComponent(content)).then(() => {
            showToast('클립보드에 복사되었습니다.');
        });
    }

    // 태그 그룹 토글
    function toggleTagGroup(tagName) {
        const group = document.getElementById(`tag-${tagName}`);
        const chevron = document.getElementById(`chevron-${tagName}`);

        if (group.classList.contains('hidden')) {
            group.classList.remove('hidden');
            chevron.classList.add('rotate-90');
        } else {
            group.classList.add('hidden');
            chevron.classList.remove('rotate-90');
        }
    }

    // 설정 모달 (환경 관리)
    function openSettingsModal() {
        showToast('환경 설정 기능은 Phase 2에서 구현 예정입니다.', 'info');
    }

    // ==========================================
    // AI 분석 / 재전송 함수
    // ==========================================

    // AI 분석용 복사
    function copyForAiAnalysis() {
        if (!lastRequestData || !lastResponseData) {
            showToast('요청/응답 데이터가 없습니다.', 'error');
            return;
        }

        const requestBody = lastRequestData.body
            ? JSON.stringify(lastRequestData.body, null, 2)
            : '(없음)';

        const responseBody = typeof lastResponseData.body === 'object'
            ? JSON.stringify(lastResponseData.body, null, 2)
            : lastResponseData.body || '(없음)';

        const analysisText = `## API 오류 분석 요청

### 요청 정보
- **Method**: ${lastRequestData.method}
- **URL**: ${lastRequestData.url}
- **Environment**: ${lastRequestData.environment}

### 요청 헤더
\`\`\`json
${JSON.stringify(lastRequestData.headers, null, 2)}
\`\`\`

### 요청 본문
\`\`\`json
${requestBody}
\`\`\`

### 응답 정보
- **Status**: ${lastResponseData.status}
- **Duration**: ${lastResponseData.duration_ms}ms

### 응답 헤더
\`\`\`json
${JSON.stringify(lastResponseData.headers, null, 2)}
\`\`\`

### 응답 본문
\`\`\`json
${responseBody}
\`\`\`

---
위 API 요청이 실패했습니다. 원인을 분석하고 해결 방법을 제안해주세요.`;

        navigator.clipboard.writeText(analysisText).then(() => {
            showToast('AI 분석용 내용이 클립보드에 복사되었습니다.\nClaude나 ChatGPT에 붙여넣기 하세요.', 'success');
        }).catch(err => {
            console.error('복사 실패:', err);
            showToast('복사에 실패했습니다.', 'error');
        });
    }

    // 마지막 요청 재전송
    async function retryLastRequest() {
        if (!lastRequestData) {
            showToast('재전송할 요청 데이터가 없습니다.', 'error');
            return;
        }

        // 응답 패널에 로딩 표시
        const content = document.getElementById('response-content');
        content.innerHTML = `
            <div class="flex items-center justify-center py-12">
                <svg class="w-8 h-8 animate-spin text-blue-500" fill="none" viewBox="0 0 24 24">
                    <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
                    <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path>
                </svg>
                <span class="ml-3 text-gray-600">재전송 중...</span>
            </div>
        `;

        try {
            const response = await fetch('{{ route("dev-tools.api-explorer.execute") }}', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-TOKEN': '{{ csrf_token() }}'
                },
                body: JSON.stringify({
                    method: lastRequestData.method,
                    url: lastRequestData.url,
                    headers: lastRequestData.headers,
                    query: lastRequestData.query,
                    body: lastRequestData.body,
                    environment: lastRequestData.environment,
                    ...lastRequestData.authPayload
                })
            });

            const result = await response.json();
            displayResponse(result);

            if (result.status >= 200 && result.status < 400) {
                showToast('재전송 성공!', 'success');
            }

        } catch (error) {
            displayResponse({
                status: 0,
                headers: {},
                body: { error: true, message: error.message },
                duration_ms: 0
            });
        }
    }

    // 토스트 메시지 (타입 지원)
    function showToast(message, type = 'success') {
        const colors = {
            success: 'bg-green-500',
            error: 'bg-red-500',
            info: 'bg-blue-500',
            warning: 'bg-yellow-500'
        };

        const toast = document.createElement('div');
        toast.className = `fixed bottom-4 right-4 ${colors[type] || colors.success} text-white px-4 py-2 rounded-lg shadow-lg z-50 animate-fade-in`;
        toast.textContent = message;
        document.body.appendChild(toast);

        setTimeout(() => {
            toast.remove();
        }, 3000);
    }
</script>
@endpush
