/**
 * LinkManager 모듈
 * 문서 링크 및 백링크 통합 관리
 */
class LinkManager {
    constructor(api) {
        console.log('🔗 LinkManager 초기화 시작');
        this.api = api;
        // 캐싱된 API 사용 (사용 가능한 경우)
        this.cachedApi = window.cachedApi || api;
        this.documentLinks = [];
        this.backlinks = [];
        
        // 안전한 초기화 확인
        console.log('🔧 LinkManager 초기화 - backlinks 타입:', typeof this.backlinks, Array.isArray(this.backlinks));
        this.selectedText = '';
        this.selectedRange = null;
        this.availableBooks = [];
        this.filteredDocuments = [];
        
        console.log('✅ LinkManager 초기화 완료');
    }

    /**
     * 문서/노트 링크 데이터 로드
     */
    async loadDocumentLinks(documentId, contentType = 'document') {
        try {
            console.log('🔍 loadDocumentLinks 호출됨 - documentId:', documentId, 'contentType:', contentType);
            
            let apiEndpoint;
            if (contentType === 'note') {
                // 노트 문서의 경우 노트 전용 링크 API 사용
                apiEndpoint = `/note-documents/${documentId}/links`;
                console.log('✅ 노트 API 엔드포인트 선택:', apiEndpoint);
            } else {
                // 일반 문서의 경우 기존 API 사용
                apiEndpoint = `/documents/${documentId}/links`;
                console.log('✅ 문서 API 엔드포인트 선택:', apiEndpoint);
            }
            
            console.log('📡 링크 API 호출:', apiEndpoint);
            console.log('📡 사용 중인 documentId:', documentId, 'contentType:', contentType);
            console.log('📡 cachedApi 객체:', this.cachedApi);
            
            const response = await this.cachedApi.get(apiEndpoint, {}, { category: 'links' });
            console.log('📡 원본 API 응답:', response);
            console.log('📡 응답 타입:', typeof response);
            console.log('📡 응답이 배열인가?', Array.isArray(response));
            console.log('📡 응답 JSON 문자열:', JSON.stringify(response, null, 2));
            console.log('📡 응답 키들:', Object.keys(response || {}));
            
            // API 응답이 객체일 경우 처리
            if (Array.isArray(response)) {
                this.documentLinks = response;
            } else if (response && typeof response === 'object') {
                // 객체에서 배열 추출 시도
                if (response.data && Array.isArray(response.data)) {
                    this.documentLinks = response.data;
                } else if (response.links && Array.isArray(response.links)) {
                    this.documentLinks = response.links;
                } else {
                    console.warn('⚠️ 예상치 못한 API 응답 구조:', response);
                    this.documentLinks = [];
                }
            } else {
                this.documentLinks = [];
            }
            
            // target_content_type이 없는 링크들에 대해 추론 로직 적용
            this.documentLinks = this.documentLinks.map(link => {
                if (!link.target_content_type) {
                    if (link.target_note_id) {
                        link.target_content_type = 'note';
                        console.log('🔍 링크 타입 추론: note -', link.id);
                    } else if (link.target_document_id) {
                        link.target_content_type = 'document';
                        console.log('🔍 링크 타입 추론: document -', link.id);
                    }
                }
                return link;
            });
            
            console.log('📡 최종 링크 데이터 (타입 추론 완료):', this.documentLinks);
            console.log('📡 최종 링크 개수:', this.documentLinks.length);
            return this.documentLinks;
        } catch (error) {
            console.error('❌ 문서 링크 로드 실패:', error);
            this.documentLinks = [];
            return [];
        }
    }

    /**
     * 백링크 데이터 로드
     */
    async loadBacklinks(documentId, contentType = 'document') {
        try {
            console.log('🔍 loadBacklinks 호출됨 - documentId:', documentId, 'contentType:', contentType);
            
            let apiEndpoint;
            if (contentType === 'note') {
                // 노트 문서의 경우 노트 전용 백링크 API 사용
                apiEndpoint = `/note-documents/${documentId}/backlinks`;
                console.log('✅ 노트 백링크 API 엔드포인트 선택:', apiEndpoint);
            } else {
                // 일반 문서의 경우 기존 API 사용
                apiEndpoint = `/documents/${documentId}/backlinks`;
                console.log('✅ 문서 백링크 API 엔드포인트 선택:', apiEndpoint);
            }
            
            console.log('📡 백링크 API 호출:', apiEndpoint);
            console.log('📡 사용 중인 documentId:', documentId, 'contentType:', contentType);
            
            const response = await this.cachedApi.get(apiEndpoint, {}, { category: 'links' });
            console.log('📡 원본 백링크 응답:', response);
            console.log('📡 백링크 응답 타입:', typeof response);
            console.log('📡 백링크 응답이 배열인가?', Array.isArray(response));
            console.log('📡 백링크 응답 JSON 문자열:', JSON.stringify(response, null, 2));
            console.log('📡 백링크 응답 키들:', Object.keys(response || {}));
            
            // API 응답이 객체일 경우 처리
            if (Array.isArray(response)) {
                this.backlinks = response;
            } else if (response && typeof response === 'object') {
                // 객체에서 배열 추출 시도
                if (response.data && Array.isArray(response.data)) {
                    this.backlinks = response.data;
                } else if (response.backlinks && Array.isArray(response.backlinks)) {
                    this.backlinks = response.backlinks;
                } else {
                    console.warn('⚠️ 예상치 못한 백링크 API 응답 구조:', response);
                    this.backlinks = [];
                }
            } else {
                this.backlinks = [];
            }
            
            console.log('📡 최종 백링크 데이터:', this.backlinks);
            console.log('📡 최종 백링크 개수:', this.backlinks.length);
            return this.backlinks;
        } catch (error) {
            console.error('❌ 백링크 로드 실패:', error);
            this.backlinks = [];
            return [];
        }
    }

    /**
     * 문서 링크 렌더링
     */
    renderDocumentLinks() {
        const documentContent = document.getElementById('document-content');
        if (!documentContent) {
            console.error('❌ document-content 요소를 찾을 수 없습니다');
            return;
        }

        // 안전한 링크 초기화
        if (!Array.isArray(this.documentLinks)) {
            console.warn('⚠️ this.documentLinks가 배열이 아닙니다. 빈 배열로 초기화합니다.');
            console.log('🔍 기존 this.documentLinks:', typeof this.documentLinks, this.documentLinks);
            this.documentLinks = [];
        }

        console.log('🔗 링크 렌더링 시작 - 총', this.documentLinks.length, '개');
        console.log('🔗 링크 데이터 상세:', this.documentLinks);
        
        // 기존 링크 제거 (항상 실행)
        const existingLinks = documentContent.querySelectorAll('.document-link');
        console.log('🔍 기존 링크 제거:', existingLinks.length, '개');
        existingLinks.forEach(el => {
            const parent = el.parentNode;
            parent.replaceChild(document.createTextNode(el.textContent), el);
            parent.normalize();
        });
        
        // 링크 데이터가 없으면 여기서 종료
        if (this.documentLinks.length === 0) {
            console.log('📝 링크 데이터가 없습니다.');
            return;
        }

        // 각 링크 렌더링
        if (Array.isArray(this.documentLinks)) {
            this.documentLinks.forEach(link => {
                this.renderSingleLink(link);
            });
        } else {
            console.warn('⚠️ this.documentLinks가 배열이 아닙니다:', typeof this.documentLinks, this.documentLinks);
        }

        console.log('✅ 링크 렌더링 완료');
    }

