<?php
// 출력 버퍼링 시작 (경고 메시지 방지)
ob_start();
@error_reporting(0);
@ini_set('display_errors', 0);

require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
@require_once($_SERVER['DOCUMENT_ROOT'] . "/load_header.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");

// 권한 체크
if ($level > 5) {
    echo "<script>alert('접근 권한이 없습니다.'); history.back();</script>";
    exit;
}

// 업무협의록 리스트 조회 (최근 10개)
$tenant_id = $user_id; // session.php에서 user_id를 tenant_id로 사용
$consult_list = [];
try {
    $pdo = db_connect();
    if (!$pdo) {
        error_log('업무협의록 조회 실패: DB 연결 실패');
    } else {
        // MVP 단계: 모든 사용자가 모든 데이터를 볼 수 있도록 tenant_id 조건 제거
        $sql = "SELECT id, title, created_at, summary_text, audio_file_path 
                FROM consult_logs 
                ORDER BY created_at DESC 
                LIMIT 10";
        $stmt = $pdo->prepare($sql);
        if (!$stmt) {
            error_log('업무협의록 조회 실패: SQL 준비 실패 - ' . print_r($pdo->errorInfo(), true));
        } else {
            $executeResult = $stmt->execute();
            if (!$executeResult) {
                error_log('업무협의록 조회 실패: SQL 실행 실패 - ' . print_r($stmt->errorInfo(), true));
            } else {
                $consult_list = $stmt->fetchAll(PDO::FETCH_ASSOC);
                error_log('업무협의록 조회 성공: ' . count($consult_list) . '개 조회됨 (모든 사용자 공개)');
            }
        }
    }
} catch (Exception $e) {
    // DB 조회 실패 시 빈 배열
    error_log('업무협의록 조회 예외 발생: ' . $e->getMessage());
    $consult_list = [];
}
?>

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>AI 스마트 업무협의록 (SAM Project)</title>
    <style>
        * {
            box-sizing: border-box;
        }

        body {
            overflow-x: hidden; /* 가로 스크롤 방지 */
            width: 100%;
        }

        .voice-container {
            max-width: 900px;
            margin: 40px auto;
            padding: 30px;
            width: 100%; /* 모바일 대응 */
        }

        .header-section {
            text-align: center;
            margin-bottom: 40px;
        }

        .header-section h3 {
            margin-bottom: 10px;
            color: #333;
        }

        .header-section p {
            color: #6c757d;
            font-size: 14px;
        }

        .recording-section {
            background: #fff;
            border-radius: 12px;
            padding: 40px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            margin-bottom: 30px;
        }

        .record-controls {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 20px;
        }

        .record-button {
            width: 120px;
            height: 120px;
            border-radius: 50%;
            border: none;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            font-size: 24px;
            cursor: pointer;
            transition: all 0.3s ease;
            box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
            position: relative;
            overflow: hidden;
        }

        .record-button:hover {
            transform: scale(1.05);
            box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6);
        }

        .record-button.recording {
            background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
            animation: pulse 1.5s ease-in-out infinite;
        }

        @keyframes pulse {
            0%, 100% {
                box-shadow: 0 4px 15px rgba(245, 87, 108, 0.4);
            }
            50% {
                box-shadow: 0 4px 30px rgba(245, 87, 108, 0.8);
            }
        }

        .timer {
            font-size: 32px;
            font-weight: bold;
            color: #333;
            font-family: 'Courier New', monospace;
            min-height: 40px;
        }

        .timer.active {
            color: #f5576c;
        }

        .status-indicator {
            display: inline-block;
            padding: 8px 20px;
            border-radius: 20px;
            font-size: 14px;
            font-weight: bold;
        }

        .status-waiting {
            background: #e9ecef;
            color: #495057;
        }

        .status-recording {
            background: #f8d7da;
            color: #842029;
        }

        .status-processing {
            background: #cfe2ff;
            color: #084298;
        }

        .status-completed {
            background: #d1e7dd;
            color: #0f5132;
        }

        .status-error {
            background: #f8d7da;
            color: #842029;
        }

        .waveform-container {
            width: 100%;
            height: 100px;
            background: #f8f9fa;
            border-radius: 8px;
            margin: 20px 0;
            position: relative;
            overflow: hidden;
        }

        .waveform-canvas {
            width: 100%;
            height: 100%;
        }

        .transcript-section {
            background: #fff;
            border-radius: 12px;
            padding: 30px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            margin-bottom: 30px;
            min-height: 200px;
        }

        .transcript-section h5 {
            margin-bottom: 15px;
            color: #333;
        }

        .transcript-text {
            background: #f8f9fa;
            border: 1px solid #dee2e6;
            border-radius: 8px;
            padding: 20px;
            min-height: 150px;
            font-size: 16px;
            line-height: 1.8;
            color: #333;
            white-space: pre-wrap;
            word-wrap: break-word;
        }

        .transcript-text.empty {
            color: #999;
            font-style: italic;
        }

        .action-buttons {
            display: flex;
            gap: 10px;
            margin-top: 20px;
        }

        .btn {
            padding: 12px 24px;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            font-size: 14px;
            font-weight: bold;
            transition: all 0.3s ease;
        }

        .btn-primary {
            background: #0d6efd;
            color: white;
        }

        .btn-primary:hover {
            background: #0b5ed7;
        }

        .btn-secondary {
            background: #6c757d;
            color: white;
        }

        .btn-secondary:hover {
            background: #5c636a;
        }

        .btn-success {
            background: #198754;
            color: white;
        }

        .btn-success:hover {
            background: #157347;
        }

        .btn:disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }

        .info-box {
            background: #e7f3ff;
            border-left: 4px solid #0d6efd;
            padding: 15px;
            margin-bottom: 20px;
            border-radius: 4px;
        }

        .info-box p {
            margin: 5px 0;
            color: #084298;
            font-size: 13px;
        }

        .loading-spinner {
            display: inline-block;
            width: 20px;
            height: 20px;
            border: 3px solid rgba(255,255,255,0.3);
            border-radius: 50%;
            border-top-color: #fff;
            animation: spin 1s linear infinite;
            margin-left: 10px;
        }

        @keyframes spin {
            to { transform: rotate(360deg); }
        }

        .processing-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0,0,0,0.7);
            color: white;
            display: none;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            z-index: 1000;
        }

        .spinner-border {
            width: 3rem;
            height: 3rem;
            border: 0.25em solid currentColor;
            border-right-color: transparent;
            border-radius: 50%;
            animation: spin 0.75s linear infinite;
        }

        /* 업무협의록 테이블 스타일 */
        .meeting-table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 10px;
        }

        .meeting-table th {
            background: #f8f9fa;
            padding: 12px;
            text-align: left;
            border-bottom: 2px solid #dee2e6;
            font-weight: bold;
            color: #495057;
        }

        .meeting-table td {
            padding: 12px;
            border-bottom: 1px solid #dee2e6;
        }

        .meeting-table tr:hover {
            background: #f8f9fa;
        }

        .summary-preview {
            max-width: 300px;
            color: #6c757d;
            font-size: 13px;
        }

        .btn-small {
            padding: 8px;
            font-size: 16px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            margin-right: 5px;
            background: #6c757d;
            color: white;
            text-decoration: none;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            width: 36px;
            height: 36px;
            position: relative;
        }

        .btn-small:hover {
            background: #5c636a;
        }

        .btn-small i {
            margin: 0;
        }

        /* 툴팁 스타일 */
        .btn-small[title] {
            position: relative;
        }

        .btn-small[title]:hover::after {
            content: attr(title);
            position: absolute;
            bottom: calc(100% + 8px);
            left: 50%;
            transform: translateX(-50%);
            padding: 6px 10px;
            background: #333;
            color: white;
            font-size: 12px;
            white-space: nowrap;
            border-radius: 4px;
            z-index: 1000;
            pointer-events: none;
            opacity: 0;
            animation: tooltipFadeIn 0.2s ease-in-out forwards;
            box-shadow: 0 2px 8px rgba(0,0,0,0.2);
        }

        .btn-small[title]:hover::before {
            content: '';
            position: absolute;
            bottom: calc(100% + 3px);
            left: 50%;
            transform: translateX(-50%);
            border: 5px solid transparent;
            border-top-color: #333;
            z-index: 1001;
            pointer-events: none;
            opacity: 0;
            animation: tooltipFadeIn 0.2s ease-in-out forwards;
        }

        @keyframes tooltipFadeIn {
            from {
                opacity: 0;
                transform: translateX(-50%) translateY(-5px);
            }
            to {
                opacity: 1;
                transform: translateX(-50%) translateY(0);
            }
        }

        /* 모달 스타일 */
        .modal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0,0,0,0.7);
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 2000;
        }

        .modal-content {
            background: white;
            border-radius: 12px;
            padding: 30px;
            max-width: 800px;
            width: 90%;
            max-height: 80vh;
            overflow-y: auto;
            position: relative;
        }

        .close-btn {
            position: absolute;
            top: 15px;
            right: 20px;
            font-size: 28px;
            font-weight: bold;
            color: #999;
            cursor: pointer;
        }

        .close-btn:hover {
            color: #333;
        }

        .modal-body {
            margin-top: 20px;
        }

        .detail-section {
            margin-bottom: 25px;
        }

        .detail-section h6 {
            margin-bottom: 10px;
            color: #495057;
            font-size: 14px;
        }

        .detail-text {
            background: #f8f9fa;
            border: 1px solid #dee2e6;
            border-radius: 8px;
            padding: 15px;
            line-height: 1.8;
            white-space: pre-wrap;
            word-wrap: break-word;
        }

        /* 모바일 햄버거 메뉴 스타일 */
        .mobile-menu-toggle {
            display: none;
            position: fixed;
            top: 15px;
            right: 15px;
            z-index: 1001;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            border-radius: 8px;
            width: 48px;
            height: 48px;
            font-size: 24px;
            cursor: pointer;
            box-shadow: 0 2px 10px rgba(0,0,0,0.2);
            transition: all 0.3s ease;
            align-items: center;
            justify-content: center;
        }

        .mobile-menu-toggle:hover {
            transform: scale(1.05);
            box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
        }

        .mobile-menu-overlay {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            z-index: 999;
            opacity: 0;
            transition: opacity 0.3s ease;
        }

        .mobile-menu-overlay.active {
            opacity: 1;
        }

        .mobile-menu-sidebar {
            position: fixed;
            top: 0;
            right: -100%;
            width: 280px;
            max-width: 85%;
            height: 100%;
            background: white;
            z-index: 1000;
            overflow-y: auto;
            transition: right 0.3s ease;
            box-shadow: -2px 0 10px rgba(0,0,0,0.1);
        }

        .mobile-menu-sidebar.active {
            right: 0;
        }

        .mobile-menu-header {
            padding: 20px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .mobile-menu-header h4 {
            margin: 0;
            font-size: 18px;
        }

        .mobile-menu-close {
            background: none;
            border: none;
            color: white;
            font-size: 28px;
            cursor: pointer;
            padding: 0;
            width: 32px;
            height: 32px;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .mobile-menu-content {
            padding: 20px 0;
        }

        .mobile-menu-content .navbar-nav {
            flex-direction: column;
        }

        .mobile-menu-content .nav-item {
            width: 100%;
            margin: 0;
            border-bottom: 1px solid #e9ecef;
        }

        .mobile-menu-content .nav-link {
            padding: 15px 20px;
            color: #333;
            display: flex;
            align-items: center;
            gap: 10px;
            font-size: 15px;
        }

        .mobile-menu-content .nav-link:hover {
            background: #f8f9fa;
            color: #667eea;
        }

        /* 모바일 반응형 스타일 */
        @media (max-width: 768px) {
            .navbar-custom {
                display: none !important;
            }

            .mobile-menu-toggle {
                display: flex;
            }

            .voice-container {
                margin-top: 70px;
                max-width: 100%;
                padding: 15px;
                width: 100%;
            }

            .recording-section, .transcript-section {
                padding: 20px;
            }

            .record-button {
                width: 100px;
                height: 100px;
                font-size: 20px;
            }

            .transcript-text {
                font-size: 14px;
                padding: 15px;
            }
            
            .header-section h3 {
                font-size: 24px;
            }

            .record-button {
                width: 100px;
                height: 100px;
                font-size: 20px;
            }

            .action-buttons {
                flex-direction: column;
                gap: 8px;
            }

            .btn {
                width: 100%;
                min-height: 48px;
            }
        }

        @media (max-width: 480px) {
            .voice-container {
                padding: 10px;
            }

            .record-button {
                width: 90px;
                height: 90px;
                font-size: 18px;
            }

            .timer {
                font-size: 24px;
            }
        }

        @media (max-width: 360px) {
            .voice-container {
                padding: 8px;
            }

            .record-button {
                width: 80px;
                height: 80px;
                font-size: 16px;
            }
        }

        /* 디버그 패널 스타일 */
        .debug-panel {
            position: fixed;
            bottom: 20px;
            right: 20px;
            width: 350px;
            max-width: calc(100% - 40px);
            max-height: 400px;
            background: #1e1e1e;
            border: 2px solid #667eea;
            border-radius: 8px;
            box-shadow: 0 4px 20px rgba(0,0,0,0.3);
            z-index: 100000;
            display: none !important;
            flex-direction: column;
            font-family: 'Courier New', monospace;
            font-size: 12px;
            pointer-events: auto;
            opacity: 0;
            transform: translateY(20px);
            transition: opacity 0.3s ease, transform 0.3s ease;
        }

        .debug-panel.active {
            display: flex !important;
            opacity: 1;
            transform: translateY(0);
        }

        .debug-panel-header {
            background: #667eea;
            color: white;
            padding: 10px 15px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            border-radius: 6px 6px 0 0;
        }

        .debug-panel-title {
            font-weight: bold;
            font-size: 14px;
        }

        .debug-panel-controls {
            display: flex;
            gap: 8px;
        }

        .debug-panel-btn {
            background: rgba(255,255,255,0.2);
            border: none;
            color: white;
            width: 24px;
            height: 24px;
            border-radius: 4px;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 12px;
        }

        .debug-panel-content {
            flex: 1;
            overflow-y: auto;
            padding: 10px;
            color: #d4d4d4;
            background: #1e1e1e;
        }

        .debug-log {
            margin: 4px 0;
            padding: 4px 8px;
            border-left: 3px solid #667eea;
            word-break: break-word;
            line-height: 1.4;
        }

        .debug-log.log { border-left-color: #4ec9b0; }
        .debug-log.info { border-left-color: #4fc3f7; }
        .debug-log.warn { border-left-color: #ffa726; color: #ffa726; }
        .debug-log.error { border-left-color: #f44336; color: #ff6b6b; }

        .debug-toggle-btn {
            position: fixed;
            bottom: 20px;
            right: 20px;
            width: 50px;
            height: 50px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            border-radius: 50%;
            box-shadow: 0 2px 10px rgba(0,0,0,0.3);
            cursor: pointer;
            z-index: 99999;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 20px;
            pointer-events: auto;
            touch-action: manipulation;
        }

        .debug-toggle-btn:hover {
            transform: scale(1.1);
        }

        .debug-toggle-btn:active {
            transform: scale(0.95);
        }

        .debug-toggle-btn.active {
            background: #f44336;
        }

        @media (max-width: 768px) {
            .debug-panel {
                width: calc(100% - 20px);
                max-width: calc(100% - 20px);
                bottom: 10px;
                right: 10px;
                max-height: 50vh;
            }

            .debug-toggle-btn {
                bottom: 10px;
                right: 10px;
                width: 44px;
                height: 44px;
                font-size: 18px;
            }
        }
    </style>
    <script>
        // 즉시 실행: 전자결재 다이얼로그 강제 닫기
        (function() {
            function closeEworksDialogs() {
                // 모든 전자결재 관련 모달 닫기
                const modals = ['eworks_viewmodal', 'eworks_form'];
                modals.forEach(function(modalId) {
                    const modal = document.getElementById(modalId);
                    if (modal) {
                        modal.style.display = 'none';
                        modal.classList.remove('show');
                        modal.setAttribute('aria-hidden', 'true');
                    }
                });
                
                // 모든 모달 배경 제거
                const backdrops = document.querySelectorAll('.modal-backdrop');
                backdrops.forEach(function(backdrop) {
                    backdrop.remove();
                });
                
                // body 클래스 정리
                document.body.classList.remove('modal-open');
                document.body.style.overflow = '';
                document.body.style.paddingRight = '';
            }
            
            // 즉시 실행
            if (document.readyState === 'loading') {
                document.addEventListener('DOMContentLoaded', closeEworksDialogs);
            } else {
                closeEworksDialogs();
            }
            
            // 지속적으로 확인 (다이얼로그가 나중에 열리는 경우 대비)
            setInterval(closeEworksDialogs, 500);
        })();
    </script>
</head>
<body>

<?php include $_SERVER['DOCUMENT_ROOT'] . "/myheader.php"; ?>

<!-- 모바일 햄버거 메뉴 -->
<button class="mobile-menu-toggle" id="mobile-menu-toggle" aria-label="메뉴 열기">
    <i class="bi bi-list"></i>
</button>

<div class="mobile-menu-overlay" id="mobile-menu-overlay"></div>
<div class="mobile-menu-sidebar" id="mobile-menu-sidebar">
    <div class="mobile-menu-header">
        <h4>메뉴</h4>
        <button class="mobile-menu-close" id="mobile-menu-close" aria-label="메뉴 닫기">
            <i class="bi bi-x-lg"></i>
        </button>
    </div>
    <div class="mobile-menu-content">
        <nav class="navbar-nav"></nav>
    </div>
</div>

<div class="processing-overlay" id="voiceloadingOverlay" style="display: none;">
    <div class="spinner-border text-light" role="status"></div>
        <h4 style="margin-top: 20px;">분석 후 요약작업 수행중... 잠시만 기다려 주세요</h4>
    <p>오디오 업로드 → 텍스트 변환 → AI 요약 진행 중입니다.</p>
</div>

<div class="voice-container">
    <div class="header-section">
        <h3><i class="bi bi-mic-fill"></i> AI 스마트 업무협의록 작성</h3>
        <p>음성을 녹음하고 AI를 통해 자동으로 업무협의록을 생성합니다</p>
    </div>

    <div class="info-box">
        <p><i class="bi bi-info-circle"></i> Chrome 브라우저에서 마이크 권한을 허용해주세요</p>
        <p><i class="bi bi-clock"></i> 실시간 음성 인식 - 말하는 즉시 텍스트로 변환됩니다</p>
        <p><i class="bi bi-stars"></i> 녹음이 끝나면 AI가 자동으로 업무협의록을 작성합니다</p>
    </div>

    <div class="recording-section">
        <div class="record-controls">
            <button id="record-button" class="record-button">
                <i class="bi bi-mic-fill"></i>
            </button>

            <div id="status" class="status-indicator status-waiting">대기중</div>

            <div id="timer" class="timer">00:00</div>

            <div class="waveform-container">
                <canvas id="waveform" class="waveform-canvas"></canvas>
            </div>
        </div>
    </div>

    <div class="transcript-section">
        <h5><i class="bi bi-eye"></i> 실시간 인식 미리보기</h5>
        <div id="preview-text" class="transcript-text empty">
            녹음 버튼을 클릭하여 음성을 녹음하세요
        </div>

        <div class="action-buttons">
            <button id="save-analyze-btn" class="btn btn-primary" disabled>
                <i class="bi bi-cloud-upload"></i> 업무협의 종료 및 AI 분석 시작
            </button>
            <button id="test-sample-btn" class="btn btn-secondary" style="margin-left: 10px;" title="테스트용 샘플 오디오 생성 (개발/테스트용)">
                <i class="bi bi-file-earmark-music"></i> 샘플 테스트
            </button>
        </div>
    </div>

    <!-- 업무협의록 리스트 섹션 -->
    <div class="transcript-section">
        <h5><i class="bi bi-list-ul"></i> 최근 업무협의록 (최근 10개)</h5>
        <div id="meeting-list">
            <?php if (empty($consult_list)): ?>
                <p style="text-align: center; color: #999; padding: 30px;">
                    <i class="bi bi-inbox"></i><br>
                    저장된 업무협의록이 없습니다
                </p>
            <?php else: ?>
                <table class="meeting-table">
                    <thead>
                        <tr>
                            <th>번호</th>
                            <th>제목</th>
                            <th>작성일</th>
                            <th>요약 미리보기</th>
                            <th>동작</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ($consult_list as $index => $consult): ?>
                            <tr>
                                <td><?= $index + 1 ?></td>
                                <td><?= htmlspecialchars($consult['title']) ?></td>
                                <td><?= date('m-d H:i', strtotime($consult['created_at'])) ?></td>
                                <td class="summary-preview">
                                    <?= htmlspecialchars(mb_substr($consult['summary_text'], 0, 50)) ?>...
                                </td>
                                <td>
                                    <button class="btn-small" onclick="viewDetail(<?= $consult['id'] ?>)" title="업무협의록 상세보기">
                                        <i class="bi bi-eye"></i>
                                    </button>
                                    <?php if (!empty($consult['audio_file_path'])): ?>
                                        <a href="download_audio.php?id=<?= $consult['id'] ?>" 
                                           class="btn-small" 
                                           download="consult_<?= $consult['id'] ?>.webm"
                                           title="오디오 파일 다운로드">
                                            <i class="bi bi-download"></i>
                                        </a>
                                    <?php else: ?>
                                        <span class="btn-small" style="opacity: 0.5; cursor: not-allowed;" title="오디오 파일이 없습니다">
                                            <i class="bi bi-download"></i>
                                        </span>
                                    <?php endif; ?>
                                    <button class="btn-small" onclick="confirmDelete(<?= $consult['id'] ?>, '<?= htmlspecialchars(addslashes($consult['title'] ?: '업무협의녹음')) ?>')" 
                                            style="background-color: #dc3545; color: white;"
                                            title="업무협의록 삭제">
                                        <i class="bi bi-trash"></i>
                                    </button>
                                </td>
                            </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            <?php endif; ?>
        </div>
    </div>
</div>

<!-- 상세보기 모달 -->
<div id="detail-modal" class="modal" style="display: none;">
    <div class="modal-content">
        <span class="close-btn" onclick="closeModal()">&times;</span>
        <h4 id="modal-title">업무협의록 상세</h4>
        <div class="modal-body">
            <div class="detail-section">
                <h6><i class="bi bi-file-text"></i> 전체 텍스트</h6>
                <div id="modal-transcript" class="detail-text"></div>
            </div>
            <div class="detail-section">
                <h6><i class="bi bi-stars"></i> AI 요약</h6>
                <div id="modal-summary" class="detail-text"></div>
            </div>
        </div>
    </div>
</div>

<!-- 삭제 확인 모달 -->
<div id="delete-modal" class="modal" style="display: none;">
    <div class="modal-content" style="max-width: 400px;">
        <span class="close-btn" onclick="closeDeleteModal()">&times;</span>
        <h4>업무협의록 삭제 확인</h4>
        <div class="modal-body">
            <p>정말로 이 업무협의록을 삭제하시겠습니까?</p>
            <p style="font-weight: bold; color: #dc3545;" id="delete-meeting-title"></p>
            <p style="font-size: 12px; color: #6c757d;">서버 파일과 Google Cloud Storage의 파일도 함께 삭제됩니다.</p>
        </div>
        <div style="text-align: right; margin-top: 20px;">
            <button class="btn-small" onclick="closeDeleteModal()" style="margin-right: 10px; width: auto; padding: 8px 20px;">취소</button>
            <button class="btn-small" onclick="deleteMeeting()" style="background-color: #dc3545; color: white; width: auto; padding: 8px 20px;">삭제</button>
        </div>
    </div>
</div>

<!-- 디버그 패널 -->
<button class="debug-toggle-btn" id="debug-toggle-btn" title="디버그 패널 열기/닫기">
    <i class="bi bi-bug"></i>
</button>

<div class="debug-panel" id="debug-panel">
    <div class="debug-panel-header">
        <span class="debug-panel-title">🔍 디버그 콘솔</span>
        <div class="debug-panel-controls">
            <button class="debug-panel-btn" id="debug-copy-btn" title="로그 복사">
                <i class="bi bi-clipboard"></i>
            </button>
            <button class="debug-panel-btn" id="debug-clear-btn" title="로그 지우기">
                <i class="bi bi-trash"></i>
            </button>
            <button class="debug-panel-btn" id="debug-close-btn" title="패널 닫기">
                <i class="bi bi-x-lg"></i>
            </button>
        </div>
    </div>
    <div class="debug-panel-content" id="debug-content">
        <div class="debug-log info">디버그 패널이 준비되었습니다. 로그가 여기에 표시됩니다.</div>
    </div>
</div>

<script>
// 모바일 감지 함수
function isMobileDevice() {
    return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
}

function isIOS() {
    return /iPhone|iPad|iPod/i.test(navigator.userAgent);
}

function isAndroid() {
    return /Android/i.test(navigator.userAgent);
}

let mediaRecorder;
let audioChunks = [];
let isRecording = false;
let startTime;
let timerInterval;

// Web Speech API (미리보기용)
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
let recognition = null;
let isRecognitionActive = false;

// Google Cloud Speech-to-Text API 변수
let useGoogleAPI = false;
let recordingInterval = null;
let audioBlob = null;
let isMobile = isMobileDevice();

// 모바일에서는 Google API 사용
if (isMobile) {
    useGoogleAPI = true;
    // console.log는 디버그 패널 초기화 후에 작동하므로, 즉시 실행
    if (window.debugLog) {
        window.debugLog('모바일 감지: Google Cloud Speech-to-Text API 사용', 'info');
    }
    // 원본 console에도 출력 (디버그 패널이 초기화되기 전일 수 있음)
    if (console && console.log) {
        console.log('모바일 감지: Google Cloud Speech-to-Text API 사용');
    }
}

// 음성 인식 텍스트 변수 (중복 방지)
let finalTranscript = '';
let interimTranscript = '';
let lastReceivedTranscript = ''; // 마지막으로 받은 텍스트 (중복 방지용)

// 시각화 변수
let audioContext = null;
let analyser = null;
let dataArray = null;
let animationId = null;
let mediaStream = null;
let gainNode = null; // 오디오 증폭용
let audioSource = null; // 오디오 소스

// DOM 요소
const recordBtn = document.getElementById('record-button');
const saveBtn = document.getElementById('save-analyze-btn');
const previewText = document.getElementById('preview-text');
const statusEl = document.getElementById('status');
const timerEl = document.getElementById('timer');
const waveformCanvas = document.getElementById('waveform');
const canvasCtx = waveformCanvas.getContext('2d');

// 화면 업데이트 전용 함수 (콘솔 로그와 함께 호출)
function updatePreviewDisplay() {
    const displayText = finalTranscript.trim();
    
    // 콘솔에 로그 출력 (디버그 패널에도 표시됨)
    console.log('🖥️ 화면 업데이트:', displayText.length, '자');
    console.log('🖥️ 화면 표시 내용 (처음 50자):', displayText.substring(0, 50));
    console.log('🖥️ finalTranscript 전체:', displayText);
    
    // 화면 업데이트
    if (previewText) {
        // 즉시 업데이트
        previewText.textContent = displayText;
        previewText.classList.remove('empty');
        
        // 모바일에서 DOM 업데이트 강제 반영
        void previewText.offsetHeight; // 강제 리플로우
        
        // requestAnimationFrame으로 다음 프레임에 재확인
        requestAnimationFrame(() => {
            if (previewText) {
                previewText.textContent = displayText;
                previewText.classList.remove('empty');
                previewText.scrollTop = previewText.scrollHeight;
            }
        });
        
        console.log('✅ 화면 업데이트 완료');
    } else {
        console.error('❌ previewText 요소를 찾을 수 없습니다!');
    }
    
    // 버튼 활성화
    if (displayText) {
        saveBtn.disabled = false;
    }
}

// Canvas 크기 초기화
function resizeCanvas() {
    waveformCanvas.width = waveformCanvas.offsetWidth;
    waveformCanvas.height = waveformCanvas.offsetHeight;
}
resizeCanvas();
window.addEventListener('resize', resizeCanvas);

// Web Speech API 초기화
function initSpeechRecognition() {
    if (!SpeechRecognition) {
        alert('이 브라우저는 음성 인식을 지원하지 않습니다. Chrome 브라우저를 사용해주세요.');
        return false;
    }

    recognition = new SpeechRecognition();
    recognition.lang = 'ko-KR';
    recognition.continuous = true;
    recognition.interimResults = true;
    // 민감도 향상을 위한 추가 설정
    recognition.maxAlternatives = 3; // 더 많은 대안 결과 허용
    
    return true;
}

// Waveform 시각화
function drawWaveform() {
    if (!analyser || !dataArray) return;

    animationId = requestAnimationFrame(drawWaveform);

    analyser.getByteTimeDomainData(dataArray);

    canvasCtx.fillStyle = '#f8f9fa';
    canvasCtx.fillRect(0, 0, waveformCanvas.width, waveformCanvas.height);

    canvasCtx.lineWidth = 2;
    canvasCtx.strokeStyle = '#667eea';
    canvasCtx.beginPath();

    const sliceWidth = waveformCanvas.width / dataArray.length;
    let x = 0;

    for (let i = 0; i < dataArray.length; i++) {
        const v = dataArray[i] / 128.0;
        const y = v * waveformCanvas.height / 2;

        if (i === 0) {
            canvasCtx.moveTo(x, y);
        } else {
            canvasCtx.lineTo(x, y);
        }

        x += sliceWidth;
    }

    canvasCtx.lineTo(waveformCanvas.width, waveformCanvas.height / 2);
    canvasCtx.stroke();
}

function stopWaveform() {
    if (animationId) {
        cancelAnimationFrame(animationId);
        animationId = null;
    }

    // Clear canvas
    canvasCtx.fillStyle = '#f8f9fa';
    canvasCtx.fillRect(0, 0, waveformCanvas.width, waveformCanvas.height);
}

// 오디오 스트림 시작 (시각화용 및 증폭)
async function startAudioStream() {
    try {
        // 마이크 제약 조건 최적화 (민감도 향상)
        const audioConstraints = {
            audio: {
                echoCancellation: false, // 에코 캔슬 비활성화 (작은 소리 감지 향상)
                noiseSuppression: false, // 노이즈 억제 비활성화 (작은 소리 감지 향상)
                autoGainControl: true,   // 자동 게인 제어 활성화
                sampleRate: 48000,      // 높은 샘플레이트
                channelCount: 1         // 모노 채널
            }
        };
        
        mediaStream = await navigator.mediaDevices.getUserMedia(audioConstraints);

        // Setup Audio Context for Visualization and Amplification
        audioContext = new (window.AudioContext || window.webkitAudioContext)();
        
        // 오디오 소스 생성
        audioSource = audioContext.createMediaStreamSource(mediaStream);
        
        // GainNode 생성 및 증폭 설정 (3배 증폭 - 작은 소리도 잘 들리도록)
        gainNode = audioContext.createGain();
        gainNode.gain.value = 3.0; // 3배 증폭 (최대 10까지 가능하지만 3이 적절)
        
        // 오디오 체인: Source -> Gain -> Analyser
        audioSource.connect(gainNode);
        analyser = audioContext.createAnalyser();
        gainNode.connect(analyser);

        analyser.fftSize = 2048;
        const bufferLength = analyser.frequencyBinCount;
        dataArray = new Uint8Array(bufferLength);

        // Start Waveform Visualization
        drawWaveform();

        return mediaStream;
    } catch (error) {
        console.error('마이크 접근 오류:', error);
        alert('마이크 권한을 허용해주세요');
        return null;
    }
}

// 오디오 스트림 중지
function stopAudioStream() {
    if (mediaStream) {
        mediaStream.getTracks().forEach(track => track.stop());
        mediaStream = null;
    }

    // 오디오 노드 연결 해제
    if (audioSource) {
        try {
            audioSource.disconnect();
        } catch (e) {
            console.log('Audio source disconnect:', e);
        }
        audioSource = null;
    }
    
    if (gainNode) {
        try {
            gainNode.disconnect();
        } catch (e) {
            console.log('Gain node disconnect:', e);
        }
        gainNode = null;
    }
    
    if (analyser) {
        try {
            analyser.disconnect();
        } catch (e) {
            console.log('Analyser disconnect:', e);
        }
        analyser = null;
    }

    if (audioContext) {
        audioContext.close();
        audioContext = null;
    }
}

// Google Cloud Speech-to-Text API 함수
// Google Cloud Speech-to-Text API 함수
async function startGoogleRecognition() {
    try {
        console.log('=== Google Cloud Speech-to-Text API 시작 (Consult/Timeslice Mode) ===');
        
        const stream = await navigator.mediaDevices.getUserMedia({ 
            audio: {
                channelCount: 1,
                sampleRate: 16000,
                echoCancellation: true,
                noiseSuppression: true
            } 
        });
        
        mediaStream = stream;
        
        // 오디오 시각화
        audioContext = new (window.AudioContext || window.webkitAudioContext)();
        analyser = audioContext.createAnalyser();
        const source = audioContext.createMediaStreamSource(stream);
        source.connect(analyser);
        
        analyser.fftSize = 2048;
        const bufferLength = analyser.frequencyBinCount;
        dataArray = new Uint8Array(bufferLength);
        
        drawWaveform();
        
        // MediaRecorder 설정
        const options = {
            mimeType: 'audio/webm;codecs=opus',
            audioBitsPerSecond: 16000
        };
        
        // 지원하는 형식 확인
        if (!MediaRecorder.isTypeSupported('audio/webm;codecs=opus')) {
            if (MediaRecorder.isTypeSupported('audio/webm')) {
                options.mimeType = 'audio/webm';
            } else if (MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')) {
                options.mimeType = 'audio/ogg;codecs=opus';
            } else if (MediaRecorder.isTypeSupported('audio/mp4')) {
                options.mimeType = 'audio/mp4';
            } else {
                options.mimeType = '';
            }
        }
        
        console.log('MediaRecorder 형식:', options.mimeType || '기본값');
        
        mediaRecorder = new MediaRecorder(stream, options);
        audioChunks = []; // 초기화
        
        // 3초마다 데이터가 들어옴
        mediaRecorder.ondataavailable = async (event) => {
            if (event.data.size > 0) {
                audioChunks.push(event.data);
                console.log('오디오 청크 수집:', event.data.size, 'bytes', '(총 ' + audioChunks.length + '개)');
                
                // 실시간 미리보기 전송 (전체 오디오 전송)
                if (isRecording && audioChunks.length > 0) {
                    const fullBlob = new Blob(audioChunks, { type: mediaRecorder.mimeType });
                    await sendAudioToServer(fullBlob, true);
                }
            }
        };
        
        mediaRecorder.onstop = () => {
            console.log('MediaRecorder 중지됨');
        };
        
        // 3000ms(3초)마다 ondataavailable 발생
        mediaRecorder.start(3000);
        
        recordBtn.classList.add('recording');
        recordBtn.innerHTML = '<i class="bi bi-stop-fill"></i>';
        updateStatus('음성 인식 중 (Google API)', 'recording');
        startTimer();
        isRecording = true;
        isRecognitionActive = true;
        
        console.log('✅ Google API 녹음 시작 완료');
        
    } catch (error) {
        console.error('Google API 녹음 시작 오류:', error);
        updateStatus('녹음 시작 실패: ' + error.message, 'error');
        alert('마이크 권한을 허용해주세요.');
    }
}

function stopGoogleRecognition() {
    console.log('=== Google Cloud Speech-to-Text API 중지 ===');
    
    isRecognitionActive = false;
    
    if (mediaRecorder && mediaRecorder.state !== 'inactive') {
        mediaRecorder.stop();
    }
    
    if (mediaStream) {
        mediaStream.getTracks().forEach(track => track.stop());
        mediaStream = null;
    }
    
    // 타이머와 시각화 중지
    stopTimer();
    stopWaveform();
    stopAudioStream();
    
    console.log('✅ Google API 녹음 중지 완료');
    console.log('audioChunks 보존됨 (저장 버튼에서 사용):', audioChunks.length, '개 청크');
}

// 긴 작업 상태 폴링 (Google STT 등)
function pollConsultStatus(consultId, operationName, pollUrl) {
    const POLL_INTERVAL = 3000; // 3초마다 확인
    let errorCount = 0;
    
    console.log(`폴링 시작: ConsultID=${consultId}, Operation=${operationName}`);
    
    // 기존 폴링 인터벌이 있다면 제거 (안전장치)
    if (window.pollingInterval) {
        clearInterval(window.pollingInterval);
    }
    
    window.pollingInterval = setInterval(async () => {
        try {
            // URL에 파라미터가 이미 포함되어 있으므로 그대로 호출
            const response = await fetch(pollUrl);
            
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            
            const data = await response.json();
            console.log('폴링 응답:', data);
            
            if (data.ok) {
                if (data.done) {
                    // 완료됨
                    clearInterval(window.pollingInterval);
                    window.pollingInterval = null;
                    updateStatus('분석 완료! 저장 중...', 'completed');
                    alert(data.message || '업무협의록 분석이 완료되었습니다.');
                    window.location.reload();
                } else if (data.processing) {
                    // 계속 진행 중
                    updateStatus('AI 분석 중... 잠시만 기다려주세요', 'processing');
                    errorCount = 0; // 성공적인 응답이면 에러 카운트 초기화
                } else {
                    // 알 수 없는 상태
                    console.warn('알 수 없는 폴링 상태:', data);
                }
            } else {
                // 서버 로직 에러
                clearInterval(window.pollingInterval);
                window.pollingInterval = null;
                updateStatus('분석 실패', 'error');
                alert('분석 중 오류가 발생했습니다: ' + (data.error || '알 수 없는 오류'));
            }
            
        } catch (e) {
            console.error('폴링 오류:', e);
            errorCount++;
            
            // 연속 5회 실패 시 중단
            if (errorCount >= 5) {
                clearInterval(window.pollingInterval);
                window.pollingInterval = null;
                updateStatus('통신 오류', 'error');
                alert('서버와 통신 중 오류가 지속되어 확인을 중단합니다. 나중에 목록을 새로고침 해보세요.');
            }
        }
    }, POLL_INTERVAL);
}

async function sendAudioToServer(audioBlob, isChunk = false, retryCount = 0) {
    const MAX_RETRIES = 2; // 최대 2번 재시도
    const MIN_AUDIO_SIZE = 2000; // 2KB 미만은 건너뛰기 (너무 작은 청크)
    const FETCH_TIMEOUT = 90000; // 90초 타임아웃 (서버 타임아웃 120초보다 짧게)
    
    try {
        console.log('서버로 오디오 전송:', audioBlob.size, 'bytes', isChunk ? '(청크)' : '(최종)', retryCount > 0 ? `(재시도 ${retryCount})` : '');
        
        // 빈 오디오 체크
        if (audioBlob.size === 0) {
            console.warn('⚠️ 빈 오디오 파일, 전송 건너뜀');
            return;
        }
        
        // 너무 작은 청크는 건너뛰기 (청크만, 최종은 항상 전송)
        if (isChunk && audioBlob.size < MIN_AUDIO_SIZE) {
            console.log(`⚠️ 오디오 청크가 너무 작음 (${audioBlob.size} bytes < ${MIN_AUDIO_SIZE} bytes), 전송 건너뜀`);
            return;
        }
        
        const formData = new FormData();
        // 파일명에 타임스탬프 추가하여 고유성 보장
        const fileName = 'recording_' + Date.now() + '.webm';
        formData.append('audio', audioBlob, fileName);
        
        // AbortController로 타임아웃 설정
        const controller = new AbortController();
        const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT);
        
        let response;
        try {
            response = await fetch('api/speech_to_text.php', {
                method: 'POST',
                body: formData,
                signal: controller.signal
            });
            clearTimeout(timeoutId);
        } catch (fetchError) {
            clearTimeout(timeoutId);
            
            // 타임아웃 또는 네트워크 오류
            if (fetchError.name === 'AbortError') {
                throw new Error('HTTP 504: 요청 시간 초과 (90초)');
            } else if (fetchError.name === 'TypeError' && fetchError.message.includes('Failed to fetch')) {
                throw new Error('HTTP 504: 네트워크 연결 실패');
            }
            throw fetchError;
        }
        
        // 응답 상태 확인
        if (!response.ok) {
            // 504 오류인 경우 재시도
            if (response.status === 504 && retryCount < MAX_RETRIES) {
                console.warn(`⚠️ 504 오류 발생, ${retryCount + 1}번째 재시도...`);
                await new Promise(resolve => setTimeout(resolve, 1000 * (retryCount + 1))); // 지수 백오프
                return sendAudioToServer(audioBlob, isChunk, retryCount + 1);
            }
            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }
        
        const result = await response.json();
        
        if (result.success && result.transcript) {
            console.log('✅ 텍스트 변환 성공:', result.transcript);
            console.log('신뢰도:', result.confidence || 'N/A');
            
            // 모바일 전용 텍스트 누적 로직: 강력한 중복 제거
            const newText = result.transcript.trim();
            
            // 빈 텍스트나 공백만 있는 텍스트는 무시
            if (!newText || newText.length === 0) {
                console.log('⏭️ 빈 텍스트 무시');
                return;
            }
            
            // 이전 응답과 동일한 텍스트인 경우 무시
            if (newText === lastReceivedTranscript) {
                console.log('⏭️ 이전 응답과 동일한 텍스트 무시:', newText);
                return;
            }

            // 모바일 로직 수정: 복잡한 중복 제거 로직 대신 전체 텍스트 교체 방식 사용
            // 이유: sendAudioToServer는 누적된 전체 오디오(audioChunks)를 서버로 보냄
            
            // 안전장치: 텍스트가 기존보다 현저히 짧아지는 경우 (오류 가능성) 무시
            // 단, 초기 단계거나 짧은 텍스트일 때는 허용
            const currentLength = finalTranscript.trim().length;
            if (currentLength > 50 && newText.length < currentLength * 0.5) {
                console.warn('⚠️ 텍스트가 비정상적으로 짧아짐, 무시 (기존:', currentLength, '자, 신규:', newText.length, '자)');
                return;
            }

            // 텍스트 전체 교체
            finalTranscript = newText;
            console.log('✅ 텍스트 교체 (Mobile 전체 업데이트):', newText.length, '자');
            
            // 마지막으로 받은 텍스트 업데이트 (성공적으로 처리된 경우만)
            lastReceivedTranscript = newText;
            
            // 화면 업데이트
            updatePreviewDisplay();
            
            updateStatus('음성 인식 중 (Google API)', 'recording');
        } else {
            console.error('❌ 텍스트 변환 실패:', result.error);
            console.error('디버그 정보:', result.debug || result.hint || '없음');
            
            // API 키 오류인 경우 사용자에게 상세 안내
            if (result.error && (
                result.error.includes('API key') || 
                result.error.includes('API 키') || 
                result.error.includes('not valid') ||
                result.error.includes('invalid')
            )) {
                updateStatus('API 키 오류', 'error');
                if (!isChunk) {
                    let errorMsg = 'Google Cloud Speech-to-Text API 키 오류가 발생했습니다.\n\n';
                    errorMsg += '⚠️ API 키 오류 해결 방법:\n';
                    errorMsg += '1. Google Cloud Console (https://console.cloud.google.com/) 접속\n';
                    errorMsg += '2. 프로젝트 선택: codebridge-chatbot\n';
                    errorMsg += '3. "API 및 서비스" > "라이브러리"에서 "Cloud Speech-to-Text API" 검색 및 활성화\n';
                    errorMsg += '4. "API 및 서비스" > "사용자 인증 정보"에서 API 키 확인\n';
                    errorMsg += '5. API 키 제한 설정에서 "Cloud Speech-to-Text API" 허용 확인\n\n';
                    if (result.debug) {
                        errorMsg += '현재 API 키 파일: ' + (result.debug.api_key_path || 'N/A') + '\n';
                        errorMsg += 'API 키 길이: ' + (result.debug.api_key_length || 'N/A') + ' 문자\n';
                        if (result.debug.service_account_path) {
                            errorMsg += '서비스 계정 파일: ' + result.debug.service_account_path + '\n';
                        }
                    }
                    
                    alert(errorMsg);
                }
            } else if (!isChunk) {
                // 에러 메시지에서 줄바꿈 처리
                const errorMsg = result.error ? result.error.replace(/\\n/g, '\n') : '알 수 없는 오류';
                updateStatus('변환 실패: ' + errorMsg.split('\n')[0], 'error');
                
                // 상세 에러가 있으면 콘솔에 출력
                if (result.error && result.error.includes('\n')) {
                    console.error('상세 에러:', result.error);
                }
            }
        }
        
    } catch (error) {
        const httpCode = error.message.match(/\d+/)?.[0] || '알 수 없음';
        console.error('❌ 텍스트 변환 실패: API 오류 (HTTP ' + httpCode + '):', error.message);
        console.error('디버그 정보:', error.stack || '없음');
        
        // 504 오류인 경우 재시도 (최종 요청만)
        if (httpCode === '504' && !isChunk && retryCount < MAX_RETRIES) {
            console.warn(`⚠️ 504 오류 발생, ${retryCount + 1}번째 재시도...`);
            await new Promise(resolve => setTimeout(resolve, 2000 * (retryCount + 1))); // 지수 백오프
            return sendAudioToServer(audioBlob, isChunk, retryCount + 1);
        }
        
        // 재시도 횟수 초과 또는 청크 요청인 경우에만 오류 표시
        if (!isChunk || retryCount >= MAX_RETRIES) {
            updateStatus('전송 실패: ' + error.message, 'error');
        }
    }
}

// 녹음 시작/종료 처리
recordBtn.addEventListener('click', async () => {
    console.log('녹음 버튼 클릭됨, isRecording:', isRecording, 'useGoogleAPI:', useGoogleAPI, 'isMobile:', isMobile);
    
    if (!isRecording) {
        // 변수 초기화
            audioChunks = [];
            finalTranscript = '';
            interimTranscript = '';
            lastReceivedTranscript = ''; // 마지막으로 받은 텍스트도 초기화
        
        // 모바일에서는 Google API 사용
        if (useGoogleAPI) {
            console.log('모바일 모드: startGoogleRecognition() 호출');
            await startGoogleRecognition();
        } else {
            // 데스크탑: Web Speech API 사용
            if (!recognition) {
                if (!initSpeechRecognition()) {
                    return;
                }
            }

            const stream = await startAudioStream();
            if (!stream) return;
            
            // MediaRecorder 시작 (파일 저장용)
            mediaRecorder = new MediaRecorder(stream);
            mediaRecorder.ondataavailable = (event) => {
                audioChunks.push(event.data);
            };
            mediaRecorder.start();

            // Web Speech API 시작 (화면 표시용)
            if (!isRecognitionActive) {
                try {
                    recognition.start();
                    isRecognitionActive = true;
                } catch (e) {
                    console.error('음성 인식 시작 실패:', e);
                }
            }

            isRecording = true;
            recordBtn.classList.add('recording');
            recordBtn.innerHTML = '<i class="bi bi-stop-fill"></i>';
            updateStatus('녹음 중...', 'recording');
            startTimer();
            saveBtn.disabled = true;
            previewText.classList.remove('empty');
        }

    } else {
        // 녹음 종료
        if (useGoogleAPI) {
            // 모바일: Google API 사용
            stopGoogleRecognition();
        } else {
            // PC: Web Speech API + MediaRecorder 사용
            mediaRecorder.stop();
            
            if (isRecognitionActive) {
                try {
                    recognition.stop();
                    isRecognitionActive = false;
                } catch (e) {
                    console.error('음성 인식 종료 실패:', e);
                }
            }
            
            stopTimer();
            stopWaveform();
            stopAudioStream();
        }
        
        isRecording = false;
        recordBtn.classList.remove('recording');
        recordBtn.innerHTML = '<i class="bi bi-mic-fill"></i>';
        updateStatus('녹음 완료', 'completed');
        
        // 최종 텍스트 정리 (임시 텍스트 제거)
        if (finalTranscript.trim()) {
            previewText.textContent = finalTranscript.trim();
            saveBtn.disabled = false;
        } else {
            previewText.innerHTML = '<span style="color:#999;font-style:italic;">인식된 텍스트가 없습니다</span>';
            saveBtn.disabled = true;
        }
    }
});

// Web Speech API 이벤트 핸들러 설정
function setupRecognitionHandlers() {
    if (!recognition) return;

    // 음성 인식 결과 처리
    recognition.onresult = (event) => {
        // 임시 텍스트 초기화 (중복 방지를 위해 매번 초기화)
        interimTranscript = '';
        
        for (let i = event.resultIndex; i < event.results.length; i++) {
            const transcript = event.results[i][0].transcript;
            
            if (event.results[i].isFinal) {
                // 확정된 텍스트는 finalTranscript에 추가
                finalTranscript += transcript + ' ';
            } else {
                // 임시 텍스트는 interimTranscript에 저장 (누적하지 않음)
                interimTranscript += transcript;
            }
        }
        
        // 텍스트 업데이트 (확정된 텍스트 + 현재 임시 텍스트만 표시)
        const displayText = finalTranscript + (interimTranscript ? '<span style="color:#999">' + interimTranscript + '</span>' : '');
        previewText.innerHTML = displayText || '음성을 인식하고 있습니다...';
        previewText.classList.remove('empty');
        previewText.scrollTop = previewText.scrollHeight;
        
        // 버튼 활성화 (확정된 텍스트가 있을 때만)
        if (finalTranscript.trim()) {
            saveBtn.disabled = false;
        }
    };

    // 음성 인식 시작
    recognition.onstart = () => {
        isRecognitionActive = true;
        updateStatus('음성 인식 중', 'recording');
    };

    // 음성 인식 종료
    recognition.onend = () => {
        isRecognitionActive = false;

        if (isRecording) {
            // 자동 재시작 (연속 녹음 모드)
            try {
                recognition.start();
            } catch (e) {
                console.log('Recognition restart failed:', e);
            }
        } else {
            updateStatus('변환 완료', 'completed');
        }
    };

    // 에러 처리
    recognition.onerror = (event) => {
        console.error('Speech recognition error:', event.error);

        if (event.error === 'no-speech') {
            // 음성이 감지되지 않음 - 자동 재시작 (작은 소리도 감지하도록 지속 시도)
            if (isRecording) {
                setTimeout(() => {
                    try {
                        if (isRecording && !isRecognitionActive) {
                            recognition.start();
                        }
                    } catch (e) {
                        console.log('Recognition restart after no-speech:', e);
                    }
                }, 500);
            }
            return;
        }

        if (event.error === 'aborted') {
            // 사용자가 중단함
            return;
        }

        // 'network' 오류는 일시적이므로 재시도
        if (event.error === 'network') {
            if (isRecording) {
                setTimeout(() => {
                    try {
                        if (isRecording && !isRecognitionActive) {
                            recognition.start();
                        }
                    } catch (e) {
                        console.log('Recognition restart after network error:', e);
                    }
                }, 1000);
            }
            return;
        }

        updateStatus('오류 발생: ' + event.error, 'error');

        if (event.error === 'not-allowed') {
            alert('마이크 권한이 거부되었습니다. 브라우저 설정에서 마이크 권한을 허용해주세요.');
        }
    };
}

// Update Status
function updateStatus(message, statusClass) {
    statusEl.textContent = message;
    statusEl.className = 'status-indicator status-' + statusClass;
}

// Timer Functions
function startTimer() {
    startTime = Date.now();
    timerEl.classList.add('active');

    timerInterval = setInterval(() => {
        const elapsed = Math.floor((Date.now() - startTime) / 1000);
        const minutes = Math.floor(elapsed / 60);
        const seconds = elapsed % 60;
        timerEl.textContent = `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
    }, 1000);
}

function stopTimer() {
    if (timerInterval) {
        clearInterval(timerInterval);
        timerInterval = null;
    }
    timerEl.classList.remove('active');
}

// 테스트용 샘플 오디오 생성 (개발/테스트용)
const testSampleBtn = document.getElementById('test-sample-btn');
if (testSampleBtn) {
    testSampleBtn.addEventListener('click', async () => {
        if (!confirm('테스트용 샘플 오디오를 생성하시겠습니까?\n(실제 녹음 없이 테스트용 더미 데이터를 생성합니다)')) {
            return;
        }
        
        try {
            // Web Audio API를 사용하여 짧은 오디오 생성
            const audioContext = new (window.AudioContext || window.webkitAudioContext)();
            const sampleRate = audioContext.sampleRate;
            const duration = 2; // 2초
            const numSamples = sampleRate * duration;
            const buffer = audioContext.createBuffer(1, numSamples, sampleRate);
            const data = buffer.getChannelData(0);
            
            // 간단한 사인파 생성 (테스트용)
            for (let i = 0; i < numSamples; i++) {
                data[i] = Math.sin(2 * Math.PI * 440 * i / sampleRate) * 0.1; // 440Hz, 작은 볼륨
            }
            
            // WAV로 변환
            const wav = audioBufferToWav(buffer);
            const blob = new Blob([wav], { type: 'audio/wav' });
            
            // audioChunks에 추가
            audioChunks = [blob];
            finalTranscript = '안녕하세요. 미래기업입니다. 업무협의를 시작합니다.';
            previewText.textContent = finalTranscript;
            saveBtn.disabled = false;
            updateStatus('샘플 데이터 준비 완료', 'completed');
            alert('샘플 오디오가 생성되었습니다. "업무협의 종료 및 AI 분석 시작" 버튼을 클릭하세요.');
        } catch (e) {
            console.error('샘플 오디오 생성 실패:', e);
            alert('샘플 오디오 생성에 실패했습니다: ' + e.message);
        }
    });
}

// AudioBuffer를 WAV로 변환하는 함수
function audioBufferToWav(buffer) {
    const length = buffer.length;
    const arrayBuffer = new ArrayBuffer(44 + length * 2);
    const view = new DataView(arrayBuffer);
    const channels = buffer.numberOfChannels;
    const sampleRate = buffer.sampleRate;
    
    // WAV 헤더 작성
    const writeString = (offset, string) => {
        for (let i = 0; i < string.length; i++) {
            view.setUint8(offset + i, string.charCodeAt(i));
        }
    };
    
    writeString(0, 'RIFF');
    view.setUint32(4, 36 + length * 2, true);
    writeString(8, 'WAVE');
    writeString(12, 'fmt ');
    view.setUint32(16, 16, true);
    view.setUint16(20, 1, true);
    view.setUint16(22, channels, true);
    view.setUint32(24, sampleRate, true);
    view.setUint32(28, sampleRate * 2, true);
    view.setUint16(32, 2, true);
    view.setUint16(34, 16, true);
    writeString(36, 'data');
    view.setUint32(40, length * 2, true);
    
    // 데이터 작성
    const channelData = buffer.getChannelData(0);
    let offset = 44;
    for (let i = 0; i < length; i++) {
        const sample = Math.max(-1, Math.min(1, channelData[i]));
        view.setInt16(offset, sample < 0 ? sample * 0x8000 : sample * 0x7FFF, true);
        offset += 2;
    }
    
    return arrayBuffer;
}

// 저장 및 분석 버튼 클릭
saveBtn.addEventListener('click', async () => {
    // 버튼 비활성화 및 로딩 표시
    saveBtn.disabled = true;
    const originalBtnText = saveBtn.innerHTML;
    saveBtn.innerHTML = '<span class="loading-spinner"></span> 처리 중...';
    
    document.getElementById('voiceloadingOverlay').style.display = 'flex';
    updateStatus('처리 중...', 'processing');

    // Blob 생성
    // 모바일에서는 audioChunks가 비어있을 수 있으므로 확인
    if (!audioChunks || audioChunks.length === 0) {
        console.warn('audioChunks가 비어있습니다. 녹음이 제대로 되지 않았을 수 있습니다.');
        console.log('isRecording:', isRecording, 'useGoogleAPI:', useGoogleAPI, 'isMobile:', isMobile);
        console.log('mediaRecorder state:', mediaRecorder ? mediaRecorder.state : 'null');
        
        alert('녹음된 오디오 데이터가 없습니다. 녹음을 시작하고 일정 시간 이상 녹음해주세요.');
        document.getElementById('voiceloadingOverlay').style.display = 'none';
        saveBtn.disabled = false;
        saveBtn.innerHTML = originalBtnText;
        updateStatus('오류', 'error');
        return;
    }
    
    console.log('저장 시 audioChunks 개수:', audioChunks.length);
    console.log('저장 시 audioChunks 총 크기:', audioChunks.reduce((sum, chunk) => sum + chunk.size, 0), 'bytes');
    
    // 모바일에서는 mediaRecorder.mimeType 사용, PC에서는 'audio/webm' 사용
    const mimeType = (useGoogleAPI && mediaRecorder && mediaRecorder.mimeType) ? mediaRecorder.mimeType : 'audio/webm';
    const audioBlob = new Blob(audioChunks, { type: mimeType });
    
    console.log('생성된 audioBlob 크기:', audioBlob.size, 'bytes, type:', mimeType);
    
    // 오디오 파일 크기 확인 (최소 크기 완화: 500 bytes 이상이면 허용)
    // 20초 정도의 짧은 회의도 처리할 수 있도록 최소 크기를 낮춤
    if (audioBlob.size < 500) { // 500 bytes 미만이면 너무 작음
        alert('녹음된 오디오가 너무 작습니다. (' + audioBlob.size + ' bytes) 녹음을 다시 시도해주세요.');
        document.getElementById('voiceloadingOverlay').style.display = 'none';
        saveBtn.disabled = false;
        saveBtn.innerHTML = originalBtnText;
        updateStatus('오류', 'error');
        return;
    }
    
    const formData = new FormData();
    formData.append('audio_file', audioBlob, 'consult_record.webm');
    
    // 확정된 텍스트 전송 (참고용)
    const finalText = finalTranscript.trim();
    console.log('저장 시 finalTranscript 길이:', finalText.length, '자');
    console.log('저장 시 finalTranscript 내용 (처음 100자):', finalText.substring(0, 100));
    console.log('저장 시 finalTranscript 내용 (마지막 100자):', finalText.substring(Math.max(0, finalText.length - 100)));
    
    if (finalText) {
        formData.append('preview_text', finalText);
        console.log('✅ preview_text 전송:', finalText.length, '자');
    } else {
        console.warn('⚠️ finalTranscript가 비어있습니다.');
    }

    try {
        const response = await fetch('process_consult.php', {
            method: 'POST',
            body: formData
        });
        
        // HTTP 상태 코드 확인
        if (!response.ok) {
            const errorText = await response.text();
            console.error('서버 통신 오류:', response.status, response.statusText);
            console.error('응답 텍스트:', errorText);
            console.error('응답 헤더:', Object.fromEntries(response.headers.entries()));
            
            let errorMessage = `서버 오류 (HTTP ${response.status})`;
            if (errorText) {
                try {
                    const errorJson = JSON.parse(errorText);
                    errorMessage = errorJson.error || errorMessage;
                    if (errorJson.details) {
                        errorMessage += ': ' + errorJson.details;
                    }
                } catch (e) {
                    errorMessage += ': ' + errorText.substring(0, 200);
                }
            }
            
            alert(errorMessage);
            throw new Error(errorMessage);
        }
        
        const text = await response.text();
        
        // 빈 응답 체크
        if (!text || text.trim() === '') {
            console.error('서버 응답이 비어있습니다.');
            console.error('응답 상태:', response.status, response.statusText);
            console.error('응답 헤더:', Object.fromEntries(response.headers.entries()));
            alert('서버 응답이 비어있습니다. PHP 오류 로그를 확인해주세요.');
            throw new Error('Empty server response');
        }
        
        // JSON 파싱 전에 텍스트 확인
        let result;
        try {
            result = JSON.parse(text);
        } catch (parseError) {
            console.error('JSON 파싱 오류:', parseError);
            console.error('응답 텍스트:', text);
            console.error('응답 길이:', text.length);
            console.error('응답 상태:', response.status, response.statusText);
            
            // PHP 에러나 경고가 포함되어 있을 수 있음
            if (text.includes('Warning:') || text.includes('Fatal error:') || text.includes('Parse error:')) {
                alert('PHP 오류가 발생했습니다. 서버 로그를 확인해주세요.\n\n' + text.substring(0, 300));
            } else {
                alert('서버 응답 형식 오류가 발생했습니다: ' + text.substring(0, 200));
            }
            throw parseError;
        }
        
        // 비동기 처리 확인
        if (result.processing) {
            // 작업이 시작되었고 처리 중임
            console.log('=== 음성 인식 작업 시작 ===');
            console.log('Consult ID:', result.consult_id);
            console.log('Operation Name:', result.operation_name);
            console.log('Poll URL:', result.poll_url);
            console.log('========================');
            
            updateStatus('음성 인식 처리 중...', 'processing');
            
            // 폴링 시작
            pollConsultStatus(result.consult_id, result.operation_name, result.poll_url);
        } else if (result.ok) {
            // 즉시 완료된 경우 (짧은 오디오)
            console.log('=== 업무협의록 저장 성공 ===');
            console.log('저장 ID:', result.id);
            console.log('제목:', result.title);
            console.log('전문 길이:', result.transcript?.length || 0, '자');
            console.log('요약 길이:', result.summary?.length || 0, '자');
            console.log('========================');
            
            alert('업무협의록이 성공적으로 생성되었습니다.\n저장 ID: ' + result.id + '\n제목: ' + result.title);
            updateStatus('완료', 'completed');
            
            // 페이지 리로드하여 리스트 갱신
            setTimeout(() => {
                window.location.reload();
            }, 1000);
        } else {
            let errorMsg = '오류 발생: ' + result.error;
            if (result.details) {
                errorMsg += '\n상세: ' + result.details;
            }
            if (result.curl_error) {
                errorMsg += '\nCURL 오류: ' + result.curl_error;
            }
            console.error('서버 오류 응답:', result);
            alert(errorMsg);
            updateStatus('오류', 'error');
        }
    } catch (e) {
        console.error('서버 통신 오류:', e);
        // JSON 파싱 오류인 경우 더 자세한 정보 표시
        if (e.message && e.message.includes('JSON')) {
            console.error('JSON 파싱 실패 - 서버 응답에 PHP 경고가 포함되어 있을 수 있습니다.');
            alert('서버 응답 오류가 발생했습니다. 페이지를 새로고침해주세요.');
        } else {
            alert('서버 통신 오류: ' + (e.message || '알 수 없는 오류'));
        }
        updateStatus('오류', 'error');
    } finally {
        document.getElementById('voiceloadingOverlay').style.display = 'none';
        saveBtn.disabled = false;
        saveBtn.innerHTML = originalBtnText;
    }
});

// 초기화: Recognition 핸들러 설정
if (SpeechRecognition) {
    initSpeechRecognition();
    setupRecognitionHandlers();
}

// 페이지 로드 시 로딩 오버레이 숨기기 및 전자결재 다이얼로그 닫기
document.addEventListener('DOMContentLoaded', function() {
    const voiceloadingOverlay = document.getElementById('voiceloadingOverlay');
    if (voiceloadingOverlay) {
        voiceloadingOverlay.style.display = 'none';
    }
    
    // 전자결재 다이얼로그 자동 닫기
    const eworksModal = document.getElementById('eworks_viewmodal');
    if (eworksModal) {
        eworksModal.style.display = 'none';
        eworksModal.classList.remove('show');
    }
    
    const eworksDialog = document.querySelector('#eworks_viewmodal .modal-dialog');
    if (eworksDialog) {
        eworksDialog.style.display = 'none';
    }
    
    // Bootstrap 모달 닫기
    if (typeof jQuery !== 'undefined' && jQuery('#eworks_viewmodal').length) {
        jQuery('#eworks_viewmodal').modal('hide');
    }
});

// 즉시 숨기기 (백업)
setTimeout(function() {
    const voiceloadingOverlay = document.getElementById('voiceloadingOverlay');
    if (voiceloadingOverlay) {
        voiceloadingOverlay.style.display = 'none';
    }
    
    // 전자결재 다이얼로그 강제 닫기
    const eworksModal = document.getElementById('eworks_viewmodal');
    if (eworksModal) {
        eworksModal.style.display = 'none';
        eworksModal.classList.remove('show');
        eworksModal.setAttribute('aria-hidden', 'true');
    }
    
    // 모든 모달 배경 제거
    const modalBackdrops = document.querySelectorAll('.modal-backdrop');
    modalBackdrops.forEach(function(backdrop) {
        backdrop.remove();
    });
    
    // body 클래스 정리
    document.body.classList.remove('modal-open');
    document.body.style.overflow = '';
    document.body.style.paddingRight = '';
}, 100);

// 업무협의록 상세보기
async function viewDetail(consultId) {
    try {
        const response = await fetch('get_consult.php?id=' + consultId);
        const text = await response.text();
        
        // JSON 파싱 전에 텍스트 확인
        let result;
        try {
            result = JSON.parse(text);
        } catch (parseError) {
            console.error('JSON 파싱 오류:', parseError);
            console.error('응답 텍스트:', text);
            alert('서버 응답 오류가 발생했습니다. 콘솔을 확인해주세요.');
            return;
        }
        
        if (result.ok) {
            document.getElementById('modal-title').textContent = result.data.title;
            document.getElementById('modal-transcript').textContent = result.data.transcript_text || '텍스트 없음';
            document.getElementById('modal-summary').textContent = result.data.summary_text || '요약 없음';
            document.getElementById('detail-modal').style.display = 'flex';
        } else {
            alert('데이터를 불러올 수 없습니다: ' + result.error);
        }
    } catch (error) {
        console.error(error);
        alert('서버 오류가 발생했습니다');
    }
}

// 모달 닫기
function closeModal() {
    document.getElementById('detail-modal').style.display = 'none';
}

// ESC 키로 모달 닫기
document.addEventListener('keydown', function(event) {
    if (event.key === 'Escape') {
        closeModal();
    }
});

// 모달 배경 클릭 시 닫기
document.getElementById('detail-modal')?.addEventListener('click', function(event) {
    if (event.target === this) {
        closeModal();
    }
});

// 삭제 확인 모달 관련 변수
let deleteConsultId = null;

// 삭제 확인 모달 열기
function confirmDelete(consultId, consultTitle) {
    deleteConsultId = consultId;
    document.getElementById('delete-meeting-title').textContent = consultTitle;
    document.getElementById('delete-modal').style.display = 'flex';
}

// 삭제 확인 모달 닫기
function closeDeleteModal() {
    document.getElementById('delete-modal').style.display = 'none';
    deleteConsultId = null;
}

// 업무협의록 삭제 실행
async function deleteMeeting() {
    if (!deleteConsultId) {
        alert('삭제할 업무협의록이 선택되지 않았습니다.');
        return;
    }
    
    try {
        const response = await fetch('delete_consult.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            body: 'id=' + deleteConsultId
        });
        
        const text = await response.text();
        let result;
        try {
            result = JSON.parse(text);
        } catch (parseError) {
            console.error('JSON 파싱 오류:', parseError);
            console.error('응답 텍스트:', text);
            alert('서버 응답 오류가 발생했습니다.');
            return;
        }
        
        if (result.ok) {
                alert('업무협의록이 삭제되었습니다.');
            closeDeleteModal();
            // 페이지 새로고침하여 목록 업데이트
            location.reload();
        } else {
            alert('삭제 실패: ' + result.error);
        }
    } catch (error) {
        console.error(error);
        alert('서버 오류가 발생했습니다');
    }
}

// ESC 키로 삭제 모달도 닫기
document.addEventListener('keydown', function(event) {
    if (event.key === 'Escape') {
        closeModal();
        closeDeleteModal();
    }
});

// 삭제 모달 배경 클릭 시 닫기
document.getElementById('delete-modal')?.addEventListener('click', function(event) {
    if (event.target === this) {
        closeDeleteModal();
    }
});

// 모바일 메뉴 초기화
function initMobileMenu() {
    const menuToggle = document.getElementById('mobile-menu-toggle');
    const menuClose = document.getElementById('mobile-menu-close');
    const menuSidebar = document.getElementById('mobile-menu-sidebar');
    const menuOverlay = document.getElementById('mobile-menu-overlay');
    const menuContent = document.querySelector('.mobile-menu-content .navbar-nav');
    const originalNav = document.querySelector('.navbar-custom .navbar-nav');

    // 원본 nav 내용을 모바일 메뉴로 복사
    if (originalNav && menuContent) {
        menuContent.innerHTML = originalNav.innerHTML;
        
        // 드롭다운 메뉴 토글 기능 추가
        const dropdownToggles = menuContent.querySelectorAll('.dropdown-toggle');
        dropdownToggles.forEach(toggle => {
            toggle.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
                const dropdown = this.nextElementSibling;
                if (dropdown && dropdown.classList.contains('dropdown-menu')) {
                    const isOpen = dropdown.classList.contains('show');
                    // 모든 드롭다운 닫기
                    menuContent.querySelectorAll('.dropdown-menu').forEach(menu => {
                        menu.classList.remove('show');
                    });
                    menuContent.querySelectorAll('.dropdown-toggle').forEach(tog => {
                        tog.setAttribute('aria-expanded', 'false');
                    });
                    // 클릭한 드롭다운 토글
                    if (!isOpen) {
                        dropdown.classList.add('show');
                        toggle.setAttribute('aria-expanded', 'true');
                    }
                }
            });
        });
    }

    // 메뉴 열기
    function openMenu() {
        menuSidebar.classList.add('active');
        menuOverlay.style.display = 'block';
        setTimeout(() => {
            menuOverlay.classList.add('active');
        }, 10);
        document.body.style.overflow = 'hidden';
        if (menuToggle) {
            menuToggle.innerHTML = '<i class="bi bi-x-lg"></i>';
            menuToggle.setAttribute('aria-label', '메뉴 닫기');
        }
    }

    // 메뉴 닫기
    function closeMenu() {
        menuSidebar.classList.remove('active');
        menuOverlay.classList.remove('active');
        setTimeout(() => {
            menuOverlay.style.display = 'none';
        }, 300);
        document.body.style.overflow = '';
        if (menuToggle) {
            menuToggle.innerHTML = '<i class="bi bi-list"></i>';
            menuToggle.setAttribute('aria-label', '메뉴 열기');
        }
    }

    // 메뉴 토글
    function toggleMenu() {
        const isOpen = menuSidebar.classList.contains('active');
        if (isOpen) {
            closeMenu();
        } else {
            openMenu();
        }
    }

    // 이벤트 리스너
    if (menuToggle) {
        menuToggle.addEventListener('click', toggleMenu);
    }
    if (menuClose) {
        menuClose.addEventListener('click', closeMenu);
    }
    if (menuOverlay) {
        menuOverlay.addEventListener('click', closeMenu);
    }
}

// 초기화
document.addEventListener('DOMContentLoaded', function() {
    initMobileMenu();
});

</script>

<!-- 디버그 패널 초기화 스크립트 -->
<script>
// 디버그 패널 초기화 (HTML 로드 후 확실하게 실행)
(function() {
    let isInitialized = false; // 중복 초기화 방지
    
    function initDebugPanelNow() {
        // 이미 초기화되었으면 중단
        if (isInitialized) {
            console.log('디버그 패널은 이미 초기화되었습니다.');
            return;
        }
        
        const debugPanel = document.getElementById('debug-panel');
        const debugToggleBtn = document.getElementById('debug-toggle-btn');
        const debugCloseBtn = document.getElementById('debug-close-btn');
        const debugClearBtn = document.getElementById('debug-clear-btn');
        const debugCopyBtn = document.getElementById('debug-copy-btn');
        const debugContent = document.getElementById('debug-content');
        
        if (!debugPanel || !debugContent || !debugToggleBtn) {
            console.warn('디버그 패널 요소를 찾을 수 없습니다. 재시도 중...');
            setTimeout(initDebugPanelNow, 100);
            return;
        }
        
        isInitialized = true; // 초기화 시작 표시
        console.log('디버그 패널 요소 찾음, 이벤트 리스너 등록 중...');
        
        // 디버그 패널 토글
        function toggleDebugPanel() {
            const isActive = debugPanel.classList.contains('active');
            if (isActive) {
                debugPanel.classList.remove('active');
                debugToggleBtn.classList.remove('active');
                console.log('디버그 패널 토글: 닫힘');
            } else {
                debugPanel.classList.add('active');
                debugToggleBtn.classList.add('active');
                console.log('디버그 패널 토글: 열림');
            }
        }
        
        // 로그 추가
        function addLog(message, type = 'log') {
            const logDiv = document.createElement('div');
            logDiv.className = `debug-log ${type}`;
            
            const timestamp = new Date().toLocaleTimeString('ko-KR');
            const logMessage = typeof message === 'object' ? JSON.stringify(message, null, 2) : String(message);
            
            logDiv.innerHTML = `<span style="color: #888; font-size: 10px;">[${timestamp}]</span> ${logMessage}`;
            
            debugContent.appendChild(logDiv);
            
            // 최대 로그 개수 제한
            while (debugContent.children.length > 100) {
                debugContent.removeChild(debugContent.firstChild);
            }
            
            // 자동 스크롤
            debugContent.scrollTop = debugContent.scrollHeight;
        }
        
        // 로그 지우기
        function clearLogs() {
            debugContent.innerHTML = '<div class="debug-log info">로그가 지워졌습니다.</div>';
        }
        
        // 로그 복사
        async function copyLogs() {
            try {
                // 모든 로그 요소 수집
                const logElements = Array.from(debugContent.children);
                
                if (logElements.length === 0) {
                    console.warn('복사할 로그가 없습니다.');
                    return;
                }
                
                let logText = `=== 디버그 로그 ===\n생성 시간: ${new Date().toLocaleString('ko-KR')}\n로그 개수: ${logElements.length}\n==================\n\n`;
                
                logElements.forEach((logEl, index) => {
                    // 타임스탬프와 메시지 추출
                    const logContent = logEl.textContent || logEl.innerText;
                    const logType = logEl.className.includes('error') ? '[ERROR]' :
                                   logEl.className.includes('warn') ? '[WARN]' :
                                   logEl.className.includes('info') ? '[INFO]' :
                                   '[LOG]';
                    
                    logText += `${index + 1}. ${logType} ${logContent}\n`;
                });

                // 클립보드에 복사
                if (navigator.clipboard && navigator.clipboard.writeText) {
                    await navigator.clipboard.writeText(logText);
                    
                    // 복사 성공 피드백
                    const originalIcon = debugCopyBtn.innerHTML;
                    debugCopyBtn.innerHTML = '<i class="bi bi-check"></i>';
                    debugCopyBtn.style.background = 'rgba(76, 175, 80, 0.3)';
                    
                    console.log('✅ 로그가 클립보드에 복사되었습니다.');
                    
                    // 2초 후 원래 아이콘으로 복원
                    setTimeout(() => {
                        debugCopyBtn.innerHTML = originalIcon;
                        debugCopyBtn.style.background = '';
                    }, 2000);
                } else {
                    // 클립보드 API를 사용할 수 없는 경우 대체 방법
                    const textArea = document.createElement('textarea');
                    textArea.value = logText;
                    textArea.style.position = 'fixed';
                    textArea.style.left = '-999999px';
                    document.body.appendChild(textArea);
                    textArea.select();
                    
                    try {
                        document.execCommand('copy');
                        console.log('✅ 로그가 클립보드에 복사되었습니다. (대체 방법)');
                        
                        // 복사 성공 피드백
                        const originalIcon = debugCopyBtn.innerHTML;
                        debugCopyBtn.innerHTML = '<i class="bi bi-check"></i>';
                        debugCopyBtn.style.background = 'rgba(76, 175, 80, 0.3)';
                        
                        setTimeout(() => {
                            debugCopyBtn.innerHTML = originalIcon;
                            debugCopyBtn.style.background = '';
                        }, 2000);
                    } catch (err) {
                        console.error('복사 실패:', err);
                        alert('복사에 실패했습니다. 로그를 수동으로 선택하여 복사해주세요.');
                    } finally {
                        document.body.removeChild(textArea);
                    }
                }
            } catch (error) {
                console.error('로그 복사 중 오류 발생:', error);
                alert('로그 복사 중 오류가 발생했습니다: ' + error.message);
            }
        }
        
        // 이벤트 리스너 등록 (중복 방지)
        // 기존 리스너가 있는지 확인하고 제거
        if (debugToggleBtn._debugListener) {
            debugToggleBtn.removeEventListener('click', debugToggleBtn._debugListener);
        }
        
        debugToggleBtn._debugListener = function(e) {
            e.preventDefault();
            e.stopPropagation();
            console.log('디버그 버튼 클릭됨');
            toggleDebugPanel();
        };
        debugToggleBtn.addEventListener('click', debugToggleBtn._debugListener);
        
        if (debugCloseBtn) {
            if (debugCloseBtn._debugListener) {
                debugCloseBtn.removeEventListener('click', debugCloseBtn._debugListener);
            }
            debugCloseBtn._debugListener = function(e) {
                e.preventDefault();
                e.stopPropagation();
                toggleDebugPanel();
            };
            debugCloseBtn.addEventListener('click', debugCloseBtn._debugListener);
        }
        
        if (debugClearBtn) {
            if (debugClearBtn._debugListener) {
                debugClearBtn.removeEventListener('click', debugClearBtn._debugListener);
            }
            debugClearBtn._debugListener = function(e) {
                e.preventDefault();
                e.stopPropagation();
                clearLogs();
            };
            debugClearBtn.addEventListener('click', debugClearBtn._debugListener);
        }
        
        if (debugCopyBtn) {
            if (debugCopyBtn._debugListener) {
                debugCopyBtn.removeEventListener('click', debugCopyBtn._debugListener);
            }
            debugCopyBtn._debugListener = function(e) {
                e.preventDefault();
                e.stopPropagation();
                copyLogs();
            };
            debugCopyBtn.addEventListener('click', debugCopyBtn._debugListener);
        }
        
        // console 오버라이드 (모바일에서도 오류 기록)
        // 기존 console 함수 백업
        const originalConsole = {
            log: console.log.bind(console),
            info: console.info.bind(console),
            warn: console.warn.bind(console),
            error: console.error.bind(console)
        };

        // console 오버라이드 함수
        const overrideConsole = function() {
            console.log = function(...args) {
                originalConsole.log(...args);
                try {
                    const message = args.map(arg => {
                        if (typeof arg === 'object') {
                            try {
                                return JSON.stringify(arg, null, 2);
                            } catch (e) {
                                return String(arg);
                            }
                        }
                        return String(arg);
                    }).join(' ');
                    addLog(message, 'log');
                } catch (e) {
                    originalConsole.error('디버그 패널 로그 추가 실패:', e);
                }
            };

            console.info = function(...args) {
                originalConsole.info(...args);
                try {
                    const message = args.map(arg => {
                        if (typeof arg === 'object') {
                            try {
                                return JSON.stringify(arg, null, 2);
                            } catch (e) {
                                return String(arg);
                            }
                        }
                        return String(arg);
                    }).join(' ');
                    addLog(message, 'info');
                } catch (e) {
                    originalConsole.error('디버그 패널 로그 추가 실패:', e);
                }
            };

            console.warn = function(...args) {
                originalConsole.warn(...args);
                try {
                    const message = args.map(arg => {
                        if (typeof arg === 'object') {
                            try {
                                return JSON.stringify(arg, null, 2);
                            } catch (e) {
                                return String(arg);
                            }
                        }
                        return String(arg);
                    }).join(' ');
                    addLog(message, 'warn');
                } catch (e) {
                    originalConsole.error('디버그 패널 로그 추가 실패:', e);
                }
            };

            console.error = function(...args) {
                originalConsole.error(...args);
                try {
                    const message = args.map(arg => {
                        if (typeof arg === 'object') {
                            try {
                                return JSON.stringify(arg, null, 2);
                            } catch (e) {
                                return String(arg);
                            }
                        }
                        return String(arg);
                    }).join(' ');
                    addLog(message, 'error');
                } catch (e) {
                    originalConsole.error('디버그 패널 로그 추가 실패:', e);
                }
            };
        };
        
        // 즉시 오버라이드 실행
        overrideConsole();
        
        // 전역 에러 핸들러 (처리되지 않은 오류 캡처)
        window.addEventListener('error', function(event) {
            addLog(`[Uncaught Error] ${event.message} at ${event.filename}:${event.lineno}:${event.colno}`, 'error');
            if (event.error && event.error.stack) {
                addLog(`Stack: ${event.error.stack}`, 'error');
            }
        });
        
        // Promise rejection 핸들러 (처리되지 않은 Promise 오류 캡처)
        window.addEventListener('unhandledrejection', function(event) {
            addLog(`[Unhandled Promise Rejection] ${event.reason}`, 'error');
            if (event.reason && event.reason.stack) {
                addLog(`Stack: ${event.reason.stack}`, 'error');
            }
        });
        
        // 전역 함수로 export
        window.debugLog = addLog;
        window.clearDebugLogs = clearLogs;
        window.copyDebugLogs = copyLogs;
        window.toggleDebugPanel = toggleDebugPanel;
        
        // 초기 메시지
        addLog('디버그 패널이 활성화되었습니다.', 'info');
        addLog('모바일에서도 콘솔 로그를 확인할 수 있습니다.', 'info');
        addLog('모든 console.log, console.error 등이 여기에 기록됩니다.', 'info');
        
        console.log('✅ 디버그 패널 초기화 완료');
    }
    
    // 즉시 실행 또는 DOMContentLoaded 후 실행
    // 모바일에서도 빠르게 초기화되도록 즉시 시도
    function tryInit() {
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', function() {
                // 모바일에서는 더 빠르게 초기화
                setTimeout(initDebugPanelNow, 50);
            });
            // DOMContentLoaded 전에도 시도 (요소가 이미 있을 수 있음)
            setTimeout(initDebugPanelNow, 50);
        } else {
            // 이미 로드된 경우 즉시 실행
            setTimeout(initDebugPanelNow, 50);
        }
    }
    
    // 즉시 시도
    tryInit();
    
    // 모바일에서는 추가로 재시도
    if (isMobileDevice()) {
        setTimeout(initDebugPanelNow, 200);
        setTimeout(initDebugPanelNow, 500);
    }
})();
</script>

<?php
// 출력 버퍼 flush
ob_end_flush();
?>
</body>
</html>