<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>제품 이미지 관리 - yakkok 크롤러</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;500;600;700&display=swap" rel="stylesheet">
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body {
            font-family: 'Noto Sans KR', sans-serif;
            background: linear-gradient(135deg, #0f0f23 0%, #1a1a3e 50%, #2d1b4e 100%);
            min-height: 100vh;
            color: #e0e0e0;
        }
        
        .container {
            max-width: 1400px;
            margin: 0 auto;
            padding: 20px;
        }
        
        header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 24px;
            flex-wrap: wrap;
            gap: 16px;
        }
        
        h1 {
            font-size: 24px;
            background: linear-gradient(135deg, #a855f7, #6366f1);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
        }
        
        .actions {
            display: flex;
            gap: 12px;
            flex-wrap: wrap;
        }
        
        .btn {
            padding: 10px 20px;
            border: none;
            border-radius: 8px;
            font-size: 14px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s;
        }
        
        .btn-primary {
            background: linear-gradient(135deg, #8b5cf6, #6366f1);
            color: white;
        }
        
        .btn-primary:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 15px rgba(139, 92, 246, 0.4);
        }
        
        .btn-secondary {
            background: rgba(255,255,255,0.1);
            color: #e0e0e0;
            border: 1px solid rgba(255,255,255,0.2);
        }
        
        .btn-secondary:hover {
            background: rgba(255,255,255,0.2);
        }
        
        .btn-danger {
            background: linear-gradient(135deg, #ef4444, #dc2626);
            color: white;
        }
        
        .stats-bar {
            display: flex;
            gap: 16px;
            margin-bottom: 24px;
            flex-wrap: wrap;
        }
        
        .stat-card {
            background: rgba(255,255,255,0.05);
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255,255,255,0.1);
            border-radius: 12px;
            padding: 16px 24px;
            min-width: 120px;
        }
        
        .stat-card .value {
            font-size: 28px;
            font-weight: 700;
            color: #a855f7;
        }
        
        .stat-card .label {
            font-size: 12px;
            color: #9ca3af;
            margin-top: 4px;
        }
        
        .stat-card.success .value { color: #10b981; }
        .stat-card.failed .value { color: #ef4444; }
        .stat-card.pending .value { color: #f59e0b; }
        
        .filters {
            display: flex;
            gap: 12px;
            margin-bottom: 20px;
            flex-wrap: wrap;
        }
        
        .search-box {
            flex: 1;
            min-width: 200px;
            padding: 10px 16px;
            background: rgba(255,255,255,0.05);
            border: 1px solid rgba(255,255,255,0.1);
            border-radius: 8px;
            color: white;
            font-size: 14px;
        }
        
        .search-box::placeholder { color: #6b7280; }
        
        .filter-select {
            padding: 10px 16px;
            background: rgba(255,255,255,0.05);
            border: 1px solid rgba(255,255,255,0.1);
            border-radius: 8px;
            color: white;
            font-size: 14px;
        }
        
        .filter-select option { background: #1a1a3e; }
        
        .image-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
            gap: 16px;
        }
        
        .image-card {
            background: rgba(255,255,255,0.05);
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255,255,255,0.1);
            border-radius: 12px;
            overflow: hidden;
            transition: all 0.3s;
        }
        
        .image-card:hover {
            transform: translateY(-4px);
            box-shadow: 0 8px 25px rgba(139, 92, 246, 0.2);
        }
        
        .image-card .thumb {
            width: 100%;
            height: 150px;
            background: rgba(0,0,0,0.3);
            display: flex;
            align-items: center;
            justify-content: center;
            overflow: hidden;
        }
        
        .image-card .thumb img {
            max-width: 100%;
            max-height: 100%;
            object-fit: contain;
        }
        
        .image-card .thumb.no-image {
            color: #6b7280;
            font-size: 12px;
        }
        
        .image-card .info {
            padding: 12px;
        }
        
        .image-card .name {
            font-size: 13px;
            font-weight: 600;
            color: #e0e0e0;
            margin-bottom: 4px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        
        .image-card .barcode {
            font-size: 11px;
            color: #9ca3af;
            font-family: monospace;
        }
        
        .image-card .status {
            display: inline-block;
            padding: 2px 8px;
            border-radius: 4px;
            font-size: 10px;
            font-weight: 600;
            margin-top: 8px;
        }
        
        .status.success { background: rgba(16,185,129,0.2); color: #10b981; }
        .status.failed { background: rgba(239,68,68,0.2); color: #ef4444; }
        .status.pending { background: rgba(245,158,11,0.2); color: #f59e0b; }
        .status.no_result { background: rgba(107,114,128,0.2); color: #9ca3af; }
        .status.manual { background: rgba(59,130,246,0.2); color: #3b82f6; }
        
        .image-card .actions {
            display: flex;
            gap: 8px;
            margin-top: 8px;
        }
        
        .image-card .btn-sm {
            padding: 4px 8px;
            font-size: 11px;
            border-radius: 4px;
        }
        
        .modal {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0,0,0,0.8);
            z-index: 1000;
            align-items: center;
            justify-content: center;
        }
        
        .modal.show { display: flex; }
        
        .modal-content {
            background: #1a1a3e;
            border-radius: 16px;
            padding: 24px;
            max-width: 500px;
            width: 90%;
            max-height: 80vh;
            overflow: auto;
        }
        
        .modal-content h3 {
            margin-bottom: 16px;
            color: #a855f7;
        }
        
        .modal-content img {
            max-width: 100%;
            border-radius: 8px;
            margin-bottom: 16px;
        }
        
        .loading {
            text-align: center;
            padding: 40px;
            color: #9ca3af;
        }
        
        .loading::after {
            content: '';
            display: inline-block;
            width: 20px;
            height: 20px;
            border: 2px solid #a855f7;
            border-top-color: transparent;
            border-radius: 50%;
            animation: spin 1s linear infinite;
            margin-left: 10px;
        }
        
        @keyframes spin {
            to { transform: rotate(360deg); }
        }
        
        .toast {
            position: fixed;
            bottom: 20px;
            right: 20px;
            padding: 12px 24px;
            border-radius: 8px;
            color: white;
            font-weight: 500;
            z-index: 2000;
            animation: slideIn 0.3s ease;
        }
        
        .toast.success { background: linear-gradient(135deg, #10b981, #059669); }
        .toast.error { background: linear-gradient(135deg, #ef4444, #dc2626); }
        .toast.info { background: linear-gradient(135deg, #3b82f6, #2563eb); }
        
        @keyframes slideIn {
            from { transform: translateX(100%); opacity: 0; }
            to { transform: translateX(0); opacity: 1; }
        }
        
        /* 탭 스타일 */
        .tab-btn {
            flex: 1;
            padding: 10px 16px;
            background: rgba(255,255,255,0.05);
            border: 1px solid rgba(255,255,255,0.1);
            border-radius: 8px;
            color: #9ca3af;
            font-size: 14px;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.3s;
        }
        
        .tab-btn:hover {
            background: rgba(255,255,255,0.1);
        }
        
        .tab-btn.active {
            background: linear-gradient(135deg, #8b5cf6, #6366f1);
            color: white;
            border-color: transparent;
        }
        
        .empty-state {
            text-align: center;
            padding: 60px 20px;
            color: #6b7280;
        }
        
        .empty-state .icon {
            font-size: 48px;
            margin-bottom: 16px;
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>🖼️ 제품 이미지 관리</h1>
            <div class="actions">
                <input type="date" id="crawlDate" class="filter-select" style="padding: 8px 12px;">
                <button class="btn btn-primary" onclick="crawlByDate()">
                    🔄 해당일 판매 제품 크롤링
                </button>
                <button class="btn btn-secondary" onclick="openManualCrawl()">
                    ➕ 수동 크롤링
                </button>
                <a href="/admin" class="btn btn-secondary">← 어드민</a>
            </div>
        </header>
        
        <div class="stats-bar" id="statsBar">
            <div class="stat-card">
                <div class="value" id="statTotal">-</div>
                <div class="label">전체</div>
            </div>
            <div class="stat-card success">
                <div class="value" id="statSuccess">-</div>
                <div class="label">성공</div>
            </div>
            <div class="stat-card failed">
                <div class="value" id="statFailed">-</div>
                <div class="label">실패/없음</div>
            </div>
            <div class="stat-card pending">
                <div class="value" id="statPending">-</div>
                <div class="label">대기</div>
            </div>
        </div>
        
        <div class="filters">
            <input type="text" class="search-box" id="searchBox" 
                   placeholder="제품명 또는 바코드 검색..." 
                   onkeyup="debounceSearch()">
            <select class="filter-select" id="statusFilter" onchange="loadImages()">
                <option value="">전체 상태</option>
                <option value="success">성공</option>
                <option value="failed">실패/검색없음</option>
                <option value="pending">대기</option>
                <option value="manual">수동등록</option>
            </select>
        </div>
        
        <div class="image-grid" id="imageGrid">
            <div class="loading">이미지 로딩 중...</div>
        </div>
    </div>
    
    <!-- 수동 크롤링 모달 -->
    <div class="modal" id="manualCrawlModal">
        <div class="modal-content" style="max-width: 600px;">
            <h3>➕ 제품 검색 & 크롤링</h3>
            <p style="color: #9ca3af; margin-bottom: 16px; font-size: 13px;">
                약국 DB에서 제품을 검색하고, 선택하면 yakkok.com에서 이미지를 가져옵니다
            </p>
            
            <!-- 검색 영역 -->
            <div style="display: flex; gap: 8px; margin-bottom: 16px;">
                <input type="text" id="mssqlSearchInput" class="search-box" style="flex: 1;" 
                       placeholder="제품명 검색 (예: 타이레놀, 센스큐탐...)" 
                       onkeypress="if(event.key==='Enter') searchMssqlProducts()">
                <button class="btn btn-primary" onclick="searchMssqlProducts()">검색</button>
            </div>
            
            <!-- 검색 결과 -->
            <div id="mssqlSearchResults" style="max-height: 300px; overflow-y: auto; margin-bottom: 16px;">
                <div style="color: #6b7280; text-align: center; padding: 20px;">
                    제품명을 검색하세요
                </div>
            </div>
            
            <!-- 선택된 제품 -->
            <div id="selectedProduct" style="display: none; background: rgba(139,92,246,0.1); border: 1px solid rgba(139,92,246,0.3); border-radius: 8px; padding: 12px; margin-bottom: 16px;">
                <div style="font-size: 12px; color: #9ca3af; margin-bottom: 4px;">선택된 제품</div>
                <div id="selectedProductName" style="font-weight: 600;"></div>
                <div id="selectedProductBarcode" style="font-size: 12px; color: #a855f7; font-family: monospace;"></div>
            </div>
            
            <div style="text-align: right;">
                <button class="btn btn-secondary" onclick="closeManualCrawl()">취소</button>
                <button class="btn btn-primary" id="crawlSelectedBtn" onclick="crawlSelected()" disabled>🔄 크롤링 시작</button>
            </div>
        </div>
    </div>
    
    <!-- 이미지 교체 모달 (탭 방식: URL / 촬영) -->
    <div class="modal" id="replaceModal">
        <div class="modal-content" style="max-width: 500px;">
            <h3>🔄 이미지 교체</h3>
            <div id="replaceProductInfo" style="background: rgba(139,92,246,0.1); border-radius: 8px; padding: 12px; margin-bottom: 16px;">
                <div style="font-weight: 600;" id="replaceProductName"></div>
                <div style="font-size: 12px; color: #a855f7; font-family: monospace;" id="replaceBarcode"></div>
            </div>
            
            <!-- 탭 버튼 -->
            <div class="replace-tabs" style="display: flex; gap: 8px; margin-bottom: 16px;">
                <button class="tab-btn active" onclick="switchReplaceTab('url')" id="tabBtnUrl">
                    🔗 URL 입력
                </button>
                <button class="tab-btn" onclick="switchReplaceTab('camera')" id="tabBtnCamera">
                    📷 촬영
                </button>
            </div>
            
            <!-- URL 입력 탭 -->
            <div id="tabUrl" class="tab-content">
                <p style="color: #9ca3af; margin-bottom: 8px; font-size: 13px;">
                    구글 이미지 등에서 찾은 URL을 붙여넣으세요
                </p>
                <div style="margin-bottom: 16px;">
                    <label style="display: block; margin-bottom: 4px; font-size: 13px;">이미지 URL *</label>
                    <input type="text" id="replaceImageUrl" class="search-box" style="width: 100%;" 
                           placeholder="https://example.com/image.jpg">
                    <div style="font-size: 11px; color: #6b7280; margin-top: 4px;">
                        💡 이미지 우클릭 → "이미지 주소 복사"로 URL을 가져오세요
                    </div>
                </div>
                <div style="text-align: right;">
                    <button class="btn btn-secondary" onclick="closeReplaceModal()">취소</button>
                    <button class="btn btn-primary" onclick="submitReplace()">교체하기</button>
                </div>
            </div>
            
            <!-- 카메라 촬영 탭 -->
            <div id="tabCamera" class="tab-content" style="display: none;">
                <!-- 카메라 뷰 -->
                <div id="cameraContainer" style="position: relative; width: 100%; aspect-ratio: 1; background: #000; border-radius: 8px; overflow: hidden; margin-bottom: 12px;">
                    <video id="cameraVideo" autoplay playsinline style="width: 100%; height: 100%; object-fit: cover;"></video>
                    <!-- 1:1 가이드 오버레이 -->
                    <div id="cameraGuide" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; pointer-events: none;">
                        <svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="none">
                            <!-- 반투명 외곽 -->
                            <rect x="0" y="0" width="100" height="100" fill="rgba(0,0,0,0.4)"/>
                            <!-- 중앙 투명 영역 -->
                            <rect x="10" y="10" width="80" height="80" fill="transparent" stroke="#a855f7" stroke-width="0.5" stroke-dasharray="2,2"/>
                            <!-- 모서리 강조 -->
                            <path d="M10,20 L10,10 L20,10" fill="none" stroke="#a855f7" stroke-width="1"/>
                            <path d="M80,10 L90,10 L90,20" fill="none" stroke="#a855f7" stroke-width="1"/>
                            <path d="M90,80 L90,90 L80,90" fill="none" stroke="#a855f7" stroke-width="1"/>
                            <path d="M20,90 L10,90 L10,80" fill="none" stroke="#a855f7" stroke-width="1"/>
                        </svg>
                    </div>
                    <!-- 촬영된 이미지 미리보기 -->
                    <canvas id="captureCanvas" style="display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></canvas>
                </div>
                
                <p style="color: #9ca3af; font-size: 12px; text-align: center; margin-bottom: 12px;">
                    📦 제품을 보라색 가이드 안에 맞춰주세요
                </p>
                
                <!-- 버튼들 -->
                <div id="cameraButtons" style="display: flex; gap: 8px; justify-content: center;">
                    <button class="btn btn-secondary" onclick="closeReplaceModal()">취소</button>
                    <button class="btn btn-primary" id="captureBtn" onclick="capturePhoto()">📸 촬영</button>
                </div>
                <div id="previewButtons" style="display: none; gap: 8px; justify-content: center;">
                    <button class="btn btn-secondary" onclick="retakePhoto()">↩️ 다시 촬영</button>
                    <button class="btn btn-primary" onclick="submitCapture()">✅ 저장</button>
                </div>
            </div>
        </div>
    </div>
    
    <!-- 상세 모달 -->
    <div class="modal" id="detailModal">
        <div class="modal-content">
            <h3 id="modalTitle">제품 상세</h3>
            <img id="modalImage" src="" alt="">
            <div id="modalInfo"></div>
            <div style="margin-top: 16px; text-align: right;">
                <button class="btn btn-secondary" onclick="closeModal()">닫기</button>
            </div>
        </div>
    </div>
    
    <script>
        let debounceTimer;
        
        // 초기 로드
        document.addEventListener('DOMContentLoaded', () => {
            // 오늘 날짜로 기본값 설정
            const today = new Date().toISOString().split('T')[0];
            document.getElementById('crawlDate').value = today;
            
            loadStats();
            loadImages();
        });
        
        async function loadStats() {
            try {
                const res = await fetch('/api/admin/product-images/stats');
                const data = await res.json();
                
                if (data.success) {
                    document.getElementById('statTotal').textContent = data.total || 0;
                    document.getElementById('statSuccess').textContent = data.stats.success || 0;
                    document.getElementById('statFailed').textContent = 
                        (data.stats.failed || 0) + (data.stats.no_result || 0);
                    document.getElementById('statPending').textContent = data.stats.pending || 0;
                }
            } catch (err) {
                console.error(err);
            }
        }
        
        async function loadImages() {
            const grid = document.getElementById('imageGrid');
            const search = document.getElementById('searchBox').value;
            const status = document.getElementById('statusFilter').value;
            
            grid.innerHTML = '<div class="loading">이미지 로딩 중...</div>';
            
            try {
                const params = new URLSearchParams();
                if (search) params.append('search', search);
                if (status) params.append('status', status);
                params.append('limit', 100);
                
                const res = await fetch(`/api/admin/product-images?${params}`);
                const data = await res.json();
                
                if (data.success && data.items.length > 0) {
                    grid.innerHTML = data.items.map(item => `
                        <div class="image-card" data-barcode="${item.barcode}">
                            <div class="thumb ${item.thumbnail_base64 ? '' : 'no-image'}">
                                ${item.thumbnail_base64 
                                    ? `<img src="data:image/jpeg;base64,${item.thumbnail_base64}" alt="${item.product_name}">`
                                    : '이미지 없음'}
                            </div>
                            <div class="info">
                                <div class="name" title="${item.product_name}">${item.product_name}</div>
                                <div class="barcode">${item.barcode}</div>
                                <span class="status ${item.status}">${getStatusText(item.status)}</span>
                                <div class="actions">
                                    <button class="btn btn-secondary btn-sm" onclick="viewDetail('${item.barcode}')">상세</button>
                                    <button class="btn btn-primary btn-sm" data-barcode="${item.barcode}" data-name="${item.product_name || ''}" onclick="openReplaceModal(this.dataset.barcode, this.dataset.name)">교체</button>
                                    <button class="btn btn-danger btn-sm" onclick="deleteImage('${item.barcode}')">삭제</button>
                                </div>
                            </div>
                        </div>
                    `).join('');
                } else {
                    grid.innerHTML = `
                        <div class="empty-state" style="grid-column: 1/-1;">
                            <div class="icon">📷</div>
                            <div>등록된 이미지가 없습니다</div>
                            <div style="margin-top: 8px; font-size: 13px;">
                                "오늘 판매 제품 크롤링" 버튼을 눌러 시작하세요
                            </div>
                        </div>
                    `;
                }
            } catch (err) {
                grid.innerHTML = `<div class="empty-state" style="grid-column: 1/-1;">오류: ${err.message}</div>`;
            }
        }
        
        function getStatusText(status) {
            const map = {
                'success': '성공',
                'failed': '실패',
                'pending': '대기',
                'no_result': '검색없음',
                'manual': '수동등록'
            };
            return map[status] || status;
        }
        
        function debounceSearch() {
            clearTimeout(debounceTimer);
            debounceTimer = setTimeout(loadImages, 300);
        }
        
        async function crawlByDate() {
            const dateInput = document.getElementById('crawlDate').value;
            if (!dateInput) {
                showToast('날짜를 선택하세요', 'error');
                return;
            }
            
            const dateStr = dateInput.replace(/-/g, '');
            const displayDate = `${dateStr.slice(4,6)}/${dateStr.slice(6,8)}`;
            
            if (!confirm(`${displayDate} 판매 제품 이미지를 크롤링합니다. 진행할까요?`)) return;
            
            showToast(`${displayDate} 크롤링 시작... 잠시 기다려주세요`, 'info');
            
            try {
                const res = await fetch('/api/admin/product-images/crawl-today', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ date: dateInput })
                });
                const data = await res.json();
                
                if (data.success) {
                    const r = data.result;
                    showToast(`완료! 성공: ${r.success}, 실패: ${r.failed}, 스킵: ${r.skipped}`, 'success');
                    loadStats();
                    loadImages();
                } else {
                    showToast(data.error || '크롤링 실패', 'error');
                }
            } catch (err) {
                showToast('오류: ' + err.message, 'error');
            }
        }
        
        async function viewDetail(barcode) {
            try {
                const res = await fetch(`/api/admin/product-images/${barcode}`);
                const data = await res.json();
                
                if (data.success) {
                    const img = data.image;
                    document.getElementById('modalTitle').textContent = img.product_name;
                    document.getElementById('modalImage').src = img.image_base64 
                        ? `data:image/jpeg;base64,${img.image_base64}` 
                        : '';
                    document.getElementById('modalImage').style.display = img.image_base64 ? 'block' : 'none';
                    document.getElementById('modalInfo').innerHTML = `
                        <p><strong>바코드:</strong> ${img.barcode}</p>
                        <p><strong>DrugCode:</strong> ${img.drug_code || '-'}</p>
                        <p><strong>검색어:</strong> ${img.search_name || '-'}</p>
                        <p><strong>상태:</strong> ${getStatusText(img.status)}</p>
                        <p><strong>원본 URL:</strong> <a href="${img.image_url}" target="_blank" style="color:#a855f7;">${img.image_url || '-'}</a></p>
                        <p><strong>등록일:</strong> ${img.created_at}</p>
                        ${img.error_message ? `<p><strong>에러:</strong> ${img.error_message}</p>` : ''}
                    `;
                    document.getElementById('detailModal').classList.add('show');
                }
            } catch (err) {
                showToast('상세 조회 실패', 'error');
            }
        }
        
        function closeModal() {
            document.getElementById('detailModal').classList.remove('show');
        }
        
        async function deleteImage(barcode) {
            if (!confirm('이 이미지를 삭제할까요?')) return;
            
            try {
                const res = await fetch(`/api/admin/product-images/${barcode}`, {
                    method: 'DELETE'
                });
                const data = await res.json();
                
                if (data.success) {
                    showToast('삭제 완료', 'success');
                    loadStats();
                    loadImages();
                } else {
                    showToast(data.error || '삭제 실패', 'error');
                }
            } catch (err) {
                showToast('오류: ' + err.message, 'error');
            }
        }
        
        function showToast(message, type = 'info') {
            const toast = document.createElement('div');
            toast.className = `toast ${type}`;
            toast.textContent = message;
            document.body.appendChild(toast);
            
            setTimeout(() => toast.remove(), 4000);
        }
        
        // 수동 크롤링
        let selectedProductData = null;
        
        function openManualCrawl() {
            selectedProductData = null;
            document.getElementById('mssqlSearchInput').value = '';
            document.getElementById('mssqlSearchResults').innerHTML = '<div style="color: #6b7280; text-align: center; padding: 20px;">제품명을 검색하세요</div>';
            document.getElementById('selectedProduct').style.display = 'none';
            document.getElementById('crawlSelectedBtn').disabled = true;
            document.getElementById('manualCrawlModal').classList.add('show');
            document.getElementById('mssqlSearchInput').focus();
        }
        
        function closeManualCrawl() {
            document.getElementById('manualCrawlModal').classList.remove('show');
        }
        
        async function searchMssqlProducts() {
            const query = document.getElementById('mssqlSearchInput').value.trim();
            if (!query) {
                showToast('검색어를 입력하세요', 'error');
                return;
            }
            
            const resultsDiv = document.getElementById('mssqlSearchResults');
            resultsDiv.innerHTML = '<div style="color: #9ca3af; text-align: center; padding: 20px;">검색 중...</div>';
            
            try {
                // OTC 라벨 검색 API 재사용
                const res = await fetch(`/api/admin/otc-labels/search-mssql?q=${encodeURIComponent(query)}`);
                const data = await res.json();
                
                if (data.success && data.drugs.length > 0) {
                    resultsDiv.innerHTML = data.drugs.map(drug => `
                        <div class="search-result-item" onclick="selectProduct('${drug.barcode}', '${drug.drug_code}', '${escapeHtml(drug.goods_name)}')"
                             style="padding: 12px; border-bottom: 1px solid rgba(255,255,255,0.1); cursor: pointer; transition: background 0.2s;"
                             onmouseover="this.style.background='rgba(139,92,246,0.1)'" 
                             onmouseout="this.style.background='transparent'">
                            <div style="font-weight: 500;">${drug.goods_name}</div>
                            <div style="font-size: 12px; color: #9ca3af;">
                                <span style="color: #a855f7; font-family: monospace;">${drug.barcode || '바코드없음'}</span>
                                ${drug.sale_price ? ` · ₩${Math.floor(drug.sale_price).toLocaleString()}` : ''}
                            </div>
                        </div>
                    `).join('');
                } else {
                    resultsDiv.innerHTML = '<div style="color: #6b7280; text-align: center; padding: 20px;">검색 결과가 없습니다</div>';
                }
            } catch (err) {
                resultsDiv.innerHTML = `<div style="color: #ef4444; text-align: center; padding: 20px;">오류: ${err.message}</div>`;
            }
        }
        
        function selectProduct(barcode, drugCode, productName) {
            if (!barcode) {
                showToast('바코드가 없는 제품은 크롤링할 수 없습니다', 'error');
                return;
            }
            
            selectedProductData = { barcode, drugCode, productName };
            document.getElementById('selectedProductName').textContent = productName;
            document.getElementById('selectedProductBarcode').textContent = barcode;
            document.getElementById('selectedProduct').style.display = 'block';
            document.getElementById('crawlSelectedBtn').disabled = false;
        }
        
        function escapeHtml(str) {
            if (!str) return '';
            return str.replace(/'/g, "\\'").replace(/"/g, '&quot;');
        }
        
        async function crawlSelected() {
            if (!selectedProductData) {
                showToast('제품을 선택하세요', 'error');
                return;
            }
            
            const { barcode, drugCode, productName } = selectedProductData;
            
            closeManualCrawl();
            showToast(`"${productName}" 크롤링 시작...`, 'info');
            
            try {
                const res = await fetch('/api/admin/product-images/crawl', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        products: [[barcode, drugCode || null, productName]]
                    })
                });
                const data = await res.json();
                
                if (data.success) {
                    const r = data.result;
                    if (r.success > 0) {
                        showToast(`✅ "${productName}" 이미지 수집 성공!`, 'success');
                    } else if (r.skipped > 0) {
                        showToast(`이미 등록된 바코드입니다`, 'info');
                    } else {
                        showToast(`❌ 이미지를 찾지 못했습니다`, 'error');
                    }
                    loadStats();
                    loadImages();
                } else {
                    showToast(data.error || '크롤링 실패', 'error');
                }
            } catch (err) {
                showToast('오류: ' + err.message, 'error');
            }
        }
        
        // 이미지 교체
        let replaceTargetBarcode = null;
        let replaceTargetName = null;
        let cameraStream = null;
        let capturedImageData = null;
        
        function openReplaceModal(barcode, productName) {
            console.log('openReplaceModal called with:', barcode, productName);
            
            if (!barcode || barcode === 'null' || barcode === 'undefined') {
                showToast('바코드 정보가 없습니다', 'error');
                return;
            }
            
            replaceTargetBarcode = barcode;
            replaceTargetName = productName || barcode;
            document.getElementById('replaceProductName').textContent = replaceTargetName;
            document.getElementById('replaceBarcode').textContent = barcode;
            document.getElementById('replaceImageUrl').value = '';
            
            // 탭 초기화 (URL 탭으로)
            switchReplaceTab('url');
            
            document.getElementById('replaceModal').classList.add('show');
            document.getElementById('replaceImageUrl').focus();
        }
        
        function closeReplaceModal() {
            stopCamera();
            document.getElementById('replaceModal').classList.remove('show');
            replaceTargetBarcode = null;
            replaceTargetName = null;
            capturedImageData = null;
        }
        
        function switchReplaceTab(tab) {
            // 탭 버튼 활성화
            document.getElementById('tabBtnUrl').classList.toggle('active', tab === 'url');
            document.getElementById('tabBtnCamera').classList.toggle('active', tab === 'camera');
            
            // 탭 콘텐츠 표시
            document.getElementById('tabUrl').style.display = tab === 'url' ? 'block' : 'none';
            document.getElementById('tabCamera').style.display = tab === 'camera' ? 'block' : 'none';
            
            // 카메라 탭이면 카메라 시작
            if (tab === 'camera') {
                startCamera();
            } else {
                stopCamera();
            }
        }
        
        async function startCamera() {
            try {
                // 이전 스트림 정리
                stopCamera();
                
                // 후면 카메라 우선 (모바일)
                const constraints = {
                    video: {
                        facingMode: { ideal: 'environment' },  // 후면 카메라
                        width: { ideal: 1920 },
                        height: { ideal: 1920 }
                    },
                    audio: false
                };
                
                cameraStream = await navigator.mediaDevices.getUserMedia(constraints);
                const video = document.getElementById('cameraVideo');
                video.srcObject = cameraStream;
                video.style.display = 'block';
                
                // 캡처 상태 초기화
                document.getElementById('captureCanvas').style.display = 'none';
                document.getElementById('cameraGuide').style.display = 'block';
                document.getElementById('cameraButtons').style.display = 'flex';
                document.getElementById('previewButtons').style.display = 'none';
                capturedImageData = null;
                
            } catch (err) {
                console.error('카메라 접근 오류:', err);
                showToast('카메라에 접근할 수 없습니다: ' + err.message, 'error');
            }
        }
        
        function stopCamera() {
            if (cameraStream) {
                cameraStream.getTracks().forEach(track => track.stop());
                cameraStream = null;
            }
            const video = document.getElementById('cameraVideo');
            video.srcObject = null;
        }
        
        function capturePhoto() {
            const video = document.getElementById('cameraVideo');
            const canvas = document.getElementById('captureCanvas');
            const ctx = canvas.getContext('2d');
            
            // 비디오 크기
            const vw = video.videoWidth;
            const vh = video.videoHeight;
            
            // 1:1 영역 계산 (가이드 박스: 80% 영역)
            const minDim = Math.min(vw, vh);
            const cropSize = minDim * 0.8;
            const sx = (vw - cropSize) / 2;
            const sy = (vh - cropSize) / 2;
            
            // 캔버스를 800x800으로 설정 (최종 해상도)
            canvas.width = 800;
            canvas.height = 800;
            
            // 크롭하여 그리기
            ctx.drawImage(video, sx, sy, cropSize, cropSize, 0, 0, 800, 800);
            
            // base64 저장
            capturedImageData = canvas.toDataURL('image/jpeg', 0.92);
            
            // UI 전환 (미리보기 모드)
            video.style.display = 'none';
            canvas.style.display = 'block';
            document.getElementById('cameraGuide').style.display = 'none';
            document.getElementById('cameraButtons').style.display = 'none';
            document.getElementById('previewButtons').style.display = 'flex';
            
            // 카메라 스트림은 유지 (다시 촬영 위해)
        }
        
        function retakePhoto() {
            const video = document.getElementById('cameraVideo');
            const canvas = document.getElementById('captureCanvas');
            
            // UI 전환 (카메라 모드)
            video.style.display = 'block';
            canvas.style.display = 'none';
            document.getElementById('cameraGuide').style.display = 'block';
            document.getElementById('cameraButtons').style.display = 'flex';
            document.getElementById('previewButtons').style.display = 'none';
            capturedImageData = null;
        }
        
        async function submitCapture() {
            if (!capturedImageData) {
                showToast('촬영된 이미지가 없습니다', 'error');
                return;
            }
            
            if (!replaceTargetBarcode) {
                showToast('바코드 정보가 없습니다', 'error');
                return;
            }
            
            // 모달 닫기 전에 값 복사 (closeReplaceModal에서 null로 리셋되므로)
            const barcode = replaceTargetBarcode;
            const productName = replaceTargetName;
            const imageData = capturedImageData;
            
            closeReplaceModal();
            showToast(`"${productName}" 이미지 저장 중...`, 'info');
            
            try {
                const res = await fetch(`/api/admin/product-images/${barcode}/upload`, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ 
                        image_data: imageData,
                        product_name: productName
                    })
                });
                const data = await res.json();
                
                if (data.success) {
                    showToast('✅ 촬영 이미지 저장 완료!', 'success');
                    loadStats();
                    loadImages();
                } else {
                    showToast(data.error || '저장 실패', 'error');
                }
            } catch (err) {
                showToast('오류: ' + err.message, 'error');
            }
        }
        
        async function submitReplace() {
            const imageUrl = document.getElementById('replaceImageUrl').value.trim();
            
            if (!imageUrl) {
                showToast('이미지 URL을 입력하세요', 'error');
                return;
            }
            
            if (!imageUrl.startsWith('http')) {
                showToast('올바른 URL을 입력하세요 (http:// 또는 https://)', 'error');
                return;
            }
            
            // 바코드 검증
            if (!replaceTargetBarcode || replaceTargetBarcode === 'null' || replaceTargetBarcode === 'undefined') {
                showToast('바코드 정보가 없습니다. 다시 시도해주세요.', 'error');
                return;
            }
            
            const barcode = replaceTargetBarcode;
            closeReplaceModal();
            showToast(`"${barcode}" 이미지 다운로드 중...`, 'info');
            
            try {
                const res = await fetch(`/api/admin/product-images/${barcode}/replace`, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ image_url: imageUrl })
                });
                const data = await res.json();
                
                if (data.success) {
                    showToast('✅ 이미지 교체 완료!', 'success');
                    loadStats();
                    loadImages();
                } else {
                    showToast(data.error || '교체 실패', 'error');
                }
            } catch (err) {
                showToast('오류: ' + err.message, 'error');
            }
        }
        
        // ESC로 모달 닫기
        document.addEventListener('keydown', (e) => {
            if (e.key === 'Escape') {
                closeModal();
                closeManualCrawl();
                closeReplaceModal();
            }
        });
        
        // 모달 외부 클릭으로 닫기
        document.getElementById('detailModal').addEventListener('click', (e) => {
            if (e.target.id === 'detailModal') closeModal();
        });
        
        document.getElementById('manualCrawlModal').addEventListener('click', (e) => {
            if (e.target.id === 'manualCrawlModal') closeManualCrawl();
        });
        
        document.getElementById('replaceModal').addEventListener('click', (e) => {
            if (e.target.id === 'replaceModal') closeReplaceModal();
        });
    </script>
</body>
</html>