    /**
     * 개별 링크 렌더링
     */
    renderSingleLink(link) {
        console.log('🔗 renderSingleLink 시작:', link.id, link.selected_text);
        const content = document.getElementById('document-content');
        const textContent = content.textContent;
        
        console.log('📝 문서 텍스트 길이:', textContent.length);
        console.log('📍 링크 위치:', link.start_offset, '-', link.end_offset);
        console.log('📝 예상 텍스트:', textContent.substring(link.start_offset, link.end_offset));
        
        if (link.start_offset >= textContent.length || link.end_offset > textContent.length) {
            console.warn('❌ 링크 위치가 텍스트 범위를 벗어남:', link);
            console.log('📝 텍스트 미리보기:', textContent.substring(0, 200));
            console.log('📝 링크 주변 텍스트:', textContent.substring(Math.max(0, link.start_offset - 50), link.start_offset + 50));
            return;
        }
        
        // 실제 텍스트와 선택된 텍스트가 일치하는지 확인
        const actualText = textContent.substring(link.start_offset, link.end_offset);
        if (actualText !== link.selected_text) {
            console.warn('⚠️ 오프셋 위치의 텍스트가 선택된 텍스트와 다름');
            console.log('📍 예상:', link.selected_text);
            console.log('📍 실제:', actualText);
            
            // 텍스트 검색으로 대체 시도
            const searchIndex = textContent.indexOf(link.selected_text);
            if (searchIndex !== -1) {
                console.log('✅ 텍스트 검색으로 위치 찾음:', searchIndex);
                link.start_offset = searchIndex;
                link.end_offset = searchIndex + link.selected_text.length;
            } else {
                console.error('❌ 링크 텍스트를 찾을 수 없음:', link.selected_text);
                return;
            }
        }

        const walker = document.createTreeWalker(
            content,
            NodeFilter.SHOW_TEXT,
            null,
            false
        );

        let currentOffset = 0;
        let node;
        
        while (node = walker.nextNode()) {
            const nodeLength = node.textContent.length;
            const nodeStart = currentOffset;
            const nodeEnd = currentOffset + nodeLength;
            
            // 링크 범위와 겹치는지 확인
            if (nodeEnd > link.start_offset && nodeStart < link.end_offset) {
                const linkStart = Math.max(0, link.start_offset - nodeStart);
                const linkEnd = Math.min(nodeLength, link.end_offset - nodeStart);
                
                if (linkStart < linkEnd) {
                    console.log('✅ 링크 적용:', linkStart, '-', linkEnd, '텍스트:', node.textContent.substring(linkStart, linkEnd));
                    this.applyLinkToNode(node, linkStart, linkEnd, link);
                    break;
                }
            }
            
            currentOffset = nodeEnd;
        }
    }

    /**
     * 텍스트 노드에 링크 적용
     */
    applyLinkToNode(textNode, start, end, link) {
        console.log('🎨 applyLinkToNode 시작:', start, end, link.id);
        const text = textNode.textContent;
        const beforeText = text.substring(0, start);
        const linkText = text.substring(start, end);
        const afterText = text.substring(end);
        
        console.log('📝 링크 텍스트:', linkText);
        
        // 링크 스팬 생성
        const span = document.createElement('span');
        span.className = 'document-link';
        span.textContent = linkText;
        span.dataset.linkId = link.id;
        
        // 링크 스타일 (보라색) - 레이아웃 안전
        span.style.cssText = `
            color: #7C3AED !important;
            text-decoration: underline !important;
            cursor: pointer !important;
            background-color: rgba(124, 58, 237, 0.1) !important;
            border-radius: 2px !important;
            padding: 0 1px !important;
            display: inline !important;
            line-height: inherit !important;
            vertical-align: baseline !important;
            margin: 0 !important;
            box-sizing: border-box !important;
        `;
        
        // 클릭 이벤트 추가 (통합 툴팁 사용)
        span.addEventListener('click', async (e) => {
            e.preventDefault();
            e.stopPropagation();
            
            console.log('🔗 링크 클릭됨:', {
                text: span.textContent,
                linkId: link.id,
                classList: Array.from(span.classList)
            });
            
            // 링크, 백링크, 하이라이트 모두 찾기
            const overlappingElements = window.documentViewerInstance.getOverlappingElements(span);
            const totalElements = overlappingElements.links.length + overlappingElements.backlinks.length + overlappingElements.highlights.length;
            
            console.log('🎯 링크 클릭 분석:', {
                links: overlappingElements.links.length,
                backlinks: overlappingElements.backlinks.length,
                highlights: overlappingElements.highlights.length,
                total: totalElements,
                selectedText: overlappingElements.selectedText
            });
            
            if (totalElements > 1) {
                // 통합 툴팁 표시 (링크 + 백링크 + 하이라이트)
                console.log('🎨 통합 툴팁 표시 시작 (링크에서)');
                await window.documentViewerInstance.showUnifiedTooltip(overlappingElements, span);
            } else {
                // 단일 링크 툴팁
                console.log('🔗 단일 링크 툴팁 표시');
                this.showLinkTooltip(link, span);
            }
        });
        
        // DOM 교체
        const parent = textNode.parentNode;
        const fragment = document.createDocumentFragment();
        
        if (beforeText) fragment.appendChild(document.createTextNode(beforeText));
        fragment.appendChild(span);
        if (afterText) fragment.appendChild(document.createTextNode(afterText));
        
        parent.replaceChild(fragment, textNode);
        console.log('✅ 링크 DOM 교체 완료:', linkText);
    }

    /**
     * 백링크 렌더링 (링크와 동일한 방식)
     */
    renderBacklinks() {
        const documentContent = document.getElementById('document-content');
        if (!documentContent) {
            console.error('❌ document-content 요소를 찾을 수 없습니다');
            return;
        }

        // 안전한 백링크 초기화
        if (!Array.isArray(this.backlinks)) {
            console.warn('⚠️ this.backlinks가 배열이 아닙니다. 빈 배열로 초기화합니다.');
            console.log('🔍 기존 this.backlinks:', typeof this.backlinks, this.backlinks);
            this.backlinks = [];
        }

        console.log('🔗 백링크 렌더링 시작 - 총', this.backlinks.length, '개');
        console.log('🔗 백링크 데이터 상세:', this.backlinks);
        
        // 기존 백링크 확인 (제거하지 않고 중복 체크만)
        const existingBacklinks = documentContent.querySelectorAll('.backlink-highlight');
        console.log(`🔍 기존 백링크 ${existingBacklinks.length}개 발견`);
        
        // 백링크 데이터가 없으면 여기서 종료
        if (this.backlinks.length === 0) {
            console.log('📝 백링크 데이터가 없습니다.');
            return;
        }

        // 각 백링크 렌더링 (중복되지 않는 것만)
        if (Array.isArray(this.backlinks)) {
            this.backlinks.forEach(backlink => {
                // 이미 렌더링된 백링크인지 확인
                const existingBacklink = Array.from(existingBacklinks).find(el => 
                    el.dataset.backlinkId === backlink.id.toString()
                );
                
                if (!existingBacklink) {
                    console.log(`🆕 새로운 백링크 렌더링: ${backlink.id}`);
                    this.renderSingleBacklink(backlink);
                } else {
                    console.log(`✅ 백링크 이미 존재: ${backlink.id}`);
                }
            });
        } else {
            console.warn('⚠️ this.backlinks가 배열이 아닙니다:', typeof this.backlinks, this.backlinks);
        }

        console.log('✅ 백링크 렌더링 완료');
    }

