// Voice Memos 완전 수정 - 안정적인 초기화 및 단일 창 관리
(function () {
    'use strict';

    if (window.HerVoiceMemos) {
        return;
    }

    const DEBUG_MODE = false; // 개발 시에만 true

    function debugLog(message, ...args) {
        if (DEBUG_MODE) {
            // console.log(message, ...args);
        }
    }

    class HerVoiceMemos {
        constructor() {
            this.isRecording = false;
            this.currentText = '';
            this.currentRecordId = null;
            this.records = [];
            this.totalCount = 0; // 전체 저장된 메모 개수
            this.loadedCount = 0; // 현재 화면에 로드된 개수
            this.sttEngine = null;
            this.currentLanguage = 'ko';
            this.isInitialized = false;
            this.isSaving = false; // 저장 중 플래그

            // 🆕 무한 스크롤
            this.PAGE_SIZE = 100;
            this.renderedCount = 0;
            this.isRenderingMore = false;
            this.scrollHandler = null;
            this.loadMoreEl = null;
            this.loadMoreObserver = null;

            // 🆕 선택 모드
            this.selectMode = false;
            this.selectedIds = new Set();

            // DOM 요소
            this.recordButton = document.getElementById('recordButton');
            this.recordStatus = document.getElementById('recordStatus');
            this.memoList = document.getElementById('memoList');
            this.memoCount = document.getElementById('memoCount');
            this.clearAllBtn = document.getElementById('clearAllBtn');
            this.emptyState = document.getElementById('emptyState');

            // 🆕 관리 풀다운 DOM
            this.manageBtn = document.getElementById('manageBtn');
            this.managePopover = document.getElementById('managePopover');
            this.popoverSelectMode = document.getElementById('popoverSelectMode');
            this.popoverExportAll = document.getElementById('popoverExportAll');
            this.popoverImport = document.getElementById('popoverImport');
            this.popoverClearAll = document.getElementById('popoverClearAll');

            // 🆕 선택 툴바 DOM
            this.selectionBar = document.getElementById('selectionBar');
            this.selectionInfo = document.getElementById('selectionInfo');
            this.selectAllBtn = document.getElementById('selectAllBtn');
            this.exportSelectedBtn = document.getElementById('exportSelectedBtn');
            this.deleteSelectedBtn = document.getElementById('deleteSelectedBtn');
            this.exitSelectBtn = document.getElementById('exitSelectBtn');

            // 🆕 가져오기 input
            this.importFileInput = document.getElementById('importFileInput');

            this.init();
        }

        async init() {
            debugLog(window.herI18n.t('logVoiceMemosInitStart'));
            try {
                // 🚨 강제 전역 상태 초기화 - 앱 시작 시 항상 깨끗한 상태로 시작
                if (window.HerSTTEngine) {
                    // console.log(`[VoiceMemos] 🧹 앱 초기화 시 전역 상태 강제 초기화`);
                    window.HerSTTEngine.globalRecordingState = {
                        isRecording: false,
                        currentSessionId: null,
                        currentContext: null,
                        currentTabId: null
                    };
                    // console.log(`[VoiceMemos] ✅ 전역 상태 초기화 완료:`, window.HerSTTEngine.globalRecordingState);
                }

                // 1. 필수 의존성 대기 (UI는 항상 먼저 표시)
                this.showEmptyState();
                this.updateUI();
                await this.waitForDependencies();
                // 2. 설정과 데이터를 병렬로 로드
                await Promise.all([
                    this.loadLanguageSettings(),
                    this.loadRecords()
                ]);
                // 3. 이벤트 리스너 설정
                this.setupEventListeners();
                // 4. Storage 리스너 설정
                this.setupStorageListener();
                // 5. 초기 UI 업데이트
                this.updateUI();
                this.updateLanguageUI();
                this.isInitialized = true;
                debugLog(window.herI18n.t('logVoiceMemosInitComplete'));
            } catch (error) {
                console.error(window.herI18n.t('logVoiceMemosInitFail'), error);
                this.showEmptyState();
            }
            // i18n 메시지 준비/변경 시 UI 강제 갱신
            window.addEventListener('her-language-changed', () => {
                this.updateUI();
            });
        }

        async waitForDependencies() {
            const requiredModules = ['herI18n', 'HerSTTEngine'];
            const checkInterval = 50;
            return new Promise((resolve) => {
                const check = () => {
                    const modulesReady = requiredModules.every(module => {
                        if (module === 'herI18n') {
                            // isReady가 없으면 무조건 true로 간주
                            return window.herI18n && (typeof window.herI18n.isReady !== 'function' || window.herI18n.isReady());
                        }
                        return window[module];
                    });
                    if (modulesReady) {
                        this.sttEngine = window.HerSTTEngine.getInstance();

                        // 🚨 HerSTTEngine 로드 직후 전역 상태 강제 초기화
                        // console.log(`[VoiceMemos] 🧹 HerSTTEngine 로드 후 전역 상태 강제 초기화`);
                        window.HerSTTEngine.globalRecordingState = {
                            isRecording: false,
                            currentSessionId: null,
                            currentContext: null,
                            currentTabId: null
                        };
                        // console.log(`[VoiceMemos] ✅ HerSTTEngine 로드 후 전역 상태 초기화 완료`);

                        resolve();
                    } else {
                        setTimeout(check, checkInterval);
                    }
                };
                check();
            });
        }

        async loadLanguageSettings() {
            try {
                const result = await chrome.storage.sync.get(['uiLanguage', 'selectedLanguage']);

                if (result.uiLanguage) {
                    this.currentLanguage = result.uiLanguage;
                    debugLog(window.herI18n.t('logVoiceMemosUILanguageSet', { language: this.currentLanguage }));

                    // i18n 언어 설정
                    if (window.herI18n && window.herI18n.setUILanguage) {
                        await window.herI18n.setUILanguage(this.currentLanguage);
                    }
                }

                // STT 언어 설정
                if (result.selectedLanguage && this.sttEngine) {
                    this.sttEngine.setLanguage(result.selectedLanguage);
                    debugLog(window.herI18n.t('logVoiceMemosSTTLanguageSet', { language: result.selectedLanguage }));
                }
            } catch (error) {
                console.error('[VoiceMemos] 언어 설정 실패:', error);
            }
        }

        async loadRecords() {
            try {
                // console.log('[VoiceMemos] 레코드 로드 시작 - 현재 레코드 수:', this.records.length);
                
                const result = await chrome.storage.local.get(['voiceRecords']);
                const newRecords = result.voiceRecords || [];
                const oldCount = this.records.length;
                
                // console.log('[VoiceMemos] Storage에서 로드된 레코드 수:', newRecords.length);
                // console.log('[VoiceMemos] 레코드 ID 목록:', newRecords.map(r => r.id).slice(0, 5));
                
                this.records = newRecords;
                this.totalCount = newRecords.length;
                this.loadedCount = newRecords.length;
                
                // console.log('[VoiceMemos] 레코드 로드 완료 - 최종 레코드 수:', this.records.length);
                
                debugLog(window.herI18n.t('logVoiceMemosRecordsLoaded', {
                    oldCount: oldCount,
                    newCount: this.records.length,
                    domains: [...new Set(this.records.map(r => r.domain))]
                }));
            } catch (error) {
                console.error(window.herI18n.t('logVoiceMemosRecordsLoadFail'), error);
                this.records = [];
                this.totalCount = 0;
                this.loadedCount = 0;
            }
            this.updateUI(); // 데이터 로딩 후 항상 UI 갱신
        }

        setupEventListeners() {
            // 녹음 버튼
            if (this.recordButton) {
                this.recordButton.addEventListener('click', () => {
                    debugLog(window.herI18n.t('logVoiceMemosRecordButtonClick'));
                    this.toggleRecording();
                });
            }

            // 전체 삭제 버튼 (legacy)
            if (this.clearAllBtn) {
                this.clearAllBtn.addEventListener('click', () => {
                    this.showConfirmModal();
                });
            }

            // 🆕 관리 풀다운 토글
            if (this.manageBtn) {
                this.manageBtn.addEventListener('click', (e) => {
                    e.stopPropagation();
                    this.toggleManagePopover();
                });
            }
            // 풀다운 바깥 클릭 시 닫기
            document.addEventListener('click', (e) => {
                if (!this.managePopover || !this.managePopover.classList.contains('open')) return;
                if (e.target.closest('#manageWrap')) return;
                this.closeManagePopover();
            });

            // 🆕 풀다운 항목
            if (this.popoverSelectMode) {
                this.popoverSelectMode.addEventListener('click', () => {
                    this.closeManagePopover();
                    this.enterSelectMode();
                });
            }
            if (this.popoverExportAll) {
                this.popoverExportAll.addEventListener('click', () => {
                    this.closeManagePopover();
                    this.exportRecords(this.records);
                });
            }
            if (this.popoverImport) {
                this.popoverImport.addEventListener('click', () => {
                    this.closeManagePopover();
                    if (this.importFileInput) this.importFileInput.click();
                });
            }
            if (this.popoverClearAll) {
                this.popoverClearAll.addEventListener('click', () => {
                    this.closeManagePopover();
                    this.showConfirmModal();
                });
            }

            // 🆕 가져오기 파일 선택
            if (this.importFileInput) {
                this.importFileInput.addEventListener('change', (e) => {
                    const file = e.target.files && e.target.files[0];
                    if (file) this.handleImportFile(file);
                    e.target.value = ''; // 같은 파일 재선택 허용
                });
            }

            // 🆕 선택 모드 툴바
            if (this.selectAllBtn) {
                this.selectAllBtn.addEventListener('click', () => this.toggleSelectAll());
            }
            if (this.exportSelectedBtn) {
                this.exportSelectedBtn.addEventListener('click', () => {
                    const items = this.records.filter(r => this.selectedIds.has(r.id));
                    if (items.length === 0) { this.showNotification('noMemosSelected'); return; }
                    this.exportRecords(items);
                });
            }
            if (this.deleteSelectedBtn) {
                this.deleteSelectedBtn.addEventListener('click', () => this.showConfirmDeleteSelectedModal());
            }
            if (this.exitSelectBtn) {
                this.exitSelectBtn.addEventListener('click', () => this.exitSelectMode());
            }

            // 🎯 테스트 버튼 (개발 모드에서만 활성화)
            if (DEBUG_MODE) {
                const testAutoStopBtn = document.getElementById('testAutoStopBtn');
                if (testAutoStopBtn) {
                    testAutoStopBtn.addEventListener('click', () => {
                        this.testAutoStopFeedback();
                    });
                }
            }

            // 키보드 단축키
            document.addEventListener('keydown', (e) => {
                if ((e.metaKey || e.ctrlKey) && e.key === 'r') {
                    e.preventDefault();
                    this.toggleRecording();
                }
            });

            window.addEventListener('her-voice-record-added', (e) => {
                const { record, source } = e.detail;
                debugLog(window.herI18n.t('logVoiceMemosExternalRecordAdded', {
                    recordId: record.id,
                    domain: record.domain,
                    source
                }));
                if (!this.isRecording) {
                    this.loadRecords().then(() => {
                        this.updateUI();
                    });
                }
            });

            // 🚨 런타임 메시지 리스너 추가 - 실시간 업데이트를 위해
            if (chrome.runtime && chrome.runtime.onMessage) {
                chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
                    // console.log('[VoiceMemos] 📨 런타임 메시지 수신:', message);

                    if (message.action === 'toggleMemoRecording') {
                        // 음성 메모 녹음 토글
                        this.toggleRecording();
                        sendResponse({ success: true });
                        return true;
                    } else if (message.action === 'startImmediateRecording') {
                        // 즉시 녹음 시작 (창 열자마자)
// console.log('[VoiceMemos] 🚀 단축키로 즉시 녹음 시작');
                        if (!this.isRecording) {
                            this.startRecording();
                        }
                        sendResponse({ success: true });
                        return true;
                    } else if (message.type === 'VOICE_MEMO_SAVED') {
                        // console.log('[VoiceMemos] 🆕 보이스 메모 저장 알림 수신:', message.record);

                        // 즉시 레코드 목록 새로고침
                        this.loadRecords().then(() => {
                            this.updateUI();
                            // console.log('[VoiceMemos] ✅ 실시간 업데이트 완료');
                        });

                        // 웹페이지에서 추가된 경우 특별 알림
                        if (message.record.domain !== 'Voice Memos') {
                            // console.log(`[VoiceMemos] 🌐 웹페이지(${message.record.domain})에서 메모 추가됨 - 실시간 업데이트`);
                        }
                    }

                    // 응답 필요시
                    if (sendResponse) {
                        sendResponse({ success: true });
                    }
                });

                // console.log('[VoiceMemos] 📨 런타임 메시지 리스너 설정 완료');
            }
        }

        setupStorageListener() {
            chrome.storage.onChanged.addListener((changes, namespace) => {
                if (changes.voiceRecords) {
                    const newRecords = changes.voiceRecords.newValue || [];
                    const oldRecords = changes.voiceRecords.oldValue || [];

                    /* console.log('[VoiceMemos] 📊 Storage 변경 감지:', {
                        oldCount: oldRecords.length,
                        newCount: newRecords.length,
                        isRecording: this.isRecording,
                        currentRecordId: this.currentRecordId
                    }); */

                    // 🚨 개선: 더 강력한 변경 감지 로직
                    let shouldUpdate = false;
                    let newRecord = null;

                    // 1. 개수 비교
                    if (newRecords.length > oldRecords.length) {
                        shouldUpdate = true;
                        newRecord = newRecords.find(r => !oldRecords.find(o => o.id === r.id));
                    }
                    // 2. 개수가 같아도 내용이 다를 수 있음 (수정된 경우)
                    else if (newRecords.length === oldRecords.length && newRecords.length > 0) {
                        // 가장 최근 레코드가 변경되었는지 확인
                        const latestNew = newRecords[0];
                        const latestOld = oldRecords[0];
                        if (latestNew && latestOld && latestNew.id !== latestOld.id) {
                            shouldUpdate = true;
                            newRecord = latestNew;
                        }
                    }
                    // 3. 강제 업데이트 (개수가 줄어든 경우도 포함)
                    else if (newRecords.length !== oldRecords.length) {
                        shouldUpdate = true;
                        // console.log('[VoiceMemos] 🔄 레코드 개수 변경으로 강제 업데이트');
                    }

                    if (shouldUpdate) {
                        // console.log('[VoiceMemos] 🆕 레코드 변경 감지 - UI 업데이트 시작');

                        // 새로운 레코드 정보 로깅
                        if (newRecord) {
                            /* console.log('[VoiceMemos] 🆕 새로운 레코드 감지:', {
                                id: newRecord.id,
                                domain: newRecord.domain,
                                text: newRecord.text.substring(0, 50) + '...',
                                isFromWebPage: newRecord.domain !== 'Voice Memos'
                            }); */
                        }

                        // 즉시 UI 업데이트
                        this.records = newRecords;
                        this.updateUI();

                        // 웹페이지에서 추가된 경우 특별 알림
                        if (newRecord && newRecord.domain !== 'Voice Memos') {
                            // console.log(`[VoiceMemos] 🌐 웹페이지(${newRecord.domain})에서 메모 추가됨`);
                        }
                    }
                }

                // UI 언어 변경 감지
                if (changes.uiLanguage) {
                    const newLanguage = changes.uiLanguage.newValue;
                    debugLog(window.herI18n.t('logVoiceMemosUILanguageChangeDetected', { language: newLanguage }));
                    this.currentLanguage = newLanguage;
                    this.updateLanguageSettings(newLanguage);
                }

                // 언어 변경 알림 감지
                if (changes.uiLanguageChanged) {
                    debugLog(window.herI18n.t('logVoiceMemosLanguageChangeNotificationDetected'));
                    this.handleLanguageChange();
                }

                // 음성 언어 변경 감지
                if (changes.selectedLanguage) {
                    const newLanguage = changes.selectedLanguage.newValue;
                    if (this.sttEngine) {
                        this.sttEngine.setLanguage(newLanguage);
                    }
                    debugLog(window.herI18n.t('logVoiceMemosVoiceLanguageChange', { language: newLanguage }));
                }
            });
        }

        async updateLanguageSettings(newLanguage) {
            try {
                this.currentLanguage = newLanguage;

                // i18n 언어 설정
                if (window.herI18n && window.herI18n.setUILanguage) {
                    await window.herI18n.setUILanguage(newLanguage);
                }

                // UI 업데이트
                this.updateLanguageUI();

            } catch (error) {
                console.error(window.herI18n.t('logVoiceMemosLanguageSettingUpdateFail'), error);
            }
        }

        handleLanguageChange() {
            // 언어 변경 처리
            setTimeout(() => {
                this.updateLanguageUI();
            }, 100);
        }

        updateLanguageUI() {
            debugLog(window.herI18n.t('logVoiceMemosUILanguageUpdate'));

            // data-i18n 속성을 가진 모든 요소 업데이트
            document.querySelectorAll('[data-i18n]').forEach(el => {
                const key = el.getAttribute('data-i18n');
                if (window.herI18n && window.herI18n.t) {
                    try {
                        const translatedText = window.herI18n.t(key);
                        el.textContent = translatedText;
                    } catch (error) {
                        console.error(window.herI18n.t('logVoiceMemosTranslationFail', { key: key }), error);
                    }
                }
            });

            // 레코드 카운트 업데이트
            this.updateRecordCount();
        }

        async toggleRecording() {
            if (!this.isInitialized) {
                // console.log(window.herI18n.t('logVoiceMemosInitNotComplete'));
                return;
            }

            if (this.isRecording) {
                await this.stopRecording();
            } else {
                await this.startRecording();
            }
        }

        async startRecording() {
            if (this.isRecording || !this.sttEngine) {
                // console.log('[VoiceMemos] 이미 녹음 중이거나 엔진 없음');
                return;
            }

            // console.log(`[VoiceMemos] 🎯 녹음 시작 시도`);

            try {
                const sessionId = `voice-memos-${Date.now()}`;

                // 🎯 핵심: 전역 상태 사전 체크 및 선점
                const globalState = window.HerGlobalState.getState();
                if (globalState.isRecording) {
                    // console.log(`[VoiceMemos] 🚫 다른 곳에서 녹음 중 - 차단`);
                    this.showBlockingNotification(globalState.currentContext);
                    return;
                }

                // 🎯 STT 콜백 설정 (먼저 설정)
                const onUpdateCallback = (sttData) => {
                    if (!this.isRecording) return;
                    const newSttText = sttData.text || '';
                    this.currentText = newSttText;
                    this.updateLiveRecordCard(this.currentText);
                };

                const onStateChangeCallback = (state, data) => {
                    // console.log(`[VoiceMemos] STT 상태 변경: ${state}`);
                    if (state === 'stop') {
                        this.handleRecordingStop();
                    } else if (state === 'error') {
                        this.handleRecordingError(data?.error, data);
                    }
                };

                this.sttEngine.setCallbacks(onUpdateCallback, onStateChangeCallback);

                // STT 시작 (전역 상태 차단은 여기서 발생)
                await this.sttEngine.start(sessionId, 'voice-memos', { preserveText: false });

                // 🎯 STT 시작 성공 후에만 UI 상태 업데이트
                this.isRecording = true;
                this.currentRecordId = Date.now();
                this.currentText = '';

                // UI 업데이트
                this.updateRecordingUI(true);
                this.createLiveRecordCard();

            } catch (error) {
                console.error('[VoiceMemos] 녹음 시작 실패:', error);

                // 🎯 동시 녹음 에러 처리 단순화
                if (error.type === 'concurrent_recording') {
                    this.showBlockingNotification(error.currentContext);
                } else {
                    this.showNotification('startRecordingFailed');
                }

                // 상태 복구 (UI 상태는 변경하지 않음 - 애초에 설정하지 않았으므로)
                this.isRecording = false;
                this.updateRecordingUI(false);
            }
        }

        // 🚨 새로운 메서드: 동시 녹음 차단 처리
        handleConcurrentRecordingBlocked(data) {
            // console.log(`[VoiceMemos] 🚫 동시 녹음 차단 처리 시작:`, data);

            const { blockingContext, requestingContext, error } = data;

            /* console.log('[VoiceMemos] 동시 녹음 차단됨:', {
                blocking: blockingContext,
                requesting: requestingContext,
                error: error,
                beforeState: { isRecording: this.isRecording, currentRecordId: this.currentRecordId }
            }); */

            // 상태 초기화
            // console.log(`[VoiceMemos] 🔄 상태 초기화 중...`);
            this.isRecording = false;
            this.updateRecordingUI(false);
            this.removeLiveRecordCard();

            // 🎯 컨텍스트별 알림 메시지
            let notificationKey = 'concurrentRecording';
            if (blockingContext === 'voice-memos') {
                notificationKey = 'concurrentRecordingVoiceMemos';
            } else if (blockingContext === 'content') {
                notificationKey = 'concurrentRecordingWebPage';
            }

            // console.log(`[VoiceMemos] 📢 알림 메시지 키: ${notificationKey}`);

            // 알림 표시
            // console.log(`[VoiceMemos] 🔔 showNotification 호출 전`);
            try {
                this.showNotification(notificationKey);
                // console.log(`[VoiceMemos] ✅ showNotification 호출 완료`);
            } catch (notificationError) {
                console.error(`[VoiceMemos] ❌ showNotification 실패:`, notificationError);

                // 폴백 알림 (브라우저 기본 alert)
                const fallbackMessage = window.herI18n ? window.herI18n.t(notificationKey) : '다른 곳에서 이미 녹음 중입니다.';
                // console.log(`[VoiceMemos] 📢 폴백 알림 표시: ${fallbackMessage}`);
                setTimeout(() => alert(fallbackMessage), 100);
            }

            // 🎯 녹음 중인 창으로 포커스 이동 시도
            // console.log(`[VoiceMemos] 🎯 포커스 이동 시도...`);
            try {
                this.focusRecordingWindow(blockingContext);
                // console.log(`[VoiceMemos] ✅ 포커스 이동 시도 완료`);
            } catch (focusError) {
                console.error(`[VoiceMemos] ❌ 포커스 이동 실패:`, focusError);
            }

            // console.log(`[VoiceMemos] 🏁 동시 녹음 차단 처리 완료`);
        }

        // 🚨 기존 에러 처리 메서드 (이중 보안)
        handleConcurrentRecordingError(error) {
            // console.log('[VoiceMemos] 동시 녹음 에러 처리:', error.currentContext);

            // 상태 초기화
            this.isRecording = false;
            this.updateRecordingUI(false);
            this.removeLiveRecordCard();

            // 알림 표시
            this.showNotification('concurrentRecording');

            // 🎯 녹음 중인 창으로 포커스 이동 시도
            this.focusRecordingWindow(error.currentContext);
        }

        async stopRecording() {
            if (!this.isRecording || !this.sttEngine) {
                debugLog(window.herI18n.t('logVoiceMemosRecordingStopFail', {
                    isRecording: this.isRecording,
                    hasEngine: !!this.sttEngine
                }));
                return;
            }
            debugLog(window.herI18n.t('logVoiceMemosRecordingStop'));
            try {
                await this.sttEngine.stop();
                this.isRecording = false;

                // 🚨 명시적 전역 상태 정리 - 좀비 상태 방지
                if (window.HerSTTEngine) {
                    // console.log(`[VoiceMemos] 🧹 명시적 전역 상태 정리`);
                    window.HerSTTEngine.globalRecordingState = {
                        isRecording: false,
                        currentSessionId: null,
                        currentContext: null,
                        currentTabId: null
                    };
                }

                this.updateRecordingUI(false);
                this.finalizeLiveRecordCard();
                if (this.currentText && this.currentText.trim()) {
                    // 🎯 자동 클립보드 복사 (설정에 따라)
                    await this.handleAutoClipboardCopy(this.currentText.trim());
                    await this.saveRecord();
                } else {
                    this.removeLiveRecordCard();
                    this.showNotification('emptyRecordingRemoved');
                    return;
                }
            } catch (error) {
                console.error(window.herI18n.t('logVoiceMemosRecordingStopFail'), error);
                this.isRecording = false;
                this.updateRecordingUI(false);
                this.removeLiveRecordCard();
            }
        }

        async handleRecordingStop() {
            if (!this.isRecording) {
                // console.log('[VoiceMemos] 이미 녹음이 중지된 상태 - 중복 처리 방지');
                return;
            }

            // 🚨 currentRecordId가 없으면 이미 처리된 것으로 간주
            if (!this.currentRecordId) {
                // console.log('[VoiceMemos] currentRecordId가 없음 - 이미 처리됨');
                this.isRecording = false;
                this.updateRecordingUI(false);
                return;
            }

            // 🎯 상태 변경을 먼저 해서 중복 호출 방지
            this.isRecording = false;

            const finalText = this.currentText || '';

            if (finalText.trim()) {
                // 메모 저장
                // console.log('[VoiceMemos] 정상 종료 - 메모 저장:', finalText.length, '글자');
                await this.saveRecord();
            } else {
                // console.log('[VoiceMemos] 빈 텍스트로 종료 - 라이브 카드 제거');
                this.removeLiveRecordCard();
                this.showNotification('emptyRecordingRemoved');
            }

            this.updateRecordingUI(false);
            this.finalizeLiveRecordCard();

            // 🎯 중요: currentRecordId는 저장 완료 후에만 초기화
            setTimeout(() => {
                this.currentRecordId = null;
                this.currentText = '';
            }, 100);
        }

        // 🎯 자동 종료 처리 메서드
        async handleAutoStop(data) {
            // console.log('[VoiceMemos] 자동 종료 처리 시작:', data);

            // 🎯 상태 변경을 먼저 해서 중복 호출 방지
            this.isRecording = false;
            this.updateRecordingUI(false);

            const finalText = data?.finalText || this.currentText || '';

            if (finalText.trim()) {
                // 메모 저장
                // console.log('[VoiceMemos] 자동 종료 - 메모 저장:', finalText.length, '글자');
                await this.saveRecord();

                // 🎯 자동 클립보드 복사 (설정에 따라)
                await this.handleAutoClipboardCopy(finalText.trim());
            }

            // 🎯 자동 종료 피드백 표시
            this.showAutoStopFeedback(data);

            this.finalizeLiveRecordCard();

            // 🎯 중요: currentRecordId는 저장 완료 후에만 초기화
            setTimeout(() => {
                this.currentRecordId = null;
                this.currentText = '';
            }, 100);
        }

        // 🎯 자동 클립보드 복사 처리
        async handleAutoClipboardCopy(text) {
            try {
                // 설정 확인 (Storage 접근 실패 시 기본값 사용)
                let autoClipboardCopy = true; // 기본값
                try {
                    const result = await chrome.storage.sync.get(['autoClipboardCopy']);
                    autoClipboardCopy = result.autoClipboardCopy !== false;
                } catch (storageError) {
                    console.warn('[VoiceMemos] Storage 접근 실패, 기본값 사용:', storageError);
                }

                if (autoClipboardCopy) {
                    try {
                        await navigator.clipboard.writeText(text);
                        // console.log('[VoiceMemos] 자동 클립보드 복사 완료:', text.length, '글자');

                        // 🎯 자동 복사 완료 토스트 알림 표시
                        this.showNotification('copied');

                        // Amplitude 이벤트
                        if (window.amplitude) {
                            window.amplitude.trackEvent('Auto Clipboard Copy', {
                                source: 'auto_stop',
                                text_length: text.length
                            });
                        }
                    } catch (clipboardError) {
                        console.error('[VoiceMemos] 클립보드 접근 실패:', clipboardError);
                        // 클립보드 접근 실패 시에도 사용자에게 알림
                        this.showNotification('copyFailed');
                    }
                } else {
                    // console.log('[VoiceMemos] 자동 클립보드 복사 비활성화됨');
                }
            } catch (error) {
                console.error('[VoiceMemos] 자동 클립보드 복사 실패:', error);
            }
        }

        // 🎯 자동 종료 피드백 표시
        showAutoStopFeedback(data) {
            const duration = data?.duration || 0;
            const durationMinutes = Math.floor(duration / 60000);
            const durationSeconds = Math.floor((duration % 60000) / 1000);

            const title = window.herI18n ? window.herI18n.t('autoStopTitle') : '녹음 자동 종료';
            const message = window.herI18n ? 
                window.herI18n.t('autoStopMessage', { minutes: durationMinutes, seconds: durationSeconds }) :
                `녹음이 자동으로 종료되었습니다.\n\n지금까지 ${durationMinutes}분 ${durationSeconds}초간 녹음된 내용이 저장되었습니다.`;

            // 🎯 풀스크린 피드백 오버레이 생성
            const overlay = document.createElement('div');
            overlay.id = 'auto-stop-overlay';
            overlay.style.cssText = `
                position: fixed;
                top: 0;
                left: 0;
                width: 100vw;
                height: 100vh;
                background: rgba(0, 0, 0, 0.75);
                backdrop-filter: blur(15px);
                display: flex;
                align-items: center;
                justify-content: center;
                z-index: 2147483647;
                animation: fadeIn 0.3s ease-out;
            `;

            const content = document.createElement('div');
            content.style.cssText = `
                background: rgba(255, 255, 255, 0.95);
                backdrop-filter: blur(20px);
                color: #1D1D1F;
                padding: 32px;
                border-radius: 16px;
                text-align: center;
                max-width: 320px;
                box-shadow: 0 12px 40px rgba(0, 0, 0, 0.2);
                border: 1px solid rgba(255, 255, 255, 0.3);
                animation: slideInUp 0.4s ease-out;
            `;

            content.innerHTML = `
                <div style="font-size: 32px; margin-bottom: 16px; opacity: 0.8;">⏰</div>
                <h3 style="margin: 0 0 12px 0; font-size: 16px; font-weight: 600; color: #1D1D1F;">${title}</h3>
                <p style="margin: 0; font-size: 14px; line-height: 1.4; color: #6B7280;">${message}</p>
            `;

            // 애니메이션 스타일 추가
            if (!document.querySelector('#auto-stop-animations')) {
                const style = document.createElement('style');
                style.id = 'auto-stop-animations';
                style.textContent = `
                    @keyframes fadeIn {
                        from { opacity: 0; }
                        to { opacity: 1; }
                    }
                    @keyframes slideInUp {
                        from {
                            transform: translateY(30px);
                            opacity: 0;
                        }
                        to {
                            transform: translateY(0);
                            opacity: 1;
                        }
                    }
                    @keyframes fadeOut {
                        from { opacity: 1; }
                        to { opacity: 0; }
                    }
                    @keyframes slideOutDown {
                        from {
                            transform: translateY(0);
                            opacity: 1;
                        }
                        to {
                            transform: translateY(30px);
                            opacity: 0;
                        }
                    }
                `;
                document.head.appendChild(style);
            }

            overlay.appendChild(content);
            document.body.appendChild(overlay);

            // 2초 후 자동 제거
            setTimeout(() => {
                overlay.style.animation = 'fadeOut 0.3s ease-out';
                content.style.animation = 'slideOutDown 0.3s ease-out';
                
                setTimeout(() => {
                    if (overlay.parentNode) {
                        overlay.parentNode.removeChild(overlay);
                    }
                }, 300);
            }, 2000);
        }

        // 🎯 테스트용 자동 종료 피드백 (개발 완료 후 제거)
        testAutoStopFeedback() {
            // console.log('[VoiceMemos] 테스트 자동 종료 피드백 실행');
            
            const testData = {
                duration: 5 * 60 * 1000 + 30 * 1000, // 5분 30초
                finalText: '이것은 테스트용 자동 종료 피드백입니다. 실제로는 STT 스펙 한계로 인해 자동으로 종료되었을 때 이 화면이 나타납니다.',
                endType: 'auto_stop',
                reason: '테스트용 자동 종료'
            };

            this.showAutoStopFeedback(testData);
        }

        // 🎯 포커스 이동 기능 개선
        focusRecordingWindow(context) {
            try {
                // console.log(`[VoiceMemos] 녹음 중인 창으로 포커스 이동 시도: ${context}`);

                if (context === 'voice-memos') {
                    // 다른 Voice Memos 창이 열려있다면 (불가능하지만 안전장치)
                    // console.log('[VoiceMemos] 다른 Voice Memos 창이 활성화되어 있음');
                    // 현재 창에 포커스
                    window.focus();

                } else if (context === 'content') {
                    // 콘텐츠 스크립트에서 녹음 중 - 해당 탭으로 이동 시도
                    if (chrome.tabs && chrome.tabs.query) {
                        chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
                            if (tabs.length > 0) {
                                chrome.tabs.update(tabs[0].id, { active: true }, () => {
                                    // console.log('[VoiceMemos] 녹음 중인 웹페이지 탭으로 포커스 이동');
                                });
                            }
                        });
                    } else {
                        // Extension context에서는 직접 탭 제어 불가
                        // console.log('[VoiceMemos] 탭 제어 권한 없음 - 메시지만 표시');
                    }

                } else {
                    // console.log(`[VoiceMemos] 알 수 없는 컨텍스트: ${context}`);
                }

            } catch (e) {
                console.error('[VoiceMemos] 창 포커스 이동 실패:', e);
            }
        }

        handleRecordingError(error, data) {
            // console.log(`[VoiceMemos] 🚨 에러 발생 전 상태 - isRecording: ${this.isRecording}, currentRecordId: ${this.currentRecordId}`);
            // console.log('[VoiceMemos] 에러 발생했지만 텍스트 보존:', this.currentText?.length || 0, '글자');

            // 🚨 ABORTED 에러는 무시 - 사전 차단이 작동하므로 발생하지 않아야 함
            if (data?.isAborted || data?.endType === 'aborted') {
                // console.log('[VoiceMemos] ABORTED 에러 감지 - 하지만 무시하고 녹음 계속');
                // console.log('[VoiceMemos] 사전 차단이 작동해야 하므로 이 에러는 발생하지 않아야 함');
                return; // 아무것도 하지 않고 녹음 계속
            }

            // 기존 에러 처리 로직...
            if (data?.preservedText) {
                this.currentText = data.preservedText;
                this.updateLiveRecordCard(this.currentText);
            }

            // 🎯 개선된 에러 처리
            const errorType = error?.type || data?.error?.type || 'unknown';
            const errorMessage = error?.message || data?.error?.message || '알 수 없는 오류가 발생했습니다.';

            // console.log(`[VoiceMemos] 에러 타입: ${errorType}, 메시지: ${errorMessage}`);

            // 에러 타입별 처리
            switch (errorType) {
                case 'network':
                    if (data?.maxRetriesExceeded) {
                        this.showNotification('maxRetriesExceeded');
                        // console.log('[VoiceMemos] 최대 재시도 횟수 초과 - 녹음 중단');
                        this.handleRecordingStop();
                    } else {
                        this.showNotification('networkErrorRecovering');
                        // console.log('[VoiceMemos] 네트워크 에러로 중단되었지만 복구 시도 중입니다.');
                    }
                    break;

                case 'not-allowed':
                    this.showNotification('microphonePermissionDenied');
                    // console.log('[VoiceMemos] 마이크 권한 거부 - 녹음 중단');
                    this.handleRecordingStop();
                    break;

                case 'audio-capture':
                    this.showNotification('microphoneAccessFailed');
                    // console.log('[VoiceMemos] 마이크 접근 실패 - 녹음 중단');
                    this.handleRecordingStop();
                    break;

                case 'https_required':
                    this.showNotification('httpsRequired');
                    // console.log('[VoiceMemos] HTTPS 필요 - 녹음 중단');
                    this.handleRecordingStop();
                    break;

                case 'microphone_permission_denied':
                    this.showNotification('microphonePermissionDenied');
                    // console.log('[VoiceMemos] 마이크 권한 거부 - 녹음 중단');
                    this.handleRecordingStop();
                    break;

                case 'api_not_supported':
                    this.showNotification('apiNotSupported');
                    // console.log('[VoiceMemos] Speech Recognition API 미지원 - 녹음 중단');
                    this.handleRecordingStop();
                    break;

                default:
                    this.showNotification('unknownError');
                    // console.log('[VoiceMemos] 기타 에러 - 녹음 중단');
                    this.handleRecordingStop();
                    break;
            }

            // console.log(`[VoiceMemos] 🚨 에러 처리 후 상태 - isRecording: ${this.isRecording}, currentRecordId: ${this.currentRecordId}`);
        }

        handleRecordingRestart(data) {
            // console.log('[VoiceMemos] STT 에러 복구됨 - UI 상태 동기화');

            // 🎯 currentRecordId가 손실되었다면 복원
            if (!this.currentRecordId) {
                const liveCards = document.querySelectorAll('[id^="live-record-"]');
                if (liveCards.length > 0) {
                    const lastCard = liveCards[liveCards.length - 1];
                    this.currentRecordId = lastCard.id.replace('live-record-', '');
                    // console.log(`[VoiceMemos] currentRecordId 복원: ${this.currentRecordId}`);
                } else {
                    console.error('[VoiceMemos] 라이브 카드를 찾을 수 없어 currentRecordId 복원 실패');
                    return; // 복원 실패 시 처리 중단
                }
            }

            // 🚨 중요: UI 상태를 녹음 중으로 복구
            this.isRecording = true;
            this.updateRecordingUI(true);

            // 보존된 텍스트가 있으면 현재 텍스트로 설정
            if (data?.preservedText) {
                this.currentText = data.preservedText;
                this.updateLiveRecordCard(this.currentText);
                // console.log('[VoiceMemos] 보존된 텍스트 복구:', this.currentText.length, '글자');
            }

            // 🚨 STT 콜백 재연결 - 누적 방식으로 수정!
            if (this.sttEngine) {
                this.sttEngine.onUpdate = (sttData) => {
                    if (!this.isRecording) return;

                    // 🎯 핵심: STT 엔진에서 온 전체 텍스트를 현재 텍스트로 설정
                    const newSttText = sttData.text || '';
                    this.currentText = newSttText;

                    this.updateLiveRecordCard(this.currentText);

                    // console.log(`[VoiceMemos] STT 업데이트: ${this.currentText.length}글자`);
                    // console.log(`[VoiceMemos] 마지막 50글자: "${this.currentText.slice(-50)}"`);
                };

                // 상태 변경 콜백도 재연결
                this.sttEngine.onStateChange = (state, stateData) => {
                    // console.log(`[VoiceMemos] STT 상태 변경: ${state}`);
                    if (state === 'stop') {
                        // 🎯 stop 상태는 정상적인 녹음 종료일 때만 처리
                        // console.log('[VoiceMemos] 정상적인 녹음 종료 - handleRecordingStop 호출');
                        this.handleRecordingStop();
                    } else if (state === 'auto_stop') {
                        // 🎯 자동 종료 처리
                        // console.log('[VoiceMemos] 자동 종료 감지 - handleAutoStop 호출');
                        this.handleAutoStop(stateData);
                    } else if (state === 'error') {
                        // 🎯 error 상태는 복구 가능한 에러이므로 stop 호출하지 않음
                        // console.log('[VoiceMemos] 복구 가능한 에러 - handleRecordingError 호출');
                        this.handleRecordingError(stateData?.error, stateData);
                    } else if (state === 'restart') {
                        // console.log('[VoiceMemos] STT 복구 - handleRecordingRestart 호출');
                        this.handleRecordingRestart(stateData);
                    } else if (state === 'concurrent_recording_blocked') {
                        // 복구 중에도 동시 녹음 차단 처리
                        this.handleConcurrentRecordingBlocked(stateData);
                    }
                };

                // console.log('[VoiceMemos] STT 콜백 재연결 완료 - 누적 방식 적용');
            }

            // 🚨 복구 타입별 알림
            const recoveryType = data?.endType || 'unknown';
            if (recoveryType === 'error_recovery') {
                this.showNotification('recordingRecovered');
            } else if (recoveryType === 'visibility_recovery') {
                this.showNotification('recordingResumedVisibility');
            } else {
                this.showNotification('recordingResumed');
            }

            // 🚨 디버깅용 상태 체크
            this.debugCurrentState();

            // console.log('[VoiceMemos] 녹음 복구 완료 - 텍스트:', this.currentText.length, '글자');
        }

        // 🚨 디버깅용 메서드 (프로덕션에서는 비활성화)
        debugCurrentState() {
            if (DEBUG_MODE) {
                // console.log('=== Voice Memos 현재 상태 ===');
                // console.log('isRecording:', this.isRecording);
                // console.log('currentText 길이:', this.currentText?.length || 0);
                // console.log('currentRecordId:', this.currentRecordId);
                // console.log('sttEngine 존재:', !!this.sttEngine);
                // console.log('라이브 카드 존재:', !!document.getElementById(`live-record-${this.currentRecordId}`));

                if (this.currentText) {
                    // console.log('currentText 마지막 100글자:', this.currentText.slice(-100));
                }

                if (this.sttEngine) {
                    // console.log('STT finalTranscript 길이:', this.sttEngine.finalTranscript?.length || 0);
                    if (this.sttEngine.finalTranscript) {
                        // console.log('STT finalTranscript 마지막 100글자:', this.sttEngine.finalTranscript.slice(-100));
                    }
                }
                // console.log('==========================');
            }
        }

        async saveRecord() {
            if (!this.currentText?.trim() || this.isSaving) return;

            this.isSaving = true; // 저장 중 플래그 설정

            const recordStartTime = this.recordingStartTime || Date.now();
            const record = {
                id: Date.now(),
                text: this.currentText.trim(),
                timestamp: new Date().toISOString(),
                domain: 'Voice Memos',
                lang: 'ko-KR'
            };

            try {
                // 🎯 저장 전 현재 상태 로깅
                // console.log('[VoiceMemos] 저장 시작 - 현재 레코드 수:', this.records.length);

                const result = await chrome.storage.local.get(['voiceRecords']);
                const records = result.voiceRecords || [];

                // console.log('[VoiceMemos] Storage에서 로드된 레코드 수:', records.length);

                // 중복 체크 강화: 같은 텍스트가 최근 5초 내에 저장되었는지 확인
                const now = Date.now();
                const isDuplicate = records.some(r =>
                    r.text === record.text &&
                    r.domain === 'Voice Memos' &&
                    (now - new Date(r.timestamp).getTime()) < 5000
                );

                if (isDuplicate) {
                    // console.log('[VoiceMemos] 중복 저장 방지:', record.text);
                    this.isSaving = false;
                    return;
                }

                // 🎯 새 레코드 추가
                records.unshift(record);
                
                // 🎯 저장 전 최종 확인
                // console.log('[VoiceMemos] 저장할 레코드 수:', records.length);
                // console.log('[VoiceMemos] 새 레코드 ID:', record.id);

                await chrome.storage.local.set({ voiceRecords: records });
                
                // 🎯 저장 후 확인
                const verifyResult = await chrome.storage.local.get(['voiceRecords']);
                const savedRecords = verifyResult.voiceRecords || [];
                // console.log('[VoiceMemos] 저장 후 확인된 레코드 수:', savedRecords.length);

                // 🎯 로컬 상태 업데이트
                this.records = savedRecords;
                this.totalCount = savedRecords.length;
                this.loadedCount = savedRecords.length;

                // 🎯 UI 업데이트
                this.updateUI();
                
                // console.log('[VoiceMemos] 저장 완료 - 최종 레코드 수:', this.records.length);
                debugLog(window.herI18n.t('logVoiceMemosSaveComplete', { id: record.id }));

                // Amplitude 이벤트 추가
                if (window.amplitude) {
                    const duration = (Date.now() - recordStartTime) / 1000;
                    window.amplitude.incrementUserProperty('total_memos_saved');
                    window.amplitude.setUserProperties({
                        last_used_source: 'voice_memos'
                    });
                    window.amplitude.trackEvent('Memo Saved', {
                        source: 'voice_memos',
                        page_domain: 'Voice Memos',
                        text_length: record.text.length,
                        recording_duration_sec: duration,
                        language: 'ko-KR'
                    });
                }

                // 🎯 저장 완료 알림은 제거 (클립보드 복사 알림만 표시)
                // this.showNotification('recordingSaved');
            } catch (error) {
                console.error(window.herI18n.t('logVoiceMemosSaveFail'), error);
                this.showNotification('saveFailed');
            } finally {
                this.isSaving = false; // 저장 완료 후 플래그 해제
                this.currentText = '';
                this.currentRecordId = null;
            }
        }

        createLiveRecordCard() {
            if (!this.memoList) return;
            this.hideEmptyState();
            const div = document.createElement('div');
            div.className = 'memo-item live-recording';
            div.id = `live-record-${this.currentRecordId}`;
            div.style.transform = 'rotate(-1deg)';
            div.innerHTML = `
                <div class="memo-header">
                    <div class="memo-meta">
                        <div class="memo-time">
                            <span class="recording-dot">●</span>
                            ${this.formatTime(new Date().toISOString())}
                        </div>
                        <div class="memo-domain">Voice Memos</div>
                    </div>
                </div>
                <div class="memo-content processing">녹음 중...</div>
            `;
            this.memoList.insertBefore(div, this.memoList.firstChild);
        }

        updateLiveRecordCard(text) {
            if (!this.currentRecordId) {
                console.error('[VoiceMemos] currentRecordId가 없음 - 복구 시도');

                // 🎯 복구 시도: 가장 최근 라이브 카드 찾기
                const liveCards = document.querySelectorAll('[id^="live-record-"]');
                if (liveCards.length > 0) {
                    const lastCard = liveCards[liveCards.length - 1];
                    this.currentRecordId = lastCard.id.replace('live-record-', '');
                    // console.log(`[VoiceMemos] currentRecordId 자동 복구: ${this.currentRecordId}`);
                } else {
                    console.error('[VoiceMemos] 복구 실패: 라이브 카드가 존재하지 않음');
                    return;
                }
            }

            const liveCard = document.getElementById(`live-record-${this.currentRecordId}`);
            if (!liveCard) {
                console.error(`[VoiceMemos] 라이브 카드 찾을 수 없음: live-record-${this.currentRecordId}`);
                return;
            }

            const contentEl = liveCard.querySelector('.memo-content');
            if (!contentEl) {
                console.error('[VoiceMemos] memo-content 요소 찾을 수 없음');
                return;
            }

            const displayText = text || '녹음 중...';

            // DOM 업데이트 전 디버깅
            // console.log(`[VoiceMemos] 라이브 카드 업데이트 시도:`);
            // console.log(`  - 현재 텍스트 길이: ${displayText.length}`);
            // console.log(`  - 마지막 50글자: "${displayText.slice(-50)}"`);
            // console.log(`  - 요소 ID: live-record-${this.currentRecordId}`);

            // 실제 DOM 업데이트
            contentEl.textContent = displayText;
            contentEl.className = text ? 'memo-content' : 'memo-content processing';

            // 업데이트 후 확인
            const actualText = contentEl.textContent;
            // console.log(`[VoiceMemos] DOM 업데이트 완료 - 실제 표시된 길이: ${actualText.length}`);

            if (actualText.length !== displayText.length) {
                console.error(`[VoiceMemos] DOM 업데이트 불일치! 예상: ${displayText.length}, 실제: ${actualText.length}`);
            }

            // 긴 텍스트일 때 스크롤을 하단으로
            if (text && text.length > 500) {
                contentEl.scrollTop = contentEl.scrollHeight;
            }
        }

        finalizeLiveRecordCard() {
            const liveCard = document.getElementById(`live-record-${this.currentRecordId}`);
            if (liveCard) {
                const recordingDot = liveCard.querySelector('.recording-dot');
                if (recordingDot) recordingDot.remove();
                liveCard.style.transform = 'rotate(0deg)';
                liveCard.classList.remove('live-recording');
                const contentEl = liveCard.querySelector('.memo-content');
                if (contentEl && this.currentText) {
                    contentEl.textContent = this.currentText;
                    contentEl.className = 'memo-content';
                }
                this.addActionButtons(liveCard, this.currentRecordId);
            }
        }

        removeLiveRecordCard() {
            const liveCard = document.getElementById(`live-record-${this.currentRecordId}`);
            if (liveCard) {
                liveCard.remove();
            }

            // 레코드가 없으면 빈 상태 표시
            if (this.records.length === 0) {
                this.showEmptyState();
            }
        }

        updateRecordingUI(isRecording) {
            if (this.recordButton) {
                // 아이콘 변경
                if (!window.herSVGIcons) throw new Error(window.herI18n.t('logVoiceMemosHerSVGIconsNotLoaded'));
                if (isRecording) {
                    this.recordButton.innerHTML = window.herSVGIcons.getStopIcon();
                    this.recordButton.classList.add('recording');
                } else {
                    this.recordButton.innerHTML = window.herSVGIcons.getMicrophoneIcon();
                    this.recordButton.classList.remove('recording');
                }
                this.recordButton.className = 'record-button ' + (window.herPremiumMode ? window.herPremiumMode.getButtonClass() : 'basic');
                this.recordButton.style.width = window.herPremiumMode && window.herPremiumMode.isPremium ? '56px' : '32px';
                this.recordButton.style.height = window.herPremiumMode && window.herPremiumMode.isPremium ? '56px' : '32px';
            }

            // 상태 텍스트는 단순하게
            if (this.recordStatus) {
                if (isRecording) {
                    this.recordStatus.textContent = window.herI18n ?
                        window.herI18n.t('recordStatusListening') :
                        'Listening...';
                    this.recordStatus.classList.add('recording');
                } else {
                    this.recordStatus.textContent = window.herI18n ?
                        window.herI18n.t('clickToRecord') :
                        'Click to record';
                    this.recordStatus.classList.remove('recording');
                }
            }
        }

        getErrorKey(error) {
            const errorMap = {
                'not-allowed': 'microphonePermissionDenied',
                'audio-capture': 'microphoneAccessFailed',
                'network': 'networkError',
                'service-not-allowed': 'serviceNotAllowed',
                'no-speech': 'noSpeechDetected'
            };

            return errorMap[error] || 'unknownError';
        }

        updateUI() {
            this.updateRecordCount();
            this.renderRecords();
        }

        updateRecordCount() {
            const count = this.records.length;
            // console.log('[VoiceMemos] 카운트 업데이트 - 레코드 수:', count);
            
            let text = '';
            if (window.herI18n && window.herI18n.t) {
                text = window.herI18n.t('recordingsCount', { count });
            } else {
                text = `${count}개 녹음`;
            }
            
            if (this.memoCount) {
                this.memoCount.textContent = text;
                // console.log('[VoiceMemos] UI 카운트 업데이트:', text);
            }
            
            if (this.clearAllBtn) {
                this.clearAllBtn.style.display = 'none'; // legacy: 항상 숨김
            }
            if (this.manageBtn) {
                this.manageBtn.style.display = this.records.length > 0 ? 'inline-flex' : 'none';
            }
            // 선택 모드 중 카운트 갱신
            if (this.selectMode) this.updateSelectionUI();
        }

        renderRecords() {
            if (!this.memoList) return;

            // 빈 상태 처리
            if (!this.records || this.records.length === 0) {
                this.renderedCount = 0;
                this.memoList.innerHTML = '';
                this.memoList.appendChild(this.emptyState);
                this.showEmptyState();
                this.detachInfiniteScroll();
                return;
            }

            this.hideEmptyState();
            this.memoList.innerHTML = '';
            this.renderedCount = 0;

            // 선택 모드 클래스
            this.memoList.classList.toggle('select-mode', this.selectMode);

            // 첫 페이지 렌더
            this.renderMore();

            // 무한 스크롤 부착
            this.attachInfiniteScroll();
        }

        renderMore() {
            if (!this.memoList || this.isRenderingMore) return;
            if (this.renderedCount >= this.records.length) return;

            this.isRenderingMore = true;
            // 기존 로더 제거
            if (this.loadMoreEl && this.loadMoreEl.parentNode) {
                this.loadMoreEl.parentNode.removeChild(this.loadMoreEl);
            }

            const start = this.renderedCount;
            const end = Math.min(start + this.PAGE_SIZE, this.records.length);

            // DocumentFragment로 일괄 추가 (reflow 최소화)
            const frag = document.createDocumentFragment();
            for (let i = start; i < end; i++) {
                frag.appendChild(this.createRecordElement(this.records[i]));
            }
            this.memoList.appendChild(frag);
            this.renderedCount = end;

            // 더 남았으면 sentinel(로더) 추가
            if (this.renderedCount < this.records.length) {
                this.ensureLoadMoreEl();
                this.memoList.appendChild(this.loadMoreEl);
                // sentinel을 관찰
                if (this.loadMoreObserver) {
                    this.loadMoreObserver.disconnect();
                    this.loadMoreObserver.observe(this.loadMoreEl);
                }
            } else {
                // 모두 렌더됨 → observer 정리
                if (this.loadMoreObserver) this.loadMoreObserver.disconnect();
            }
            this.isRenderingMore = false;
        }

        ensureLoadMoreEl() {
            if (this.loadMoreEl) return;
            const el = document.createElement('div');
            el.className = 'load-more-indicator';
            el.id = 'loadMoreIndicator';
            const txt = (window.herI18n && window.herI18n.t) ? window.herI18n.t('loadingMore') : 'Loading more…';
            el.textContent = txt;
            this.loadMoreEl = el;
        }

        attachInfiniteScroll() {
            this.detachInfiniteScroll();
            if (!this.memoList) return;

            // IntersectionObserver: 스크롤 컨테이너에 의존하지 않음 (가장 robust)
            if ('IntersectionObserver' in window) {
                this.loadMoreObserver = new IntersectionObserver((entries) => {
                    for (const entry of entries) {
                        if (entry.isIntersecting && this.renderedCount < this.records.length) {
                            this.renderMore();
                        }
                    }
                }, { rootMargin: '300px 0px' });
                if (this.loadMoreEl) this.loadMoreObserver.observe(this.loadMoreEl);
            }

            // 폴백: 컨테이너/window 양쪽 스크롤 리스너
            this.scrollHandler = () => {
                if (this.renderedCount >= this.records.length) return;
                const fromList = this.memoList.scrollHeight > this.memoList.clientHeight
                    && this.memoList.scrollTop + this.memoList.clientHeight >= this.memoList.scrollHeight - 300;
                const fromWin = (window.innerHeight + window.scrollY) >= (document.documentElement.scrollHeight - 300);
                if (fromList || fromWin) this.renderMore();
            };
            this.memoList.addEventListener('scroll', this.scrollHandler, { passive: true });
            window.addEventListener('scroll', this.scrollHandler, { passive: true });
        }

        detachInfiniteScroll() {
            if (this.loadMoreObserver) {
                this.loadMoreObserver.disconnect();
                this.loadMoreObserver = null;
            }
            if (this.scrollHandler) {
                if (this.memoList) this.memoList.removeEventListener('scroll', this.scrollHandler);
                window.removeEventListener('scroll', this.scrollHandler);
                this.scrollHandler = null;
            }
        }

        createRecordElement(record) {
            const div = document.createElement('div');
            div.className = 'memo-item';
            div.dataset.id = record.id;
            if (this.selectedIds.has(record.id)) div.classList.add('selected');
            const domainDisplay = record.domain === 'Voice Memos' ? 'Voice Memos' : record.domain;
            // 시간 정보 치환 보장
            const timeStr = this.formatTime(record.timestamp);
            const checkedAttr = this.selectedIds.has(record.id) ? 'checked' : '';
            div.innerHTML = `
               <div class="memo-header">
                   <input type="checkbox" class="memo-checkbox" data-id="${record.id}" ${checkedAttr} data-her-extension="true" />
                   <div class="memo-meta">
                       <div class="memo-time">${timeStr}</div>
                       <div class="memo-domain">${domainDisplay}</div>
                   </div>
                   <div class="memo-actions">
                       <button class="action-btn copy-btn" data-id="${record.id}" data-her-extension="true">
                           ${this.getCopyIcon()}
                       </button>
                       <button class="action-btn delete-btn" data-id="${record.id}" data-her-extension="true">
                           ${this.getDeleteIcon()}
                       </button>
                   </div>
               </div>
               <div class="memo-content">${this.escapeHtml(record.text)}</div>
           `;
            div.querySelector('.copy-btn').addEventListener('click', () => {
                this.copyRecord(record);
            });
            div.querySelector('.delete-btn').addEventListener('click', () => {
                this.showDeleteConfirmModal(record);
            });
            const cb = div.querySelector('.memo-checkbox');
            cb.addEventListener('click', (e) => e.stopPropagation());
            cb.addEventListener('change', (e) => {
                this.toggleSelectOne(record.id, e.target.checked);
                div.classList.toggle('selected', e.target.checked);
            });
            // 선택 모드일 때 카드 클릭으로도 토글
            div.addEventListener('click', (e) => {
                if (!this.selectMode) return;
                if (e.target.closest('.memo-checkbox') || e.target.closest('.action-btn')) return;
                const newVal = !this.selectedIds.has(record.id);
                cb.checked = newVal;
                this.toggleSelectOne(record.id, newVal);
                div.classList.toggle('selected', newVal);
            });
            return div;
        }

        async copyRecord(record) {
            try {
                await navigator.clipboard.writeText(record.text);

                // Amplitude 이벤트 추가
                if (window.amplitude) {
                    window.amplitude.trackEvent('Memo Copied', {
                        source_domain: record.domain,
                        text_length: record.text.length
                    });
                }

                this.showNotification('copied');
            } catch (error) {
                console.error(window.herI18n.t('logVoiceMemosCopyFail'), error);
                this.showNotification('copyFailed');
            }
        }

        async copyToClipboard(text) {
            try {
                await navigator.clipboard.writeText(text);
                // console.log('[VoiceMemos] 클립보드 복사 성공:', text.length, '글자');

                // Amplitude 이벤트 추가
                if (window.amplitude) {
                    window.amplitude.trackEvent('Memo Auto Copied', {
                        source: 'voice_memos',
                        text_length: text.length
                    });
                }

                this.showNotification('copied');
            } catch (error) {
                console.error('[VoiceMemos] 클립보드 복사 실패:', error);
                this.showNotification('copyFailed');
            }
        }

        async deleteRecord(recordId) {
            try {
                // 레코드 정보 저장 (삭제 전)
                const recordToDelete = this.records.find(r => r.id === recordId);

                // Storage에서 먼저 제거
                await chrome.storage.local.set({
                    voiceRecords: this.records.filter(r => r.id !== recordId)
                });

                // 로컬에서도 제거하고 UI 업데이트
                this.records = this.records.filter(r => r.id !== recordId);
                this.updateUI();

                // Amplitude 이벤트 추가
                if (window.amplitude && recordToDelete) {
                    const memo_age_days = (new Date() - new Date(recordToDelete.timestamp)) / (1000 * 60 * 60 * 24);
                    window.amplitude.trackEvent('Memo Deleted', {
                        source_domain: recordToDelete.domain,
                        memo_age_days: Math.floor(memo_age_days)
                    });
                }

                this.showNotification('deleted');
            } catch (error) {
                console.error(window.herI18n.t('logVoiceMemosDeleteFail'), error);
                // 실패 시 원복
                await this.loadRecords();
                this.updateUI();
                this.showNotification('deleteFailed');
            }
        }

        async clearAllRecords() {
            try {
                const deletedCount = this.records.length;

                // Storage 삭제
                await chrome.storage.local.set({ voiceRecords: [] });

                // 상태 초기화
                this.records = [];
                this.totalCount = 0;
                this.loadedCount = 0;

                // UI 갱신
                this.updateUIAfterClear();

                // Analytics
                if (window.amplitude) {
                    window.amplitude.trackEvent('All Memos Deleted', {
                        deleted_count: deletedCount
                    });
                }

                this.showNotification('allCleared');
                return true;
            } catch (error) {
                console.error('전체 삭제 실패:', error);
                this.showNotification('clearFailed');
                return false;
            }
        }

        updateUIAfterClear() {
            this.renderedCount = 0;
            this.detachInfiniteScroll();
            this.selectedIds.clear();
            if (this.selectMode) this.exitSelectMode();
            if (this.memoList) {
                this.memoList.innerHTML = '';
                if (this.emptyState) this.memoList.appendChild(this.emptyState);
            }
            if (this.memoCount) this.memoCount.textContent = '0개 녹음';
            if (this.clearAllBtn) this.clearAllBtn.style.display = 'none';
            if (this.manageBtn) this.manageBtn.style.display = 'none';
            if (this.emptyState) this.emptyState.style.display = 'block';
        }

        showEmptyState() {
            if (this.emptyState) {
                this.emptyState.style.display = 'block';
            }
        }

        hideEmptyState() {
            if (this.emptyState) {
                this.emptyState.style.display = 'none';
            }
        }

        showConfirmModal() {
            const modal = document.getElementById('confirmModal');
            if (modal) {
                modal.classList.add('show');

                const confirmBtn = document.getElementById('confirmBtn');
                const cancelBtn = document.getElementById('cancelBtn');

                const handleConfirm = async () => {
                    modal.classList.remove('show');
                    await this.clearAllRecords();
                    confirmBtn.removeEventListener('click', handleConfirm);
                    cancelBtn.removeEventListener('click', handleCancel);
                };

                const handleCancel = () => {
                    modal.classList.remove('show');
                    confirmBtn.removeEventListener('click', handleConfirm);
                    cancelBtn.removeEventListener('click', handleCancel);
                };

                confirmBtn.addEventListener('click', handleConfirm);
                cancelBtn.addEventListener('click', handleCancel);
            }
        }

        showNotification(key, isUserNotice = true, params = null) {
            // console.log(`[VoiceMemos] 🔔 showNotification 호출:`, { key, isUserNotice });

            try {
                // 로그성 메시지는 콘솔에만, 사용자 알림만 토스트로
                const message = window.herI18n ? window.herI18n.t(key, params || undefined) : key;
                // console.log(`[VoiceMemos] 📝 번역된 메시지:`, message);

                // 로그 메시지 키 패턴: logVoiceMemos, logPopup, logMicButton, logSTT 등은 토스트 X
                const isLog = /^log(V|P|M|S)/.test(key);
                if (isLog && !isUserNotice) {
                    // console.log(`[VoiceMemos] 📋 로그 메시지이므로 콘솔에만 출력:`, message);
                    return;
                }

                // console.log(`[VoiceMemos] 🎨 토스트 메시지 생성 중...`);

                // 사용자 알림만 토스트로
                const notification = document.createElement('div');
                notification.style.cssText = `
                   position: fixed;
                   bottom: 20px;
                   left: 50%;
                   transform: translateX(-50%);
                   background: linear-gradient(135deg, #ff6b6b, #ff8e8e);
                   color: white;
                   padding: 16px 20px;
                   border-radius: 12px;
                   font-size: 14px;
                   font-weight: 500;
                   z-index: 2147483647;
                   pointer-events: none;
                   max-width: 90vw;
                   word-wrap: break-word;
                   box-shadow: 0 8px 32px rgba(255, 107, 107, 0.3);
                   border: 1px solid rgba(255, 255, 255, 0.2);
                   backdrop-filter: blur(10px);
                   animation: slideInFromBottom 0.3s ease-out;
                `;

                // 애니메이션 스타일 추가
                const style = document.createElement('style');
                style.textContent = `
                    @keyframes slideInFromBottom {
                        from {
                            transform: translate(-50%, 100%);
                            opacity: 0;
                        }
                        to {
                            transform: translate(-50%, 0);
                            opacity: 1;
                        }
                    }
                `;
                if (!document.querySelector('#voice-memos-toast-style')) {
                    style.id = 'voice-memos-toast-style';
                    document.head.appendChild(style);
                }

                notification.textContent = message;
                // console.log(`[VoiceMemos] 📱 DOM에 토스트 추가 중...`);
                document.body.appendChild(notification);
                // console.log(`[VoiceMemos] ✅ 토스트 DOM 추가 완료`);

                // 4초 후 자동 제거 (동시 녹음 알림은 더 오래 표시)
                const duration = key.includes('concurrent') ? 5000 : 2000;
                // console.log(`[VoiceMemos] ⏰ ${duration}ms 후 토스트 제거 예약`);

                setTimeout(() => {
                    // console.log(`[VoiceMemos] 🗑️ 토스트 제거 시작`);
                    if (notification.parentNode) {
                        notification.style.animation = 'slideInFromBottom 0.3s ease-out reverse';
                        setTimeout(() => {
                            if (notification.parentNode) {
                                notification.parentNode.removeChild(notification);
                                // console.log(`[VoiceMemos] ✅ 토스트 제거 완료`);
                            }
                        }, 300);
                    }
                }, duration);

                // console.log(`[VoiceMemos] 🎉 토스트 알림 표시 성공`);

            } catch (error) {
                console.error(`[VoiceMemos] ❌ showNotification 에러:`, error);

                // 에러 발생 시 폴백 알림
                try {
                    const fallbackMessage = window.herI18n ? window.herI18n.t(key) : key;
                    // console.log(`[VoiceMemos] 📢 폴백 알림 시도: ${fallbackMessage}`);

                    // 간단한 폴백 토스트
                    const fallbackToast = document.createElement('div');
                    fallbackToast.style.cssText = `
                        position: fixed;
                        top: 20px;
                        right: 20px;
                        background: #333;
                        color: white;
                        padding: 12px 16px;
                        border-radius: 8px;
                        z-index: 2147483647;
                        font-size: 14px;
                    `;
                    fallbackToast.textContent = fallbackMessage;
                    document.body.appendChild(fallbackToast);

                    setTimeout(() => {
                        if (fallbackToast.parentNode) {
                            fallbackToast.remove();
                        }
                    }, 3000);

                    // console.log(`[VoiceMemos] ✅ 폴백 알림 표시 완료`);
                } catch (fallbackError) {
                    console.error(`[VoiceMemos] ❌ 폴백 알림도 실패:`, fallbackError);
                    // 최후 수단 - 브라우저 alert
                    setTimeout(() => alert(key), 100);
                }
            }
        }

        formatTime(timestamp) {
            if (window.herI18n && window.herI18n.formatTime) {
                return window.herI18n.formatTime(timestamp);
            }
            // 폴백 처리
            const date = new Date(timestamp);
            const now = new Date();
            const diff = now.getTime() - date.getTime();
            const minutes = Math.floor(diff / 60000);

            if (minutes < 1) {
                return 'Just now';
            } else if (minutes < 60) {
                return `${minutes}m ago`;
            } else {
                return `${Math.floor(minutes / 60)}h ago`;
            }
        }

        getCopyIcon() {
            if (!window.herSVGIcons) throw new Error(window.herI18n.t('logVoiceMemosHerSVGIconsNotLoaded'));
            return window.herSVGIcons.getCopyIcon();
        }

        getDeleteIcon() {
            if (!window.herSVGIcons) throw new Error(window.herI18n.t('logVoiceMemosHerSVGIconsNotLoaded'));
            return window.herSVGIcons.getDeleteIcon();
        }

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

        showDeleteConfirmModal(record) {
            const modal = document.getElementById('confirmModal');
            if (modal) {
                const title = modal.querySelector('.modal-title');
                const text = modal.querySelector('.modal-text');
                const confirmBtn = document.getElementById('confirmBtn');
                const cancelBtn = document.getElementById('cancelBtn');
                title.textContent = window.herI18n ? window.herI18n.t('confirmDeleteMemoTitle') : 'Delete Memo';
                const preview = record.text.length > 50 ? record.text.substring(0, 50) + '...' : record.text;
                text.textContent = `"${preview}"을(를) 삭제하시겠습니까?`;
                confirmBtn.textContent = window.herI18n ? window.herI18n.t('deleteButton') : 'Delete';
                modal.classList.add('show');
                const handleConfirm = () => {
                    this.deleteRecord(record.id);
                    modal.classList.remove('show');
                    confirmBtn.removeEventListener('click', handleConfirm);
                    cancelBtn.removeEventListener('click', handleCancel);
                };
                const handleCancel = () => {
                    modal.classList.remove('show');
                    confirmBtn.removeEventListener('click', handleConfirm);
                    cancelBtn.removeEventListener('click', handleCancel);
                };
                confirmBtn.addEventListener('click', handleConfirm);
                cancelBtn.addEventListener('click', handleCancel);
            }
        }

        addActionButtons(cardElement, recordId) {
            const header = cardElement.querySelector('.memo-header .memo-meta');
            if (header && !cardElement.querySelector('.memo-actions')) {
                const actionsDiv = document.createElement('div');
                actionsDiv.className = 'memo-actions';
                actionsDiv.innerHTML = `
                    <button class="action-btn copy-btn" data-id="${recordId}" data-her-extension="true">
                        ${this.getCopyIcon()}
                    </button>
                    <button class="action-btn delete-btn" data-id="${recordId}" data-her-extension="true">
                        ${this.getDeleteIcon()}
                    </button>
                `;
                header.parentElement.appendChild(actionsDiv);
                actionsDiv.querySelector('.copy-btn').addEventListener('click', () => {
                    const record = this.records.find(r => r.id === recordId);
                    if (record) this.copyRecord(record);
                });
                actionsDiv.querySelector('.delete-btn').addEventListener('click', () => {
                    const record = this.records.find(r => r.id === recordId);
                    if (record) this.showDeleteConfirmModal(record);
                });
            }
        }

        // 차단 알림 단순화
        showBlockingNotification(blockingContext) {
            let message = '다른 곳에서 이미 녹음 중입니다.';

            if (blockingContext === 'voice-memos') {
                message = 'Voice Memos에서 이미 녹음 중입니다.';
            } else if (blockingContext === 'content') {
                message = '웹페이지에서 이미 녹음 중입니다.';
            }

            // 간단한 토스트만 표시
            this.showSimpleToast(message);
        }

        showSimpleToast(message) {
            const toast = document.createElement('div');
            toast.style.cssText = `
                position: fixed; top: 20px; right: 20px;
                background: #ff4444; color: white; padding: 12px 16px;
                border-radius: 8px; z-index: 2147483647; font-size: 14px;
            `;
            toast.textContent = message;
            document.body.appendChild(toast);

            setTimeout(() => toast.remove(), 3000);
        }

        // ────────────────────────────────────────────────
        // 🆕 관리 풀다운
        // ────────────────────────────────────────────────
        toggleManagePopover() {
            if (!this.managePopover) return;
            const willOpen = !this.managePopover.classList.contains('open');
            this.managePopover.classList.toggle('open', willOpen);
            if (this.manageBtn) this.manageBtn.setAttribute('aria-expanded', String(willOpen));
        }

        closeManagePopover() {
            if (!this.managePopover) return;
            this.managePopover.classList.remove('open');
            if (this.manageBtn) this.manageBtn.setAttribute('aria-expanded', 'false');
        }

        // ────────────────────────────────────────────────
        // 🆕 선택 모드
        // ────────────────────────────────────────────────
        enterSelectMode() {
            this.selectMode = true;
            this.selectedIds.clear();
            if (this.selectionBar) this.selectionBar.classList.add('show');
            this.updateSelectionUI();
            this.renderRecords();
        }

        exitSelectMode() {
            this.selectMode = false;
            this.selectedIds.clear();
            if (this.selectionBar) this.selectionBar.classList.remove('show');
            this.renderRecords();
        }

        toggleSelectOne(id, checked) {
            if (checked) this.selectedIds.add(id);
            else this.selectedIds.delete(id);
            this.updateSelectionUI();
        }

        toggleSelectAll() {
            const allSelected = this.selectedIds.size === this.records.length;
            this.selectedIds.clear();
            if (!allSelected) {
                this.records.forEach(r => this.selectedIds.add(r.id));
            }
            // 보이는 체크박스 & 카드 상태 동기화
            const items = this.memoList ? this.memoList.querySelectorAll('.memo-item') : [];
            items.forEach(el => {
                const id = el.dataset.id;
                const isSel = this.selectedIds.has(id);
                el.classList.toggle('selected', isSel);
                const cb = el.querySelector('.memo-checkbox');
                if (cb) cb.checked = isSel;
            });
            this.updateSelectionUI();
        }

        updateSelectionUI() {
            const count = this.selectedIds.size;
            if (this.selectionInfo) {
                const txt = (window.herI18n && window.herI18n.t)
                    ? window.herI18n.t('selectedCount', { count })
                    : `${count} selected`;
                this.selectionInfo.textContent = txt;
            }
            if (this.exportSelectedBtn) this.exportSelectedBtn.disabled = count === 0;
            if (this.deleteSelectedBtn) this.deleteSelectedBtn.disabled = count === 0;
            if (this.selectAllBtn) {
                const allSelected = count > 0 && count === this.records.length;
                const key = allSelected ? 'deselectAll' : 'selectAll';
                const txt = (window.herI18n && window.herI18n.t) ? window.herI18n.t(key) : (allSelected ? 'Deselect All' : 'Select All');
                this.selectAllBtn.textContent = txt;
            }
        }

        // ────────────────────────────────────────────────
        // 🆕 내보내기
        // ────────────────────────────────────────────────
        exportRecords(items) {
            try {
                if (!items || items.length === 0) {
                    this.showNotification('importEmpty');
                    return;
                }
                const payload = {
                    type: 'her-voice-memos',
                    version: 1,
                    exportedAt: new Date().toISOString(),
                    count: items.length,
                    records: items
                };
                const json = JSON.stringify(payload, null, 2);
                const blob = new Blob([json], { type: 'application/json' });
                const url = URL.createObjectURL(blob);

                const now = new Date();
                const pad = n => String(n).padStart(2, '0');
                const stamp = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}_${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
                const filename = `her-voice-memos_${stamp}_${items.length}.json`;

                const a = document.createElement('a');
                a.href = url;
                a.download = filename;
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                setTimeout(() => URL.revokeObjectURL(url), 1000);

                if (window.amplitude) {
                    window.amplitude.trackEvent('Memos Exported', {
                        exported_count: items.length,
                        is_selection: items.length !== this.records.length
                    });
                }

                this.showNotification('exportSuccess', true, { count: items.length });
            } catch (error) {
                console.error('[VoiceMemos] 내보내기 실패:', error);
                this.showNotification('exportFailed');
            }
        }

        // ────────────────────────────────────────────────
        // 🆕 가져오기
        // ────────────────────────────────────────────────
        async handleImportFile(file) {
            try {
                const text = await file.text();
                let parsed;
                try {
                    parsed = JSON.parse(text);
                } catch {
                    this.showNotification('importInvalidFile');
                    return;
                }

                // 다양한 형태 허용: { records: [...] } 또는 [...]
                let incoming = null;
                if (Array.isArray(parsed)) {
                    incoming = parsed;
                } else if (parsed && Array.isArray(parsed.records)) {
                    incoming = parsed.records;
                } else {
                    this.showNotification('importInvalidFile');
                    return;
                }

                // 유효성 검증 + 정규화
                const valid = incoming
                    .filter(r => r && typeof r === 'object' && typeof r.text === 'string' && r.text.trim().length > 0)
                    .map(r => ({
                        id: r.id || `imported-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
                        text: r.text,
                        timestamp: r.timestamp || new Date().toISOString(),
                        domain: r.domain || 'Imported'
                    }));

                if (valid.length === 0) {
                    this.showNotification('importEmpty');
                    return;
                }

                // 기존 ID와 중복 제거
                const existingIds = new Set(this.records.map(r => r.id));
                const deduped = valid.filter(r => !existingIds.has(r.id));

                // 병합 (가져온 항목을 앞에 둠 → 최신 정렬)
                const merged = [...deduped, ...this.records];

                // 타임스탬프 기준 정렬 (최신 우선)
                merged.sort((a, b) => {
                    const ta = new Date(a.timestamp).getTime() || 0;
                    const tb = new Date(b.timestamp).getTime() || 0;
                    return tb - ta;
                });

                await chrome.storage.local.set({ voiceRecords: merged });
                this.records = merged;
                this.totalCount = merged.length;
                this.loadedCount = merged.length;
                this.updateUI();

                if (window.amplitude) {
                    window.amplitude.trackEvent('Memos Imported', {
                        imported_count: deduped.length,
                        skipped_duplicates: valid.length - deduped.length
                    });
                }

                this.showNotification('importSuccess', true, { count: deduped.length });
            } catch (error) {
                console.error('[VoiceMemos] 가져오기 실패:', error);
                this.showNotification('importFailed');
            }
        }

        // ────────────────────────────────────────────────
        // 🆕 선택 삭제 확인 모달
        // ────────────────────────────────────────────────
        showConfirmDeleteSelectedModal() {
            const count = this.selectedIds.size;
            if (count === 0) { this.showNotification('noMemosSelected'); return; }
            const modal = document.getElementById('confirmModal');
            if (!modal) return;
            const title = modal.querySelector('.modal-title');
            const text = modal.querySelector('.modal-text');
            const confirmBtn = document.getElementById('confirmBtn');
            const cancelBtn = document.getElementById('cancelBtn');
            const i18n = window.herI18n;
            title.textContent = i18n ? i18n.t('confirmDeleteSelectedTitle') : 'Delete Selected Memos';
            text.textContent = i18n ? i18n.t('confirmDeleteSelectedText', { count }) : `Delete ${count} selected memos? This can't be undone.`;
            confirmBtn.textContent = i18n ? i18n.t('deleteButton') : 'Delete';
            modal.classList.add('show');

            const handleConfirm = async () => {
                modal.classList.remove('show');
                await this.deleteSelectedRecords();
                cleanup();
            };
            const handleCancel = () => {
                modal.classList.remove('show');
                cleanup();
            };
            const cleanup = () => {
                confirmBtn.removeEventListener('click', handleConfirm);
                cancelBtn.removeEventListener('click', handleCancel);
            };
            confirmBtn.addEventListener('click', handleConfirm);
            cancelBtn.addEventListener('click', handleCancel);
        }

        async deleteSelectedRecords() {
            try {
                const ids = this.selectedIds;
                const remaining = this.records.filter(r => !ids.has(r.id));
                const deletedCount = this.records.length - remaining.length;
                await chrome.storage.local.set({ voiceRecords: remaining });
                this.records = remaining;
                this.totalCount = remaining.length;
                this.loadedCount = remaining.length;
                this.selectedIds.clear();
                this.updateSelectionUI();
                this.updateUI();
                if (window.amplitude) {
                    window.amplitude.trackEvent('Selected Memos Deleted', { deleted_count: deletedCount });
                }
                this.showNotification('deleted');
            } catch (error) {
                console.error('[VoiceMemos] 선택 삭제 실패:', error);
                this.showNotification('deleteFailed');
            }
        }
    }

    // 초기화
    window.HerVoiceMemos = HerVoiceMemos;

    // DOM이 준비되면 초기화
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => {
            new HerVoiceMemos();
        });
    } else {
        // 이미 로드된 경우 즉시 초기화
        new HerVoiceMemos();
    }
})();