    /**
     * 개별 백링크 렌더링
     */
    renderSingleBacklink(backlink) {
        console.log('🔗 renderSingleBacklink 시작:', backlink.id, backlink.target_text);
        const content = document.getElementById('document-content');
        if (!content) {
            console.error('❌ document-content 요소를 찾을 수 없습니다');
            return;
        }
        
        // 원본 문서 내용 사용 (오프셋 정확성을 위해)
        const textContent = content.textContent || content.innerText || '';
        console.log('📝 문서 텍스트 길이:', textContent.length);
        
        // target_start_offset과 target_end_offset이 있으면 직접 사용
        let textIndex, searchText, searchLength;
        
        if (backlink.target_start_offset !== undefined && backlink.target_end_offset !== undefined) {
            // 오프셋 정보가 있으면 직접 사용 (더 정확함)
            textIndex = backlink.target_start_offset;
            searchLength = backlink.target_end_offset - backlink.target_start_offset;
            searchText = textContent.substring(textIndex, textIndex + searchLength);
            console.log('✅ 오프셋으로 백링크 텍스트 찾음:', searchText, '위치:', textIndex);
        } else {
            // 오프셋 정보가 없으면 텍스트 검색 사용
            searchText = backlink.target_text || backlink.selected_text;
            if (!searchText) {
                console.warn('❌ 백링크 텍스트 정보가 없음:', backlink);
                return;
            }
            
            // 텍스트 검색 (대소문자 무시, 공백 정규화)
            const normalizedContent = textContent.replace(/\s+/g, ' ').trim();
            const normalizedSearchText = searchText.replace(/\s+/g, ' ').trim();
            
            textIndex = normalizedContent.indexOf(normalizedSearchText);
            if (textIndex === -1) {
                // 부분 검색 시도
                const words = normalizedSearchText.split(' ');
                if (words.length > 1) {
                    const firstWord = words[0];
                    const lastWord = words[words.length - 1];
                    const partialPattern = firstWord + '.*' + lastWord;
                    const regex = new RegExp(partialPattern, 'i');
                    const match = normalizedContent.match(regex);
                    if (match) {
                        textIndex = match.index;
                        console.log('✅ 부분 매칭으로 백링크 텍스트 찾음:', searchText);
                    }
                }
            }
            
            if (textIndex === -1) {
                console.warn('❌ 백링크 텍스트를 찾을 수 없음:', searchText);
                console.log('📝 검색 대상 텍스트 미리보기:', normalizedContent.substring(0, 200));
                console.log('📝 전체 텍스트 길이:', normalizedContent.length);
                return;
            }
            
            searchLength = searchText.length;
            console.log('✅ 텍스트 검색으로 백링크 텍스트 찾음:', searchText, '위치:', textIndex);
        }

        const walker = document.createTreeWalker(
            content,
            NodeFilter.SHOW_TEXT,
            null,
            false
        );

        let currentOffset = 0;
        let node;
        
        while (node = walker.nextNode()) {
            const nodeLength = node.textContent.length;
            const nodeStart = currentOffset;
            const nodeEnd = currentOffset + nodeLength;
            
            // 백링크 범위와 겹치는지 확인
            if (nodeEnd > textIndex && nodeStart < textIndex + searchLength) {
                const backlinkStart = Math.max(0, textIndex - nodeStart);
                const backlinkEnd = Math.min(nodeLength, textIndex + searchLength - nodeStart);
                
                if (backlinkStart < backlinkEnd) {
                    console.log('✅ 백링크 적용:', backlinkStart, '-', backlinkEnd, '텍스트:', node.textContent.substring(backlinkStart, backlinkEnd));
                    this.applyBacklinkToNode(node, backlinkStart, backlinkEnd, backlink);
                    break;
                }
            }
            
            currentOffset = nodeEnd;
        }
    }

    /**
     * 텍스트 노드에 백링크 적용
     */
    applyBacklinkToNode(textNode, start, end, backlink) {
        console.log('🎨 applyBacklinkToNode 시작:', start, end, backlink.id);
        const text = textNode.textContent;
        const beforeText = text.substring(0, start);
        const backlinkText = text.substring(start, end);
        const afterText = text.substring(end);
        
        console.log('📝 백링크 텍스트:', backlinkText);
        
        // 백링크 스팬 생성
        const span = document.createElement('span');
        span.className = 'backlink-highlight';
        span.textContent = backlinkText;
        span.dataset.backlinkId = backlink.id;
        
        // 백링크 스타일 (주황색) - 레이아웃 안전
        span.style.cssText = `
            color: #EA580C !important;
            text-decoration: underline !important;
            cursor: pointer !important;
            background-color: rgba(234, 88, 12, 0.2) !important;
            border: 1px solid #EA580C !important;
            border-radius: 3px !important;
            padding: 0 2px !important;
            font-weight: bold !important;
            display: inline !important;
            line-height: inherit !important;
            vertical-align: baseline !important;
            margin: 0 !important;
            box-sizing: border-box !important;
        `;
        
        // 클릭 이벤트 추가 (통합 툴팁 사용)
        span.addEventListener('click', async (e) => {
            e.preventDefault();
            e.stopPropagation();
            
            console.log('🔙 백링크 클릭됨:', {
                text: span.textContent,
                backlinkId: backlink.id,
                classList: Array.from(span.classList)
            });
            
            // 링크, 백링크, 하이라이트 모두 찾기
            const overlappingElements = window.documentViewerInstance.getOverlappingElements(span);
            const totalElements = overlappingElements.links.length + overlappingElements.backlinks.length + overlappingElements.highlights.length;
            
            console.log('🔙 백링크 클릭 분석:', {
                links: overlappingElements.links.length,
                backlinks: overlappingElements.backlinks.length,
                highlights: overlappingElements.highlights.length,
                total: totalElements,
                selectedText: overlappingElements.selectedText
            });
            
            if (totalElements > 1) {
                // 통합 툴팁 표시 (링크 + 백링크 + 하이라이트)
                console.log('🎯 통합 툴팁 표시 시작 (백링크에서)');
                await window.documentViewerInstance.showUnifiedTooltip(overlappingElements, span);
            } else {
                // 단일 백링크 툴팁
                console.log('🔙 단일 백링크 툴팁 표시');
                this.showBacklinkTooltip(backlink, span);
            }
        });
        
        // DOM 교체
        const parent = textNode.parentNode;
        const fragment = document.createDocumentFragment();
        
        if (beforeText) fragment.appendChild(document.createTextNode(beforeText));
        fragment.appendChild(span);
        if (afterText) fragment.appendChild(document.createTextNode(afterText));
        
        parent.replaceChild(fragment, textNode);
        console.log('✅ 백링크 DOM 교체 완료:', backlinkText);
    }

    /**
     * 겹치는 링크들 찾기
     */
    getOverlappingLinks(clickedElement) {
        const clickedLinkId = clickedElement.getAttribute('data-link-id');
        const clickedText = clickedElement.textContent;
        
        console.log('🔍 겹치는 링크 찾기:', {
            clickedLinkId: clickedLinkId,
            clickedText: clickedText,
            totalLinks: this.documentLinks.length
        });
        
        // 동일한 텍스트 범위에 있는 모든 링크 찾기
        const overlappingLinks = this.documentLinks.filter(link => {
            // 클릭된 링크와 텍스트가 겹치는지 확인
            const linkElement = document.querySelector(`[data-link-id="${link.id}"]`);
            if (!linkElement) return false;
            
            // 텍스트가 겹치는지 확인 (간단한 방법: 텍스트 내용 비교)
            const isOverlapping = linkElement.textContent === clickedText;
            
            if (isOverlapping) {
                console.log('✅ 겹치는 링크 발견:', {
                    id: link.id,
                    text: linkElement.textContent,
                    target: link.target_document_title
                });
            }
            
            return isOverlapping;
        });
        
        console.log(`🔍 총 ${overlappingLinks.length}개의 겹치는 링크 발견`);
        return overlappingLinks;
    }

    /**
     * 다중 링크 툴팁 표시
     */
    showMultiLinkTooltip(links, element, selectedText) {
        console.log('🔗 다중 링크 툴팁 표시:', links.length, '개');
        
        // 기존 툴팁 제거
        this.hideTooltip();
        
        const tooltip = document.createElement('div');
        tooltip.id = 'link-tooltip';
        tooltip.className = 'absolute bg-white border border-gray-300 rounded-lg shadow-lg p-4 z-50 max-w-lg';
        tooltip.style.minWidth = '400px';
        tooltip.style.maxHeight = '80vh';
        tooltip.style.overflowY = 'auto';
        
        let tooltipHTML = `
            <div class="mb-4">
                <div class="text-sm text-gray-600 mb-2">선택된 텍스트</div>
                <div class="font-medium text-gray-900 bg-gray-100 px-3 py-2 rounded border-l-4 border-purple-500">
                    "${selectedText}"
                </div>
            </div>
        `;
        
        if (links.length > 1) {
            tooltipHTML += `
                <div class="mb-4">
                    <div class="text-sm font-medium text-gray-700 mb-2 flex items-center">
                        <svg class="w-4 h-4 mr-2 text-purple-600" fill="currentColor" viewBox="0 0 20 20">
                            <path fill-rule="evenodd" d="M12.586 4.586a2 2 0 112.828 2.828l-3 3a2 2 0 01-2.828 0 1 1 0 00-1.414 1.414 4 4 0 005.656 0l3-3a4 4 0 00-5.656-5.656l-1.5 1.5a1 1 0 101.414 1.414l1.5-1.5zm-5 5a2 2 0 012.828 0 1 1 0 101.414-1.414 4 4 0 00-5.656 0l-3 3a4 4 0 105.656 5.656l1.5-1.5a1 1 0 10-1.414-1.414l-1.5 1.5a2 2 0 11-2.828-2.828l3-3z" clip-rule="evenodd"></path>
                        </svg>
                        연결된 링크 (${links.length}개)
                    </div>
                </div>
            `;
        }
        
        tooltipHTML += '<div class="space-y-3">';
        
        links.forEach((link, index) => {
            const createdDate = link.created_at ? this.formatDate(link.created_at) : '알 수 없음';
            const isNote = link.target_content_type === 'note';
            const iconClass = isNote ? 'text-green-600' : 'text-purple-600';
            const bgClass = isNote ? 'hover:bg-green-50' : 'hover:bg-purple-50';
            
            tooltipHTML += `
                <div class="border rounded-lg p-3 ${bgClass} transition-colors duration-200 relative group">
                    <div class="flex items-start justify-between">
                        <div class="flex-1 cursor-pointer" onclick="window.documentViewerInstance.navigateToLink(${JSON.stringify(link).replace(/"/g, '&quot;')})">
                            <div class="flex items-center mb-2">
                                <svg class="w-4 h-4 mr-2 ${iconClass}" fill="currentColor" viewBox="0 0 20 20">
                                    ${isNote ? 
                                        '<path d="M9 2a1 1 0 000 2h2a1 1 0 100-2H9z"></path><path fill-rule="evenodd" d="M4 5a2 2 0 012-2v1a1 1 0 102 0V3a2 2 0 012 0v1a1 1 0 102 0V3a2 2 0 012 2v6.586A2 2 0 0115.414 13L13 15.586A2 2 0 0111.586 16H6a2 2 0 01-2-2V5zm8 4a1 1 0 10-2 0v2a1 1 0 102 0V9z" clip-rule="evenodd"></path>' :
                                        '<path fill-rule="evenodd" d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 6a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1zm1 3a1 1 0 100 2h6a1 1 0 100-2H7z" clip-rule="evenodd"></path>'
                                    }
                                </svg>
                                <span class="font-medium ${iconClass}">${link.target_document_title}</span>
                            </div>
                            
                            <!-- 연결된 텍스트 정보 -->
                            ${link.target_text ? `
                                <div class="mb-2 p-2 bg-gray-50 rounded border-l-3 ${isNote ? 'border-green-400' : 'border-purple-400'}">
                                    <div class="text-xs ${isNote ? 'text-green-700' : 'text-purple-700'} mb-1">연결된 텍스트</div>
                                    <div class="text-sm text-gray-800 font-medium">"${link.target_text}"</div>
                                </div>
                            ` : ''}
                            
                            ${link.description ? `
                                <div class="mb-2 p-2 bg-blue-50 rounded border-l-3 border-blue-400">
                                    <div class="text-xs text-blue-700 mb-1">링크 설명</div>
                                    <div class="text-sm text-blue-800">${link.description}</div>
                                </div>
                            ` : ''}
                            
                            <div class="text-xs text-gray-500 flex items-center justify-between">
                                <span class="flex items-center">
                                    <svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 20 20">
                                        <path fill-rule="evenodd" d="M12.586 4.586a2 2 0 112.828 2.828l-3 3a2 2 0 01-2.828 0 1 1 0 00-1.414 1.414 4 4 0 005.656 0l3-3a4 4 0 00-5.656-5.656l-1.5 1.5a1 1 0 101.414 1.414l1.5-1.5zm-5 5a2 2 0 012.828 0 1 1 0 101.414-1.414 4 4 0 00-5.656 0l-3 3a4 4 0 105.656 5.656l1.5-1.5a1 1 0 10-1.414-1.414l-1.5 1.5a2 2 0 11-2.828-2.828l3-3z" clip-rule="evenodd"></path>
                                    </svg>
                                    ${link.link_type === 'text_fragment' ? '텍스트 조각 링크' : '문서 링크'}
                                </span>
                                <span>${createdDate}</span>
                            </div>
                        </div>
                        
                        <!-- 삭제 버튼 -->
                        <button onclick="event.stopPropagation(); window.documentViewerInstance.deleteLinkWithConfirm('${link.id}', '${link.target_document_title.replace(/'/g, "\\'")}');" 
                                class="ml-3 p-1 text-gray-400 hover:text-red-600 hover:bg-red-50 rounded transition-colors duration-200 opacity-0 group-hover:opacity-100"
                                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="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
                            </svg>
                        </button>
                    </div>
                </div>
            `;
        });
        
        tooltipHTML += '</div>';
        
        tooltip.innerHTML = tooltipHTML;
        
        // 위치 계산 및 표시
        const rect = element.getBoundingClientRect();
        tooltip.style.top = (rect.bottom + window.scrollY + 10) + 'px';
        tooltip.style.left = Math.max(10, rect.left + window.scrollX - 200) + 'px';
        
        document.body.appendChild(tooltip);
        
        // 외부 클릭 시 툴팁 숨기기
        setTimeout(() => {
            document.addEventListener('click', this.handleTooltipOutsideClick.bind(this));
        }, 100);
    }

    /**
     * 링크 툴팁 표시 (단일 링크용)
     */
    showLinkTooltip(link, element) {
        this.hideTooltip();
        
        const tooltip = document.createElement('div');
        tooltip.id = 'link-tooltip';
        tooltip.className = 'absolute bg-white border border-gray-300 rounded-lg shadow-lg p-5 z-50 max-w-2xl';
        tooltip.style.minWidth = '450px';
        tooltip.style.maxHeight = '80vh';
        tooltip.style.overflowY = 'auto';
        
        // 생성 날짜 포맷팅
        const createdDate = link.created_at ? this.formatDate(link.created_at) : '알 수 없음';
        
        const tooltipHTML = `
            <div class="mb-4">
                <div class="flex items-center justify-between mb-3">
                    <div class="text-lg font-semibold text-purple-800 flex items-center">
                        <svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20">
                            <path fill-rule="evenodd" d="M12.586 4.586a2 2 0 112.828 2.828l-3 3a2 2 0 01-2.828 0 1 1 0 00-1.414 1.414 4 4 0 005.656 0l3-3a4 4 0 00-5.656-5.656l-1.5 1.5a1 1 0 101.414 1.414l1.5-1.5zm-5 5a2 2 0 012.828 0 1 1 0 101.414-1.414 4 4 0 00-5.656 0l-3 3a4 4 0 105.656 5.656l1.5-1.5a1 1 0 10-1.414-1.414l-1.5 1.5a2 2 0 11-2.828-2.828l3-3z" clip-rule="evenodd"></path>
                        </svg>
                        링크 정보
                    </div>
                    <div class="text-xs text-gray-500">${createdDate}</div>
                </div>
                
                <div class="font-medium text-purple-900 bg-purple-50 px-4 py-3 rounded-lg border-l-4 border-purple-500">
                    <div class="text-sm text-purple-700 mb-1">선택된 텍스트</div>
                    <div class="text-base">"${link.selected_text}"</div>
                </div>
            </div>
            
            <div class="mb-5">
                <div class="text-sm font-medium text-gray-700 mb-3 flex items-center">
                    <svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20">
                        <path d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
                    </svg>
                    연결된 문서
                </div>
                <div class="bg-gradient-to-r from-gray-50 to-gray-100 p-4 rounded-lg border">
                    <div class="font-semibold text-gray-900 mb-2">${link.target_document_title}</div>
                    ${link.target_text ? `
                        <div class="bg-white p-3 rounded border-l-3 border-blue-400">
                            <div class="text-xs text-gray-600 mb-1">대상 텍스트</div>
                            <div class="text-sm text-gray-800">"${link.target_text}"</div>
                        </div>
                    ` : ''}
                    ${link.description ? `
                        <div class="mt-3 p-3 bg-blue-50 rounded border-l-3 border-blue-300">
                            <div class="text-xs text-blue-700 mb-1">설명</div>
                            <div class="text-sm text-blue-800">${link.description}</div>
                        </div>
                    ` : ''}
                </div>
            </div>
            
            <div class="flex flex-col sm:flex-row gap-3 mb-4">
                <button onclick="window.documentViewerInstance.linkManager.navigateToLinkedDocument('${link.target_note_id || link.target_document_id}', ${JSON.stringify(link).replace(/"/g, '&quot;')})" 
                        class="flex-1 bg-purple-500 text-white px-4 py-2 rounded-lg hover:bg-purple-600 transition-colors flex items-center justify-center">
                    <svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20">
                        <path fill-rule="evenodd" d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z" clip-rule="evenodd"></path>
                    </svg>
                    문서로 이동
                </button>
                <button onclick="window.documentViewerInstance.linkManager.deleteLink('${link.id}')" 
                        class="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition-colors flex items-center justify-center">
                    <svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20">
                        <path fill-rule="evenodd" d="M9 2a1 1 0 000 2h2a1 1 0 100-2H9z" clip-rule="evenodd"></path>
                        <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414L7.586 12l-1.293 1.293a1 1 0 101.414 1.414L9 13.414l2.293 2.293a1 1 0 001.414-1.414L11.414 12l1.293-1.293z" clip-rule="evenodd"></path>
                    </svg>
                    삭제
                </button>
            </div>
            
            <div class="flex justify-end pt-3 border-t border-gray-200">
                <button onclick="window.documentViewerInstance.linkManager.hideTooltip()" 
                        class="text-sm bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition-colors">
                    닫기
                </button>
            </div>
        `;
        
        tooltip.innerHTML = tooltipHTML;
        this.positionTooltip(tooltip, element);
    }

    /**
     * 백링크 툴팁 표시
     */
    showBacklinkTooltip(backlink, element) {
        this.hideTooltip();
        
        const tooltip = document.createElement('div');
        tooltip.id = 'backlink-tooltip';
        tooltip.className = 'absolute bg-white border border-gray-300 rounded-lg shadow-lg p-5 z-50 max-w-2xl';
        tooltip.style.minWidth = '450px';
        tooltip.style.maxHeight = '80vh';
        tooltip.style.overflowY = 'auto';
        
        // 생성 날짜 포맷팅
        const createdDate = backlink.created_at ? this.formatDate(backlink.created_at) : '알 수 없음';
        
        const tooltipHTML = `
            <div class="mb-4">
                <div class="flex items-center justify-between mb-3">
                    <div class="text-lg font-semibold text-orange-800 flex items-center">
                        <svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20">
                            <path fill-rule="evenodd" d="M7.707 3.293a1 1 0 010 1.414L5.414 7H11a7 7 0 017 7v2a1 1 0 11-2 0v-2a5 5 0 00-5-5H5.414l2.293 2.293a1 1 0 11-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd"></path>
                        </svg>
                        백링크 정보
                    </div>
                    <div class="text-xs text-gray-500">${createdDate}</div>
                </div>
                
                <!-- 백링크 설명 -->
                <div class="mb-4 p-3 bg-blue-50 rounded-lg border-l-4 border-blue-400">
                    <div class="text-sm text-blue-800">
                        <strong>💡 백링크란?</strong><br>
                        다른 문서에서 현재 문서의 이 텍스트를 참조하는 연결입니다.<br>
                        클릭하면 참조하는 문서로 이동할 수 있습니다.
                    </div>
                </div>
                
                <!-- 현재 문서의 참조된 텍스트 (강화된 정보) -->
                <div class="mb-4">
                    <div class="font-medium text-orange-900 bg-orange-50 px-4 py-3 rounded-lg border-l-4 border-orange-500">
                        <div class="text-sm text-orange-700 mb-1">현재 문서의 참조된 텍스트</div>
                        <div class="text-base font-semibold">"${backlink.target_text || backlink.selected_text}"</div>
                    </div>
                    
                    ${backlink.target_text && backlink.target_text !== backlink.selected_text ? `
                        <div class="mt-2 p-3 bg-gray-50 rounded-lg border-l-4 border-gray-400">
                            <div class="text-xs text-gray-600 mb-1">원본 링크에서 선택한 텍스트</div>
                            <div class="text-sm text-gray-800">"${backlink.selected_text}"</div>
                        </div>
                    ` : ''}
                </div>
            </div>
            
            <div class="mb-5">
                <div class="text-sm font-medium text-gray-700 mb-3 flex items-center">
                    <svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20">
                        <path d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
                    </svg>
                    이 텍스트를 참조하는 문서
                </div>
                <div class="bg-gradient-to-r from-orange-50 to-orange-100 p-4 rounded-lg border">
                    <div class="cursor-pointer" onclick="window.documentViewerInstance.navigateToBacklink(${JSON.stringify(backlink).replace(/"/g, '&quot;')})">
                        <div class="font-semibold text-gray-900 mb-3 flex items-center">
                            <svg class="w-4 h-4 mr-2 text-orange-600" fill="currentColor" viewBox="0 0 20 20">
                                <path fill-rule="evenodd" d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 6a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1zm1 3a1 1 0 100 2h6a1 1 0 100-2H7z" clip-rule="evenodd"></path>
                            </svg>
                            ${backlink.source_document_title}
                        </div>
                        
                        <!-- 원본 링크 정보 (강화된 표시) -->
                        <div class="space-y-3">
                            <div class="bg-white p-3 rounded border-l-3 border-orange-400">
                                <div class="text-xs text-gray-600 mb-1">원본 문서에서 링크로 설정한 텍스트</div>
                                <div class="text-sm text-gray-800 font-medium">"${backlink.selected_text}"</div>
                            </div>
                            
                            ${backlink.target_text ? `
                                <div class="bg-white p-3 rounded border-l-3 border-blue-400">
                                    <div class="text-xs text-blue-600 mb-1">현재 문서에서 연결된 구체적인 텍스트</div>
                                    <div class="text-sm text-blue-800 font-medium">"${backlink.target_text}"</div>
                                </div>
                            ` : ''}
                            
                            ${backlink.description ? `
                                <div class="bg-white p-3 rounded border-l-3 border-green-400">
                                    <div class="text-xs text-green-600 mb-1">링크 설명</div>
                                    <div class="text-sm text-green-800">${backlink.description}</div>
                                </div>
                            ` : ''}
                        </div>
                    </div>
                </div>
            </div>
            
            <div class="flex justify-center mb-4">
                <button onclick="window.documentViewerInstance.linkManager.navigateToSourceDocument('${backlink.source_document_id}', ${JSON.stringify(backlink).replace(/"/g, '&quot;')})" 
                        class="bg-gradient-to-r from-orange-500 to-orange-600 text-white px-6 py-2 rounded-lg hover:from-orange-600 hover:to-orange-700 transition-all duration-200 flex items-center justify-center font-medium shadow-md hover:shadow-lg">
                    <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-2M7 7l10 10M17 7v4h-4"></path>
                    </svg>
                    원본 문서로 이동
                </button>
            </div>
            
            <div class="flex justify-end pt-3 border-t border-gray-200">
                <button onclick="window.documentViewerInstance.linkManager.hideTooltip()" 
                        class="text-sm bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition-colors">
                    닫기
                </button>
            </div>
        `;
        
        tooltip.innerHTML = tooltipHTML;
        this.positionTooltip(tooltip, element);
    }

    /**
     * 날짜 포맷팅
     */
    formatDate(dateString) {
        if (!dateString) return '알 수 없음';
        
        const date = new Date(dateString);
        const now = new Date();
        const diffTime = Math.abs(now - date);
        const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
        
        if (diffDays === 1) {
            return '오늘';
        } else if (diffDays <= 7) {
            return `${diffDays}일 전`;
        } else if (diffDays <= 30) {
            return `${Math.ceil(diffDays / 7)}주 전`;
        } else {
            return date.toLocaleDateString('ko-KR', { 
                year: 'numeric', 
                month: 'short', 
                day: 'numeric' 
            });
        }
    }

    /**
     * 툴팁 위치 설정
     */
    positionTooltip(tooltip, element) {
        const rect = element.getBoundingClientRect();
        const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
        const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
        
        document.body.appendChild(tooltip);
        
        // 툴팁 위치 조정
        const tooltipRect = tooltip.getBoundingClientRect();
        let top = rect.bottom + scrollTop + 5;
        let left = rect.left + scrollLeft;
        
        // 화면 경계 체크
        if (left + tooltipRect.width > window.innerWidth) {
            left = window.innerWidth - tooltipRect.width - 10;
        }
        if (top + tooltipRect.height > window.innerHeight + scrollTop) {
            top = rect.top + scrollTop - tooltipRect.height - 5;
        }
        
        tooltip.style.top = top + 'px';
        tooltip.style.left = left + 'px';
        
        // 외부 클릭 시 닫기
        setTimeout(() => {
            document.addEventListener('click', this.handleTooltipOutsideClick.bind(this));
        }, 100);
    }

    /**
     * 툴팁 숨기기
     */
    hideTooltip() {
        const linkTooltip = document.getElementById('link-tooltip');
        if (linkTooltip) {
            linkTooltip.remove();
        }
        
        const backlinkTooltip = document.getElementById('backlink-tooltip');
        if (backlinkTooltip) {
            backlinkTooltip.remove();
        }
        
        const overlapMenu = document.getElementById('overlap-menu');
        if (overlapMenu) {
            overlapMenu.remove();
        }
        
        document.removeEventListener('click', this.handleTooltipOutsideClick.bind(this));
    }

    /**
     * 툴팁 외부 클릭 처리
     */
    handleTooltipOutsideClick(e) {
        const linkTooltip = document.getElementById('link-tooltip');
        const backlinkTooltip = document.getElementById('backlink-tooltip');
        const overlapMenu = document.getElementById('overlap-menu');
        
        const isOutsideLinkTooltip = linkTooltip && !linkTooltip.contains(e.target);
        const isOutsideBacklinkTooltip = backlinkTooltip && !backlinkTooltip.contains(e.target);
        const isOutsideOverlapMenu = overlapMenu && !overlapMenu.contains(e.target);
        
        if (isOutsideLinkTooltip || isOutsideBacklinkTooltip || isOutsideOverlapMenu) {
            this.hideTooltip();
        }
    }

    /**
     * 링크된 문서로 이동
     */
    navigateToLinkedDocument(targetDocumentId, linkInfo) {
        console.log('🔗 navigateToLinkedDocument 호출됨');
        console.log('📋 전달받은 파라미터:', {
            targetDocumentId: targetDocumentId,
            linkInfo: linkInfo
        });
        
        // targetDocumentId가 null이거나 'null' 문자열인 경우 처리
        if (!targetDocumentId || targetDocumentId === 'null' || targetDocumentId === null) {
            console.error('❌ targetDocumentId가 유효하지 않습니다:', targetDocumentId);
            console.log('🔍 linkInfo에서 대체 ID 찾기:', linkInfo);
            
            // linkInfo에서 대체 ID 찾기 (노트 링크의 경우 target_note_id 우선)
            if (linkInfo && linkInfo.target_note_id && linkInfo.target_note_id !== 'null') {
                targetDocumentId = linkInfo.target_note_id;
                console.log('✅ linkInfo에서 target_note_id 발견:', targetDocumentId);
            } else if (linkInfo && linkInfo.target_document_id && linkInfo.target_document_id !== 'null') {
                targetDocumentId = linkInfo.target_document_id;
                console.log('✅ linkInfo에서 target_document_id 발견:', targetDocumentId);
            } else {
                alert('대상 문서 ID가 유효하지 않습니다.');
                return;
            }
        }
        
        // contentType에 따라 적절한 URL 생성
        let targetUrl;
        
        if (linkInfo.target_content_type === 'note') {
            // 노트 문서로 이동
            targetUrl = `/viewer.html?id=${targetDocumentId}&contentType=note`;
            console.log('📝 노트 문서로 이동:', targetDocumentId);
        } else {
            // 일반 문서로 이동
            targetUrl = `/viewer.html?id=${targetDocumentId}`;
            console.log('📄 일반 문서로 이동:', targetDocumentId);
        }
        
        // 특정 텍스트 위치가 있는 경우 URL에 추가
        if (linkInfo.target_text && linkInfo.target_start_offset !== undefined) {
            targetUrl += `&highlight_text=${encodeURIComponent(linkInfo.target_text)}`;
            targetUrl += `&start_offset=${linkInfo.target_start_offset}`;
            targetUrl += `&end_offset=${linkInfo.target_end_offset}`;
            console.log('🎯 텍스트 하이라이트 추가:', linkInfo.target_text);
        }
        
        console.log('🚀 최종 이동할 URL:', targetUrl);
        window.location.href = targetUrl;
    }

    /**
     * 원본 문서로 이동 (백링크)
     */
    navigateToSourceDocument(sourceDocumentId, backlinkInfo) {
        console.log('🔙 navigateToSourceDocument 호출됨');
        console.log('📋 전달받은 파라미터:', {
            sourceDocumentId: sourceDocumentId,
            backlinkInfo: backlinkInfo
        });
        
        if (!sourceDocumentId) {
            console.error('❌ sourceDocumentId가 없습니다!');
            alert('소스 문서 ID가 없습니다.');
            return;
        }
        
        // source_content_type에 따라 적절한 URL 생성
        let targetUrl;
        
        // source_content_type이 없으면 ID로 추론
        let sourceContentType = backlinkInfo.source_content_type;
        if (!sourceContentType) {
            if (backlinkInfo.source_note_id) {
                sourceContentType = 'note';
            } else if (backlinkInfo.source_document_id) {
                sourceContentType = 'document';
            }
            console.log('🔍 백링크에서 source_content_type 추론됨:', sourceContentType);
        }
        
        if (sourceContentType === 'note') {
            // 노트 문서로 이동
            targetUrl = `/viewer.html?id=${sourceDocumentId}&contentType=note`;
            console.log('📝 노트 문서로 이동 (백링크):', sourceDocumentId);
        } else {
            // 일반 문서로 이동
            targetUrl = `/viewer.html?id=${sourceDocumentId}`;
            console.log('📄 일반 문서로 이동 (백링크):', sourceDocumentId);
        }
        
        // 원본 텍스트 위치가 있는 경우 URL에 추가
        if (backlinkInfo.selected_text && backlinkInfo.start_offset !== undefined) {
            targetUrl += `&highlight_text=${encodeURIComponent(backlinkInfo.selected_text)}`;
            targetUrl += `&start_offset=${backlinkInfo.start_offset}`;
            targetUrl += `&end_offset=${backlinkInfo.end_offset}`;
            console.log('🎯 텍스트 하이라이트 추가 (백링크):', backlinkInfo.selected_text);
        }
        
        console.log('🚀 최종 이동할 URL (백링크):', targetUrl);
        window.location.href = targetUrl;
    }

    /**
     * 링크 삭제
     */
    async deleteLink(linkId) {
        if (!confirm('이 링크를 삭제하시겠습니까?')) {
            return;
        }
        
        try {
            // 링크 타입 확인 (노트 링크인지 문서 링크인지)
            const link = this.documentLinks.find(l => l.id === linkId);
            
            if (link && link.source_note_id) {
                // 노트 링크 삭제
                console.log('📝 노트 링크 삭제 API 호출');
                await this.api.delete(`/note-links/${linkId}`);
            } else {
                // 문서 링크 삭제
                console.log('📄 문서 링크 삭제 API 호출');
                await this.api.delete(`/document-links/${linkId}`);
            }
            
            this.documentLinks = this.documentLinks.filter(l => l.id !== linkId);
            
            this.hideTooltip();
            this.renderDocumentLinks();
            
            console.log('링크 삭제 완료:', linkId);
        } catch (error) {
            console.error('링크 삭제 실패:', error);
            alert('링크 삭제에 실패했습니다');
        }
    }

    /**
     * 선택된 텍스트로 링크 생성
     */
    async createLinkFromSelection(documentId = null, selectedText = null, selectedRange = null) {
        // 매개변수가 없으면 현재 선택된 텍스트 사용
        if (!selectedText || !selectedRange) {
            selectedText = window.getSelection().toString().trim();
            const selection = window.getSelection();
            
            if (!selectedText || selection.rangeCount === 0) {
                alert('텍스트를 먼저 선택해주세요.');
                return;
            }
            
            selectedRange = selection.getRangeAt(0);
        }
        
        if (!documentId && window.documentViewerInstance) {
            documentId = window.documentViewerInstance.documentId;
        }

        try {
            console.log('🔗 링크 생성 시작:', selectedText);
            
            // ViewerCore의 링크 생성 모달 표시
            if (window.documentViewerInstance) {
                window.documentViewerInstance.selectedText = selectedText;
                window.documentViewerInstance.selectedRange = selectedRange;
                window.documentViewerInstance.showLinkModal = true;
                window.documentViewerInstance.linkForm.selected_text = selectedText;
                
                // 서적 목록 로드
                await window.documentViewerInstance.loadAvailableBooks();
                
                // 기본적으로 같은 서적 문서들 로드
                await window.documentViewerInstance.loadSameBookDocuments();
                
                // 텍스트 오프셋 계산
                const documentContent = document.getElementById('document-content');
                const fullText = documentContent.textContent;
                const startOffset = this.getTextOffset(documentContent, selectedRange.startContainer, selectedRange.startOffset);
                const endOffset = startOffset + selectedText.length;
                
                window.documentViewerInstance.linkForm.start_offset = startOffset;
                window.documentViewerInstance.linkForm.end_offset = endOffset;
            }
            
        } catch (error) {
            console.error('링크 생성 실패:', error);
            alert('링크 생성에 실패했습니다: ' + error.message);
        }
    }



    /**
     * 겹치는 요소 찾기 (하이라이트, 링크, 백링크)
     */
    findOverlappingElements(element) {
        const overlapping = [];
        const rect = element.getBoundingClientRect();
        
        // 같은 위치에 있는 모든 요소 찾기
        const elementsAtPoint = document.elementsFromPoint(
            rect.left + rect.width / 2, 
            rect.top + rect.height / 2
        );
        
        elementsAtPoint.forEach(el => {
            if (el !== element) {
                // 하이라이트 요소
                if (el.classList.contains('highlight')) {
                    overlapping.push({ type: 'highlight', element: el });
                }
                // 링크 요소
                if (el.classList.contains('document-link')) {
                    overlapping.push({ type: 'link', element: el });
                }
                // 백링크 요소
                if (el.classList.contains('backlink-highlight')) {
                    overlapping.push({ type: 'backlink', element: el });
                }
            }
        });
        
        return overlapping;
    }

    /**
     * 겹침 메뉴 표시
     */
    showOverlapMenu(event, clickedElement, overlappingElements, clickedType) {
        this.hideTooltip();
        
        const menu = document.createElement('div');
        menu.id = 'overlap-menu';
        menu.className = 'absolute bg-white border border-gray-300 rounded-lg shadow-lg p-4 z-50';
        menu.style.minWidth = '320px';
        menu.style.maxWidth = '400px';
        
        let menuHTML = `
            <div class="text-sm font-medium text-gray-700 mb-3 flex items-center">
                <svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20">
                    <path fill-rule="evenodd" d="M3 4a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm0 4a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm0 4a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z" clip-rule="evenodd"></path>
                </svg>
                겹치는 요소들
            </div>
            <div class="space-y-2">
        `;
        
        // 클릭된 요소 추가
        menuHTML += this.getMenuItemHTML(clickedType, clickedElement, true);
        
        // 겹치는 요소들 추가
        overlappingElements.forEach(item => {
            menuHTML += this.getMenuItemHTML(item.type, item.element, false);
        });
        
        menuHTML += `
            </div>
            <div class="mt-2 pt-2 border-t border-gray-200">
                <button onclick="window.documentViewerInstance.linkManager.hideTooltip()" 
                        class="text-xs bg-gray-500 text-white px-2 py-1 rounded hover:bg-gray-600 w-full">
                    닫기
                </button>
            </div>
        `;
        
        menu.innerHTML = menuHTML;
        
        // 메뉴 위치 설정
        const rect = clickedElement.getBoundingClientRect();
        const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
        const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
        
        document.body.appendChild(menu);
        
        let top = rect.bottom + scrollTop + 5;
        let left = rect.left + scrollLeft;
        
        // 화면 경계 체크
        const menuRect = menu.getBoundingClientRect();
        if (left + menuRect.width > window.innerWidth) {
            left = window.innerWidth - menuRect.width - 10;
        }
        if (top + menuRect.height > window.innerHeight + scrollTop) {
            top = rect.top + scrollTop - menuRect.height - 5;
        }
        
        menu.style.top = top + 'px';
        menu.style.left = left + 'px';
        
        // 외부 클릭 시 닫기
        setTimeout(() => {
            document.addEventListener('click', this.handleTooltipOutsideClick.bind(this));
        }, 100);
    }

    /**
     * 메뉴 아이템 HTML 생성
     */
    getMenuItemHTML(type, element, isClicked) {
        const icons = {
            highlight: '🖍️',
            link: '🔗',
            backlink: '🔙'
        };
        
        const labels = {
            highlight: '하이라이트',
            link: '링크',
            backlink: '백링크'
        };
        
        const colors = {
            highlight: 'bg-yellow-50 border-yellow-200 text-yellow-800',
            link: 'bg-purple-50 border-purple-200 text-purple-800',
            backlink: 'bg-orange-50 border-orange-200 text-orange-800'
        };
        
        const clickedClass = isClicked ? 'ring-2 ring-blue-300' : '';
        const elementId = element.dataset.highlightId || element.dataset.linkId || element.dataset.backlinkId || '';
        

        
        // 각 타입별 액션 버튼들
        let actionButtons = '';
        if (type === 'highlight') {
            actionButtons = `
                <div class="flex gap-1 mt-2">
                    <button onclick="window.documentViewerInstance.linkManager.handleOverlapMenuClick('${type}', '${elementId}')" 
                            class="text-xs bg-yellow-500 text-white px-2 py-1 rounded hover:bg-yellow-600 transition-colors">
                        메모 보기
                    </button>
                </div>
            `;
        } else if (type === 'link') {
            actionButtons = `
                <div class="flex gap-1 mt-2">
                    <button onclick="window.documentViewerInstance.linkManager.navigateToLinkedDocumentFromMenu('${elementId}')" 
                            class="text-xs bg-purple-500 text-white px-2 py-1 rounded hover:bg-purple-600 transition-colors">
                        문서로 이동
                    </button>
                    <button onclick="window.documentViewerInstance.linkManager.handleOverlapMenuClick('${type}', '${elementId}')" 
                            class="text-xs bg-gray-500 text-white px-2 py-1 rounded hover:bg-gray-600 transition-colors">
                        상세보기
                    </button>
                </div>
            `;
        } else if (type === 'backlink') {
            actionButtons = `
                <div class="flex gap-1 mt-2">
                    <button onclick="window.documentViewerInstance.linkManager.navigateToSourceDocumentFromMenu('${elementId}')" 
                            class="text-xs bg-orange-500 text-white px-2 py-1 rounded hover:bg-orange-600 transition-colors">
                        원본으로 이동
                    </button>
                    <button onclick="window.documentViewerInstance.linkManager.handleOverlapMenuClick('${type}', '${elementId}')" 
                            class="text-xs bg-gray-500 text-white px-2 py-1 rounded hover:bg-gray-600 transition-colors">
                        상세보기
                    </button>
                </div>
            `;
        }
        
        return `
            <div class="w-full p-3 rounded border ${colors[type].replace('text-yellow-800', '').replace('text-purple-800', '').replace('text-orange-800', '')} ${clickedClass}">
                <div class="flex items-center space-x-2">
                    <span class="text-lg">${icons[type]}</span>
                    <div class="flex-1">
                        <div class="font-medium text-gray-800">${labels[type]}</div>
                        <div class="text-xs text-gray-600">${element.textContent.substring(0, 40)}${element.textContent.length > 40 ? '...' : ''}</div>
                    </div>
                    ${isClicked ? '<span class="text-xs bg-blue-500 text-white px-1 rounded">클릭됨</span>' : ''}
                </div>
                ${actionButtons}
            </div>
        `;
    }

    /**
     * 메뉴에서 바로 링크된 문서로 이동
     */
    navigateToLinkedDocumentFromMenu(elementId) {
        this.hideTooltip();
        
        const link = this.documentLinks.find(l => l.id === elementId);
        if (link) {
            console.log('🔗 메뉴에서 링크 클릭:', link);
            
            // target_content_type이 없으면 ID로 추론
            let targetContentType = link.target_content_type;
            if (!targetContentType) {
                if (link.target_note_id) {
                    targetContentType = 'note';
                } else if (link.target_document_id) {
                    targetContentType = 'document';
                }
                console.log('🔍 메뉴에서 target_content_type 추론됨:', targetContentType);
            }
            
            const targetId = link.target_document_id || link.target_note_id;
            if (!targetId) {
                console.error('❌ 메뉴에서 대상 ID가 없습니다!', link);
                alert('링크 대상을 찾을 수 없습니다.');
                return;
            }
            
            // 링크 객체에 추론된 타입 추가
            const linkWithType = {
                ...link,
                target_content_type: targetContentType
            };
            
            console.log('🚀 메뉴에서 최종 링크 데이터:', linkWithType);
            this.navigateToLinkedDocument(targetId, linkWithType);
        } else {
            console.warn('링크 데이터를 찾을 수 없음:', elementId);
        }
    }

    /**
     * 메뉴에서 바로 소스 문서로 이동
     */
    navigateToSourceDocumentFromMenu(elementId) {
        this.hideTooltip();
        
        const backlink = this.backlinks.find(b => b.id === elementId);
        if (backlink) {
            this.navigateToSourceDocument(backlink.source_document_id, backlink);
        } else {
            console.warn('백링크 데이터를 찾을 수 없음:', elementId);
        }
    }

    /**
     * 겹침 메뉴 클릭 처리
     */
    handleOverlapMenuClick(type, elementId) {

        this.hideTooltip();
        
        // 해당 요소 찾기
        let element;
        if (type === 'highlight') {
            element = document.querySelector(`[data-highlight-id="${elementId}"]`);
            if (element && window.documentViewerInstance.highlightManager) {
                // 하이라이트 클릭 처리 (HighlightManager에 위임)
                const highlightId = elementId;
                
                // 해당 하이라이트 찾기
                const highlight = window.documentViewerInstance.highlightManager.highlights.find(h => h.id === highlightId);
                
                if (highlight) {
                    // 하이라이트 툴팁 표시 (메모 작성/편집 기능 포함)
                    window.documentViewerInstance.highlightManager.showHighlightTooltip(highlight, element);
                } else {
                    console.warn('하이라이트를 찾을 수 없음:', highlightId);
                }
            }
        } else if (type === 'link') {
            element = document.querySelector(`[data-link-id="${elementId}"]`);
            
            if (element) {
                // 링크 데이터 찾기
                const link = this.documentLinks.find(l => l.id === elementId);
                if (link) {
                    this.showLinkTooltip(link, element);
                }
            }
        } else if (type === 'backlink') {
            element = document.querySelector(`[data-backlink-id="${elementId}"]`);
            
            if (element) {
                // 백링크 데이터 찾기
                const backlink = this.backlinks.find(b => b.id === elementId);
                if (backlink) {
                    this.showBacklinkTooltip(backlink, element);
                }
            }
        }
    }

    /**
     * 텍스트 오프셋 계산
     */
    getTextOffset(root, node, offset) {
        let textOffset = 0;
        const walker = document.createTreeWalker(
            root,
            NodeFilter.SHOW_TEXT,
            null,
            false
        );
        
        let currentNode;
        while (currentNode = walker.nextNode()) {
            if (currentNode === node) {
                return textOffset + offset;
            }
            textOffset += currentNode.textContent.length;
        }
        
        return textOffset;
    }
}

// 전역으로 내보내기
window.LinkManager = LinkManager;
