
   <!DOCTYPE html>
<!-- TEMPLATE GENERATED AT: 1769772154.6960351 -->
<html lang="en"
    data-fresh-server-start="{{ is_fresh_server_start|lower }}"
    data-augmented-mode="{{ augmented_mode|default(false)|lower }}"
    data-session-id="{{ session_id }}"
    >
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="Permissions-Policy" content="payment=()">
    <title>{{ title }}</title>

    <style>        
        /* ===== CSS VARIABLES ===== */
        :root {
            --base-font-size: 16px;
            --small-font-size: calc(var(--base-font-size) * 0.8);
            --large-font-size: calc(var(--base-font-size) * 1.2);
            --extra-large-font-size: calc(var(--base-font-size) * 1.5);
            --section-spacing: 30px;
            --form-spacing: 15px;
            --container-padding: 20px;
        }

        /* ===== BASE STYLES ===== */
        body { 
            font-family: Arial, sans-serif; 
            margin: 20px; 
            background-color: #f5f5f5; 
            font-size: var(--base-font-size);
        }

        .container { 
            max-width: 1200px; 
            margin: 0 auto; 
            background: white; 
            padding: var(--container-padding); 
            border-radius: 8px;
            transform: scale(1.0);
            transform-origin: top left;
            width: 100%;
        }

        /* ===== HEADER STYLES (COLLAPSIBLE) ===== */
        .header { 
            text-align: center; 
            margin-bottom: var(--section-spacing);
            cursor: pointer;
            user-select: none;
            transition: all 0.3s ease;
            position: relative;
        }

        .header:hover {
            background-color: #f8f9fa;
            border-radius: 4px;
            padding: 5px;
        }

        .header.collapsed {
            display: none !important;
        }

        .header::after {
            content: "Double-click to hide header and gain more workspace";
            position: absolute;
            bottom: -25px;
            left: 50%;
            transform: translateX(-50%);
            background: rgba(0,0,0,0.8);
            color: white;
            padding: 4px 8px;
            border-radius: 4px;
            font-size: 11px;
            white-space: nowrap;
            opacity: 0;
            transition: opacity 0.3s ease;
            pointer-events: none;
            z-index: 100;
        }

        .header:hover::after {
            opacity: 1;
        }

        .header-collapsed-indicator {
            display: none;
            position: fixed;
            top: 15px;
            right: 15px;
            background: linear-gradient(45deg, #007bff, #0056b3);
            color: white;
            padding: 8px 15px;
            border-radius: 20px;
            font-size: 12px;
            font-weight: bold;
            z-index: 1000;
            box-shadow: 0 2px 8px rgba(0,0,0,0.2);                    
            opacity: 0;
            transition: opacity 0.3s ease;
            pointer-events: none;
        }

        .header-collapsed-indicator.show {
            display: block;
            opacity: 1;
        }

        /* ===== SECTION STYLES ===== */
        .section { 
            margin-bottom: var(--section-spacing); 
            border: 1px solid #ddd; 
            border-radius: 8px; 
            padding: 15px; 
        }

        .section h3 { 
            margin-top: 0; 
            color: #333; 
            font-size: var(--large-font-size);
            cursor: pointer;
            user-select: none;
        }

        .section.first-visible {
            border-top: 3px solid #007bff;
            position: relative;
        }

        .section.first-visible::before {
            content: "Double-click to restore header";
            position: absolute;
            top: -25px;
            left: 50%;
            transform: translateX(-50%);
            background: #007bff;
            color: white;
            padding: 2px 8px;
            border-radius: 10px;
            font-size: 10px;
            opacity: 0;
            transition: opacity 0.3s ease;
            pointer-events: none;
        }

        .section.first-visible:hover::before {
            opacity: 1;
        }

        .section.first-visible .section-header,
        .section.first-visible > .section-header h3,
        .section.first-visible > h3 {
            cursor: pointer !important;
            user-select: none !important;
        }

        .section.first-visible > .section-header h3:hover,
        .section.first-visible > h3:hover {
            color: #007bff !important;
            transform: scale(1.02);
            transition: all 0.2s ease;
        }

        .section-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
            gap: 15px;
        }

        .section-header h3 {
            margin: 0;
            flex-shrink: 0;
        }

        .header-buttons {
            display: flex;
            gap: 6px;
            align-items: center;
            flex-shrink: 0;
        }

        .upload-section {
            margin-bottom: calc(var(--section-spacing) * 0.3);
        }

        .chat-section {
            margin-bottom: calc(var(--section-spacing) * 0.3);
        }

        /* ===== MODE MANAGEMENT ===== */
        /* ADD THIS: */
        body.augmented-mode #user-directive-container {
            display: block !important;
        }

        .normal-mode-only {
            display: block;
        }

        .user-code-indicator {
                    display: inline-block;
                    font-size: 16px;
                    font-weight: bold;
                    color: #fff;
                    background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
                    padding: 2px 8px;
                    border-radius: 12px;
                    margin-left: 8px;
                    box-shadow: 0 2px 4px rgba(0,0,0,0.2);
                }
        .expiration-warning {
            font-size: 0.5em;
            color: #ff6600;
            font-weight: normal;
            margin-left: 10px;
        }

                
                .powered-by {
                    display: block;
                    font-size: 16px;
                    font-weight: bold;
                    color: #888;
                    margin-top: 5px;
                }
                
                .powered-by a {
                    color: #007bff;
                    text-decoration: none;
                }
                
                .powered-by a:hover {
                    text-decoration: underline;
                }
                .mode-indicator {
            display: inline-block;
            padding: 4px 8px;
            border-radius: 4px;
            font-size: 12px;
            font-weight: bold;
            margin-left: 10px;
        }

        .normal-mode {
            background: #d4edda;
            color: #155724;
        }

        /* ADD THIS NEW STYLE */
        .augmented-mode {
            background: #fff3cd;
            color: #856404;
            border: 2px solid #ffc107;
        }

        /* Update body class handling for augmented mode */
        body.augmented-mode .container {
            /* Optional: Add specific styling for augmented mode */
        }

        /* ===== BUTTON STYLES ===== */
        .new-start-btn {
            background: linear-gradient(45deg, #28a745 0%, #20c997 100%);
            color: white;
            border: none;
            padding: 5px 12px;
            border-radius: 4px;
            font-weight: bold;
            cursor: pointer;
            transition: all 0.3s ease;
            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
            font-size: calc(var(--small-font-size) * 0.9);
        }

        .new-start-btn:hover {
            transform: translateY(-1px);
            box-shadow: 0 4px 8px rgba(0,0,0,0.2);
            background: linear-gradient(45deg, #218838 0%, #1ea085 100%);
        }

        .window-augment-btn {
            background: linear-gradient(45deg, #4facfe 0%, #00f2fe 100%);
            color: white;
            border: none;
            padding: 5px 12px;
            border-radius: 4px;
            font-weight: bold;
            cursor: pointer;
            transition: all 0.3s ease;
            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
            font-size: calc(var(--small-font-size) * 0.9);
        }

        .window-augment-btn:hover {
            transform: translateY(-1px);
            box-shadow: 0 4px 8px rgba(0,0,0,0.2);
        }

        .clear-session-btn {
            background: #dc3545;
            color: white;
        }

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

        .clear-direction-btn {
            padding: 2px 6px;
            background: #dc3545;
            color: white;
            border: none;
            border-radius: 3px;
            cursor: pointer;
            font-size: 12px;
        }

        .clear-direction-btn:hover {
            background: #c82333;
        }

        .clear-btn {
            padding: 2px 6px;
            background: #dc3545;
            color: white;
            border: none;
            border-radius: 3px;
            cursor: pointer;
            font-size: var(--small-font-size);
        }

        .clear-btn:hover {
            background: #c82333;
        }
        
        /* 문서 선택 버튼 스타일 */
        .doc-filter-btn {
            background: linear-gradient(135deg, #3498db 0%, #2980b9 100%);
            color: white;
            border: none;
            padding: 6px 12px;
            border-radius: 6px;
            cursor: pointer;
            font-size: 13px;
            font-weight: 500;
            transition: all 0.2s ease;
        }
        .doc-filter-btn:hover {
            background: linear-gradient(135deg, #2980b9 0%, #1a5276 100%);
            transform: translateY(-1px);
        }
        .doc-filter-btn.has-filter {
            background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%);
        }
        
        /* 문서 선택 모달 스타일 */
        .doc-filter-modal {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            z-index: 10000;
            justify-content: center;
            align-items: center;
        }
        .doc-filter-modal.show {
            display: flex;
        }
        .doc-filter-content {
            background: white;
            border-radius: 12px;
            padding: 24px;
            max-width: 500px;
            width: 90%;
            max-height: 80vh;
            overflow-y: auto;
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
        }
        .doc-filter-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 16px;
            padding-bottom: 12px;
            border-bottom: 1px solid #eee;
        }
        .doc-filter-header h3 {
            margin: 0;
            font-size: 18px;
            color: #333;
        }
        .doc-filter-close {
            background: none;
            border: none;
            font-size: 24px;
            cursor: pointer;
            color: #666;
            padding: 0;
            line-height: 1;
        }
        .doc-filter-close:hover {
            color: #333;
        }
        .doc-filter-list {
            margin-bottom: 16px;
        }
        .doc-filter-item {
            display: flex;
            align-items: center;
            padding: 10px 12px;
            margin-bottom: 8px;
            background: #f8f9fa;
            border-radius: 8px;
            cursor: pointer;
            transition: background 0.2s;
        }
        .doc-filter-item:hover {
            background: #e9ecef;
        }
        .doc-filter-item input[type="checkbox"] {
            margin-right: 12px;
            width: 18px;
            height: 18px;
            cursor: pointer;
        }
        .doc-filter-item label {
            cursor: pointer;
            flex: 1;
            font-size: 14px;
            word-break: break-all;
        }
        .doc-filter-actions {
            display: flex;
            gap: 12px;
            justify-content: flex-end;
            padding-top: 12px;
            border-top: 1px solid #eee;
        }
        .doc-filter-actions button {
            padding: 8px 16px;
            border-radius: 6px;
            font-size: 14px;
            cursor: pointer;
            transition: all 0.2s;
        }
        .doc-filter-select-all {
            background: #f8f9fa;
            border: 1px solid #ddd;
            color: #333;
        }
        .doc-filter-select-all:hover {
            background: #e9ecef;
        }
        .doc-filter-apply {
            background: #3498db;
            border: none;
            color: white;
        }
        .doc-filter-apply:hover {
            background: #2980b9;
        }
        .doc-filter-clear {
            background: #e74c3c;
            border: none;
            color: white;
        }
        .doc-filter-clear:hover {
            background: #c0392b;
        }
        .doc-filter-status {
            font-size: 12px;
            color: #666;
            margin-top: 8px;
            text-align: center;
        }
        
        /* 대화하기 섹션 헤더 버튼 스타일 */
        .chat-header-buttons {
            display: flex;
            gap: 8px;
            margin-left: auto;
        }

        .chat-header-btn {
            padding: 4px 10px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: var(--small-font-size);
            font-weight: bold;
            transition: all 0.2s;
        }

        .save-btn {
            background: linear-gradient(45deg, #28a745 0%, #20c997 100%);
            color: white;
        }

        .save-btn:hover {
            background: linear-gradient(45deg, #218838 0%, #1aa179 100%);
            transform: translateY(-1px);
            box-shadow: 0 2px 4px rgba(0,0,0,0.15);
        }

        .btn { 
            padding: 10px 20px; 
            margin: 5px; 
            border: none; 
            border-radius: 4px; 
            cursor: pointer; 
            text-decoration: none; 
            display: inline-block; 
            font-size: var(--small-font-size);
        }

        .btn-primary { background: #007bff; color: white; }
        .btn-danger { background: #dc3545; color: white; }
        .btn-secondary { background: #6c757d; color: white; }
        .btn-success { background: #28a745; color: white; }

        /* ===== COPY BUTTONS ===== */
        .copy-btn {
            padding: 4px 8px;
            border: none;
            border-radius: 3px;
            cursor: pointer;
            font-size: 14px;
            font-weight: bold;
            margin-right: 5px;
            transition: all 0.2s ease;
            min-width: 28px;
            height: 24px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
        }

        .copy-up-btn {
            background: linear-gradient(45deg, #28a745 0%, #20c997 100%);
            color: white;
            border: 1px solid #1e7e34;
        }

        .copy-up-btn:hover {
            background: linear-gradient(45deg, #218838 0%, #1ea085 100%);
            transform: translateY(-1px);
            box-shadow: 0 2px 4px rgba(0,0,0,0.2);
        }

        .copy-up-btn:active {
            transform: translateY(0);
            box-shadow: 0 1px 2px rgba(0,0,0,0.2);
        }

        .copy-down-btn {
            background: linear-gradient(45deg, #ffc107 0%, #fd7e14 100%);
            color: #212529;
            border: 1px solid #e0a800;
        }

        .copy-down-btn:hover {
            background: linear-gradient(45deg, #e0a800 0%, #e8590c 100%);
            transform: translateY(-1px);
            box-shadow: 0 2px 4px rgba(0,0,0,0.2);
        }

        .copy-down-btn:active {
            transform: translateY(0);
            box-shadow: 0 1px 2px rgba(0,0,0,0.2);
        }

        .copy-btn:disabled {
            background: #6c757d !important;
            color: #fff !important;
            cursor: not-allowed !important;
            transform: none !important;
            box-shadow: none !important;
            opacity: 0.6;
        }

        .copy-btn.copying {
            background: #17a2b8 !important;
            color: white !important;
        }

        /* ===== TOGGLE BUTTONS ===== */
        .toggle-buttons-row {
            display: flex;
            gap: 20px;
            margin-bottom: var(--form-spacing);
            flex-wrap: wrap;
            padding: 15px;
            background: #f8f9fa;
            border-radius: 8px;
            border: 1px solid #dee2e6;
        }

        .toggle-group { 
            display: flex; 
            align-items: center; 
            gap: 8px; 
        }

        .toggle-group label { 
            font-weight: bold; 
            color: #333; 
            margin: 0; 
        }

        .toggle-btn {
            padding: 6px 16px;
            border: 2px solid;
            border-radius: 20px;
            font-weight: bold;
            font-size: var(--small-font-size);
            cursor: pointer;
            transition: all 0.2s ease;
            min-width: 50px;
            text-transform: uppercase;
            background: none;
        }

        .toggle-btn:hover { 
            transform: translateY(-1px); 
            box-shadow: 0 2px 4px rgba(0,0,0,0.1); 
        }

        .toggle-on { 
            background: #28a745; 
            color: white; 
            border-color: #28a745; 
        }

        .toggle-on:hover { 
            background: #218838; 
            border-color: #218838; 
        }

        .toggle-off { 
            background: #6c757d; 
            color: white; 
            border-color: #6c757d; 
        }

        .toggle-off:hover { 
            background: #545b62; 
            border-color: #545b62; 
        }

        .toggle-btn:active { 
            transform: translateY(0); 
        }

        .enf-webs-on { 
            background: #DAA520; 
            color: white; 
            border-color: #B8860B; 
        }

        .enf-webs-on:hover { 
            background: #B8860B; 
            border-color: #9A7209; 
        }

        /* ===== FONT SIZE & SPACING CONTROLS ===== */
        .controls-row {
            display: flex;
            gap: 20px;
            margin-bottom: var(--form-spacing);
            flex-wrap: wrap;
        }

        .font-size-control, .spacing-control {
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 10px;
            border-radius: 6px;
            border: 1px solid;
            flex: 1;
            min-width: 300px;
        }

        .font-size-control {
            background: #f8f9fa;
            border-color: #dee2e6;
        }

        .spacing-control {
            background: #f0f9ff;
            border-color: #bee3f8;
        }

        .font-size-btn {
            background: #6c757d;
            color: white;
            border: none;
            border-radius: 4px;
            width: 35px;
            height: 35px;
            font-size: 18px;
            font-weight: bold;
            cursor: pointer;
            transition: background-color 0.2s;
        }

        .font-size-btn:hover {
            background: #545b62;
        }

        .font-size-display {
            font-family: monospace;
            font-weight: bold;
            color: #495057;
            min-width: 60px;
            text-align: center;
        }

        .spacing-btn {
            background: #3182ce;
            color: white;
            border: none;
            border-radius: 4px;
            width: 35px;
            height: 35px;
            font-size: 18px;
            font-weight: bold;
            cursor: pointer;
            transition: background-color 0.2s;
        }

        .spacing-btn:hover {
            background: #2c5aa0;
        }

        .spacing-display {
            font-family: monospace;
            font-weight: bold;
            color: #2d3748;
            min-width: 60px;
            text-align: center;
        }

        /* ===== FORM STYLES ===== */
        .form-group { 
            margin-bottom: var(--form-spacing); 
        }

        .form-group label { 
            display: block; 
            margin-bottom: 5px; 
            font-weight: bold; 
        }

        .form-group input, .form-group select, .form-group textarea { 
            width: 100%; 
            padding: 8px; 
            border: 1px solid #000; 
            border-radius: 4px; 
            box-sizing: border-box; 
            font-size: calc(var(--base-font-size) * 0.9);
        }

        .form-group select { 
            display: block !important; 
            visibility: visible !important; 
            min-height: 30px; 
            background: #fff; 
            color: #000; 
        }

        .form-group input[type="range"] { 
            width: 100%; 
            padding: 0; 
            cursor: pointer; 
        }

        .form-group .range-value { 
            display: inline-block; 
            margin-left: 10px; 
            color: #333; 
        }

        .form-group textarea { 
            height: 100px; 
            resize: vertical; 
        }

        .form-row { 
            display: flex; 
            gap: 15px; 
            align-items: flex-end; 
            flex-wrap: wrap; 
            margin-bottom: var(--form-spacing);
        }

        .form-row .form-group { 
            flex: 1; 
            min-width: 150px;
            margin-bottom: 0;
        }

        .form-row .form-group label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
            font-size: var(--small-font-size);
        }

        .form-row .form-group select {
            width: 100%;
            padding: 8px;
            border: 1px solid #000;
            border-radius: 4px;
            box-sizing: border-box;
            font-size: calc(var(--base-font-size) * 0.9);
            background: #fff;
            color: #000;
            display: block !important;
            visibility: visible !important;
            min-height: 30px;
        }

        .form-row button { 
            align-self: flex-end; 
        }

        .upload-section .form-group {
            margin-bottom: 8px;
        }

        /* ===== QUERY INPUT ===== */
        label[for="query"] {
            display: inline-block;
            margin-right: 15px;
            vertical-align: top;
        }

        #chat-progress {
            display: inline-block;
            vertical-align: top;
            max-width: 350px;
        }

        #chat-progress .progress-bar-container {
            height: 5px !important;
        }

        .history-textarea {
            font-family: inherit;
            background-color: #fff;
            border: 2px solid #ddd;
            transition: border-color 0.2s, background-color 0.2s;
            min-height: 80px;
        }

        .history-textarea:focus { 
            outline: none; 
            border-color: #007bff; 
        }

        .history-textarea.navigating { 
            border-color: #28a745; 
            background-color: #f8fff8; 
        }

        .query-help { 
            color: #666; 
            margin-top: 5px; 
            font-style: italic; 
            font-size: var(--small-font-size); 
        }

        /* ===== USER DIRECTIVE ===== */                        
        .user-directive-container {
            display: none;
            margin-bottom: 15px;
        }

        .user-directive-container.show {
            display: block;
        }

        .user-directive-input {
            background-color: #fff8e1;
            border: 2px solid #ffc107;
            border-radius: 4px;
            min-height: 60px;
            font-family: inherit;
        }

        .user-directive-input:focus {
            outline: none;
            border-color: #ff8f00;
            background-color: #fff9e6;
        }

        .directive-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 5px;
        }

        .directive-header label {
            margin: 0;
            font-weight: bold;
        }

        /* ===== CONFIG & THRESHOLD ===== */
        .config-form {
            background: #f8f9fa;
            border: 1px solid #dee2e6;
            border-radius: 6px;
            padding: 15px;
            margin-top: 15px;
        }

        .config-form h4 {
            margin: 0 0 15px 0;
            color: #495057;
            font-size: var(--large-font-size);
        }

        .config-row {
            display: flex;
            gap: 20px;
            align-items: flex-end;
            flex-wrap: wrap;
            margin-bottom: 10px;
        }

        .config-row .form-group {
            flex: 1;
            min-width: 200px;
        }

        .threshold-display {
            font-family: monospace;
            font-weight: bold;
            color: #007bff;
            margin-left: 8px;
        }

        .threshold-control {
            display: flex;
            align-items: center;
            gap: 8px;
            margin-top: 5px;
        }

        .threshold-btn {
            background: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            width: 30px;
            height: 30px;
            font-weight: bold;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: background-color 0.2s;
            font-size: var(--large-font-size);
        }

        .threshold-btn:hover {
            background: #0056b3;
        }

        .threshold-btn:active {
            transform: translateY(1px);
        }

        .threshold-control input[type="range"] {
            flex: 1;
            margin: 0 8px;
        }

        .warning-box {
            background: #fff3cd;
            border: 1px solid #ffeaa7;
            border-radius: 4px;
            padding: 8px;
            margin-top: 8px;
            color: #856404;
            font-size: var(--small-font-size);
        }

        /* ===== FILE MANAGEMENT ===== */
        .files-table { 
            width: 100%; 
            border-collapse: collapse; 
            margin-top: 15px; 
        }

        .files-table th, .files-table td { 
            padding: 10px; 
            border: 1px solid #ddd; 
            text-align: left; 
        }

        .files-table th { 
            background-color: #f8f9fa; 
        }

        .files-table tr:nth-child(even) { 
            background-color: #f2f2f2; 
        }

        .files-table tr.selected { 
            background-color: #cce5ff; 
        }

        .file-path { 
            color: #666; 
            font-family: monospace; 
            word-break: break-all; 
            font-size: var(--small-font-size); 
        }

        .file-name { 
            font-weight: bold; 
            margin-bottom: 3px; 
        }

        .file-details { 
            color: #666; 
            margin-bottom: 3px; 
            font-size: var(--small-font-size); 
        }

        .file-info-cell { 
            padding: 8px; 
            border: 1px solid #ddd; 
            min-width: 300px; 
        }

        .full-path { 
            background: #f8f9fa; 
            padding: 2px 4px; 
            border-radius: 2px; 
            margin-top: 2px; 
        }

        /* ===== BULK ACTIONS & ANALYSIS ===== */
        .bulk-actions {
            margin-top: 10px;
            display: flex;
            flex-wrap: wrap;
            gap: 15px;
            align-items: center;
        }

        .bulk-actions-buttons {
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
            align-items: center;
        }

        .bulk-actions-buttons form {
            display: inline-block;
            margin: 0;
        }

        .analyze-section {
            display: flex;
            align-items: center;
            gap: 15px;
            flex-wrap: wrap;
        }

        .analyze-section button {
            margin: 0 !important;
        }

        #analyze-progress {
            margin: 0;
        }

        .document-status-display {
            display: inline-flex;
            align-items: center;
        }

        /* ===== CHAT HISTORY ===== */
        .chat-history { 
            height: 400px;
            min-height: 150px;
            max-height: 80vh;
            overflow-y: auto; 
            border: 1px solid #ddd; 
            padding: 15px; 
            background: #fafafa; 
            user-select: text;
            resize: vertical;
        }

        .message { 
            margin-bottom: 15px; 
            padding: 10px; 
            border-radius: 4px; 
        }

        .human-message { background: #e3f2fd; }
        .ai-message { background: #f1f8e9; }

        /* ===== STATUS INDICATORS ===== */
        .status { 
            padding: 10px; 
            margin-bottom: 15px; 
            border-radius: 4px; 
        }

        .status.success { background: #d4edda; color: #155724; }
        .status.error { background: #f8d7da; color: #721c24; }
        .status.info { background: #d1ecf1; color: #0c5460; }


        .session-info { 
            font-family: monospace; 
            color: #666; 
            margin-bottom: 10px; 
            font-size: var(--small-font-size); 
        }

        /* ===== PROGRESS BARS ===== */
        .progress-modal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 1000;
        }

        .progress-content {
            background: white;
            padding: 30px;
            border-radius: 8px;
            min-width: 400px;
            text-align: center;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
        }

        .progress-bar-container {
            width: 100%;
            height: 20px;
            background: #f0f0f0;
            border-radius: 10px;
            margin: 20px 0;
            overflow: hidden;
        }

        .progress-bar {
            height: 100%;
            background: linear-gradient(45deg, #007bff, #0056b3);
            border-radius: 10px;
            transition: width 0.3s ease;
        }

        .progress-text {
            font-weight: bold;
            margin-bottom: 10px;
        }

        .progress-details {
            color: #666;
            font-size: var(--small-font-size);
        }

        /* ===== MOVE BUTTON ===== */
        .move-button-container {
            margin: 10px 0;
            text-align: center;
            padding: 10px;
            background: #f8f9fa;
            border-radius: 4px;
            border: 1px solid #dee2e6;
        }

        .move-button-container button {
            margin: 0;
            transition: all 0.3s ease;
        }

        .move-button-container button:disabled {
            background: #6c757d;
            cursor: not-allowed;
            opacity: 0.6;
        }

        .move-button-container button:not(:disabled) {
            background: #28a745;
            animation: pulse 2s infinite;
        }

        .move-status-text {
            display: block;
            margin-top: 5px;
            font-size: var(--small-font-size);
            color: #666;
            font-style: italic;
        }

        /* ===== MESSAGE DIALOG ===== */
        .message-dialog {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: white;
            border: none;
            border-radius: 8px;
            box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
            z-index: 1000;
            min-width: 220px;
            max-width: 300px;
            padding: 0;
            opacity: 0;
            transition: all 0.3s ease;
            overflow: hidden;
        }

        .message-dialog.show {
            opacity: 1;
        }

        .message-dialog.dragging {
            transition: none;
        }

        .message-dialog-header {
            background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
            padding: 8px 12px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            cursor: move;
            user-select: none;
        }

        .dialog-title {
            font-weight: 600;
            font-size: 12px;
            color: white;
        }

        .message-dialog-close {
            background: rgba(255, 255, 255, 0.2);
            border: none;
            font-size: 14px;
            font-weight: bold;
            color: white;
            cursor: pointer;
            padding: 2px;
            width: 20px;
            height: 20px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 3px;
            transition: all 0.2s ease;
        }

        .message-dialog-close:hover {
            background: rgba(255, 255, 255, 0.3);
        }

        .message-dialog-content {
            padding: 12px 16px;
            text-align: center;
            cursor: default;
        }

        .message-dialog-text {
            font-size: 13px;
            font-weight: 500;
            margin: 0;
            color: #2d3748;
            line-height: 1.4;
        }

        .message-dialog-success .message-dialog-header {
            background: linear-gradient(135deg, #48bb78 0%, #38a169 100%);
        }

        .message-dialog-info .message-dialog-header {
            background: linear-gradient(135deg, #4299e1 0%, #3182ce 100%);
        }

        .message-dialog::backdrop {
            background: rgba(0, 0, 0, 0.1);
        }

        /* ===== UTILITY CLASSES ===== */
        .no-select {
            user-select: none !important;
            -webkit-user-select: none !important;
            -moz-user-select: none !important;
            -ms-user-select: none !important;
        }

        pre, code {
            font-size: calc(var(--base-font-size) * 0.9) !important;
        }

        pre code {
            font-size: inherit !important;
        }

        /* ===== ANIMATIONS ===== */
        @keyframes fadeInOut {
            0%, 100% { opacity: 0.8; }
            50% { opacity: 1; }
        }

        @keyframes progress-stripe {
            0% { background-position: 0 0; }
            100% { background-position: 20px 0; }
        }

        @keyframes pulse {
            0% { transform: scale(1); }
            50% { transform: scale(1.05); }
            100% { transform: scale(1); }
        }

        @keyframes pulse-processing {
            0%, 100% { opacity: 0.8; }
            50% { opacity: 1; }
        }

        /* ===== RESPONSIVE DESIGN ===== */
        @media (max-width: 768px) {
            :root {
                --base-font-size: 14px;
            }
            
            .font-size-control {
                flex-wrap: wrap;
                gap: 8px;
            }
            
            .font-size-btn {
                width: 30px;
                height: 30px;
                font-size: 16px;
            }
            
            .form-row {
                flex-direction: column;
                gap: 10px;
            }
            
            .form-row .form-group {
                min-width: 100%;
                margin-bottom: 10px;
            }
            
            .copy-btn {
                min-width: 24px;
                height: 20px;
                font-size: 12px;
                padding: 2px 6px;
            }
            
            .direction-textarea {
                min-height: 35px;
                max-height: 120px;
                height: 50px;
            }
            
            .direction-container {
                min-height: 50px;
                max-height: 140px;
            }

            .analyze-section {
                flex-direction: column;
                align-items: flex-start;
                gap: 10px;
            }
            

            #analyze-progress {
                width: 100% !important;
                margin-left: 0 !important;
            }
        }
    </style>


</head>
<body>

    <div class="container">
        <div class="header" id="main-header">
            <h1>{{ title }} 
                <span id="mode-indicator" class="mode-indicator {% if augmented_mode %}augmented-mode{% else %}normal-mode{% endif %}">
                    {% if augmented_mode %}
                        보강 모드
                    {% else %}
                        일반 모드
                    {% endif %}
                </span>
                <span id="user-code-indicator" class="user-code-indicator" title="사용자 코드">({{ user_code }})</span>
                {% if expiration_warning %}
                <span class="expiration-warning">{{ expiration_warning }}</span>
                {% endif %}

            </h1>
            <div class="powered-by">powered by <a href="https://ko-agent.com" target="_blank">ko-agent.com</a>(koagentcom@gmail.com)</div>
            {% if request.query_params.get('message') %}
            <div class="status success">{{ request.query_params.get('message') }}</div>
            {% endif %}
            {% if request.query_params.get('error') %}
            <div class="status error">{{ request.query_params.get('error') }}</div>
            {% endif %}
            {% if error_message %}
            <div class="status error">{{ error_message }}</div>
            {% endif %}
        </div>
        <!-- Add this right after your existing header div -->                
        <div class="header-collapsed-indicator" id="header-indicator">
            Header Hidden - Double-click "문서 올리기" to restore
        </div>

        <!-- Normal Mode Sections -->
        <div class="section normal-mode-only">
            <div class="section-header">
                <h3>대화하기</h3>
                <div class="chat-header-buttons">
                    {% if loaded_file_names|length > 1 %}
                    <button type="button" id="doc-filter-btn" class="doc-filter-btn" onclick="openDocumentFilter()">
                        📄 문서 선택
                    </button>
                    {% endif %}
                    <button type="button" id="new-start-btn" class="new-start-btn" onclick="newStart()">
                        새로 시작
                    </button>
                    <button type="button" id="window-augment-btn" class="window-augment-btn" onclick="toggleWindowAugment()">
                        {% if augmented_mode %}일반 모드로{% else %}보강 모드로{% endif %}
                    </button>
                    <button type="button" id="normal-save-btn" class="chat-header-btn save-btn" onclick="saveOutputToDocx()" style="display: {% if chat_history %}inline-block{% else %}none{% endif %};">
                        저장
                    </button>
                </div>
            </div>

            <div class="chat-content">                            

                {% if chat_history %}
                <div class="chat-history-container">
                    <div class="chat-history">
                        {% for message in chat_history %}
                        <div class="message {% if message.type == 'human' %}human-message{% else %}ai-message{% endif %}">
                            <strong>{% if message.type == 'human' %}You{% else %}Assistant{% if message.model %}({{ message.model }}){% endif %}{% endif %}:</strong>
                            {{ message.content|safe }}
                        </div>
                        {% endfor %}
                        <div id="chat-bottom"></div>
                    </div>
                    <div class="move-button-container">
                        <button type="button" id="move-btn" class="btn btn-secondary" onclick="moveSelectedText()" disabled>
                            선택영역을 입력창으로 복사
                        </button>
                        <span id="move-status" class="move-status-text"></span>
                    </div>
                </div>
                {% endif %}
                
                <div class="chat-form-container">
                    <form action="/chat" method="post" id="chat-form" onsubmit="return submitChatQuery(event)">
                        <input type="hidden" name="session_id" value="{{ session_id }}">
                        <input type="hidden" name="allowed_files" id="allowed-files-input" value="{{ selected_allowed_files | join(',') }}">
                        
                        <!-- CORRECT VERSION -->                                                
                        <div id="user-directive-container" class="user-directive-container {% if augmented_mode %}show{% endif %}">
                            <div class="form-group">
                                <div class="directive-header">
                                    <label for="user_directive">추가 지시사항:</label>
                                    <div class="directive-buttons">
                                        <button type="button" onclick="clearUserDirective()" class="clear-btn">
                                            Clear
                                        </button>
                                    </div>
                                </div>
                                <textarea id="user_directive" name="user_directive" class="user-directive-input" 
                                        placeholder="여기에 추가 지시사항을 입력하세요..." rows="3" autocomplete="off" spellcheck="false"></textarea>
                            </div>
                        </div>

                        <div class="query-input-section">
                            <div class="form-group">
                                <div class="label-progress-row">        
                                    <label for="query" class="label-with-nav">
                                        <span>여기에 질문하거나 명령을 내리세요:</span>
                                        <button type="button" class="history-nav-btn" id="history-up-btn" onclick="navigateQueryHistoryUp()" title="이전 입력 (↑)">▲</button>
                                        <button type="button" class="history-nav-btn" id="history-down-btn" onclick="navigateQueryHistoryDown()" title="다음 입력 (↓)">▼</button>
                                    </label>
                                    <div class="chat-progress-container" id="chat-progress" style="display: none; width: 350px;">
                                        <div class="progress-text-container" style="margin-bottom: 3px;">
                                            <span id="chat-progress-text" style="font-size: 12px; color: #333;">Processing...</span>
                                            <span id="chat-progress-percent" style="float: right; font-size: 12px; color: #666; font-family: monospace;"></span>
                                        </div>
                                        <div class="progress-bar-container" style="width: 100%; height: 16px; background: #e0e0e0; border-radius: 8px; overflow: hidden; border: 1px solid #ccc;">
                                            <div id="chat-progress-bar-fill" style="width: 0%; height: 100%; background: linear-gradient(90deg, #28a745, #17a2b8); border-radius: 8px; transition: width 0.3s ease;"></div>
                                        </div>
                                    </div>
                                </div>

                                <!-- TEXTAREA ONLY -->
                                <div style="margin-top: 8px;">
                                    <textarea 
                                        id="query" 
                                        name="query" 
                                        class="history-textarea" 
                                        placeholder="여기에 질문을 입력하세요..." 
                                        required 
                                        spellcheck="false"
                                        autocomplete="off"
                                        style="width: 100%; resize: vertical; min-height: 60px;"
                                        {% if not vectorstore_exists %}disabled{% endif %}
                                    ></textarea>
                                </div>

                                <div class="query-help" style="margin-top: 6px; font-size: 12px; color: #666;">
                                    ↑/↓ 키로 이전 이력을 다시 이용하거나 뒤로 되돌리실 수 있습니다. • Enter키로 질문을 처리하세요. • Shift+Enter키는 new line을 만들 때 사용
                                </div>
                            </div>
                        </div>

                        <div class="form-options-section">
                            <div class="form-row">
                                <div class="form-group">
                                    <label for="language">언어:</label>
                                    <select id="language" name="language" 
                                            data-ajax-endpoint="/update-language"
                                            onchange="syncLanguageSelection(this.value, 'normal')">
                                        <option value="korean" {% if language == 'korean' %}selected{% endif %}>한국어</option>
                                        <option value="english" {% if language == 'english' %}selected{% endif %}>English</option>
                                        <option value="japanese" {% if language == 'japanese' %}selected{% endif %}>日本語</option>
                                    </select>
                                </div>
                            
                                <div class="form-group">
                                    <label for="model">LLM Model:</label>
                                    <select id="model" name="model" 
                                            onchange="syncModelSelection(this.value, 'normal')">
                                        {% for model_name in models %}
                                        <option value="{{ model_name }}" {% if model_name == selected_model %}selected{% endif %}>
                                            {{ model_name }}
                                        </option>
                                        {% endfor %}
                                    </select>
                                </div>
                                
                                <div class="form-group">
                                    <label for="websearch_tool">Web Tool:</label>
                                    <select id="websearch-tool" name="websearch_tool" 
                                            onchange="updateWebSearchTool(this.value)">
                                        {% for tool in websearch_tools %}
                                        <option value="{{ tool }}" {% if tool == selected_websearch_tool %}selected{% endif %}>{{ tool }}</option>
                                        {% endfor %}
                                    </select>
                                </div>
                                
                                <div class="form-group" style="display: flex !important; align-items: center; gap: 15px; flex-wrap: wrap;">
                                    <span style="display: inline-flex !important; align-items: center; gap: 5px; white-space: nowrap;">
                                        <label style="display: inline !important; margin: 0 !important;">Memory:</label>
                                        <button type="button" 
                                                class="toggle-btn {% if history_mode %}toggle-on{% else %}toggle-off{% endif %}" 
                                                data-mode="history" 
                                                data-value="{{ history_mode|default(false) }}"
                                                onclick="toggleMode(this.getAttribute('data-mode'), this.getAttribute('data-value') === 'True')"
                                                style="padding: 4px 12px; min-width: 50px;">
                                            {% if history_mode %}ON{% else %}OFF{% endif %}
                                        </button>
                                    </span>
                                    
                                    <span style="display: inline-flex !important; align-items: center; gap: 6px; white-space: nowrap;">
                                        <label style="display: inline !important; margin: 0 !important; font-size: 0.9em;">검색:</label>
                                        <label style="display: inline-flex; align-items: center; gap: 2px; cursor: pointer; font-size: 0.9em;">
                                            <input type="radio" name="search_mode" value="rag" 
                                                   {% if search_mode == 'rag' or not search_mode %}checked{% endif %}
                                                   onchange="setSearchMode('rag')" style="margin: 0;">
                                            <span>RAG</span>
                                        </label>
                                        <label style="display: inline-flex; align-items: center; gap: 2px; cursor: pointer; font-size: 0.9em;">
                                            <input type="radio" name="search_mode" value="web"
                                                   {% if search_mode == 'web' %}checked{% endif %}
                                                   onchange="setSearchMode('web')" style="margin: 0;">
                                            <span>Web</span>
                                        </label>
                                        <label style="display: inline-flex; align-items: center; gap: 2px; cursor: pointer; font-size: 0.9em;">
                                            <input type="radio" name="search_mode" value="mixed"
                                                   {% if search_mode == 'mixed' %}checked{% endif %}
                                                   onchange="setSearchMode('mixed')" style="margin: 0;">
                                            <span>Mixed</span>
                                        </label>
                                    </span>
                                </div>
                            </div>
                        </div>
                    </form>
                    
                    {% if not vectorstore_exists %}
                    <div class="chat-disabled-notice">
                        <p style="color: #666; font-style: italic; margin-top: 10px;">
                            Vector Store가 로드되지 않았습니다. 문서를 업로드해주세요.
                        </p>
                    </div>
                    {% endif %}
                </div>
            </div>
        </div>

    </div>
    <dialog id="message-dialog" class="message-dialog">
        <div class="message-dialog-header" id="dialog-header">
            <span class="dialog-title">Notification</span>
            <button id="message-dialog-close" class="message-dialog-close" onclick="closeMessageDialog()">&times;</button>
        </div>
        <div class="message-dialog-content">
            <p id="message-dialog-text" class="message-dialog-text"></p>
        </div>
    </dialog>


    <script>

    // Drag state for dialog
    let dragState = {
        isDragging: false,
        startX: 0,
        startY: 0,
        initialX: 0,
        initialY: 0
    };

    // Global variables for cursor position management
    var isAgentModeOn = false;
    let isAugmented = false;        
    let processingPollInterval = null;

    let savedCursorPosition = 0;
    let lastQueryInputFocus = 0;
        
    let longQueryStartTime = null;
    let isLongQuery = false;
        
    let preservationTimers = {};
    let isPreservationActive = false;
    let lastModeSwitchTime = -100000;

    let isProcessing = false;


    const debounceStorage = (() => {
        const timers = {};
        return (key, fn, delay = 500) => {
            clearTimeout(timers[key]);
            timers[key] = setTimeout(fn, delay);
        };
    })();
    
    // Extract cleanup logic
    function cleanupForFreshStart() {
        const url = new URL(window.location.href);
        url.searchParams.delete('session_id');
        window.history.replaceState({}, '', url.toString());

        // Set toggle defaults
        localStorage.setItem('augmentedMode', 'false');
        
        // Reset priority button UI

        // Clear specific keys
        const keysToRemove = [];
        for (let i = 0; i < localStorage.length; i++) {
            const key = localStorage.key(i);
            if (key && (
                key === 'currentQuery' ||                 
                key === 'savedCursorPosition' ||          
                key === 'userDirective' ||                
                key === 'savedLanguage' ||                
                key === 'savedModel' ||
                key === 'syncedModel' ||
                key === 'savedEmbedModel' ||
                key === 'preserve_query' ||
                key === 'preserve_query_cursor' ||
                key === 'preserve_user_directive' ||
                key === 'preserve_user_directive_cursor' ||
                key.startsWith('queryHistory_')
            )) {
                keysToRemove.push(key);
            }
        }
        
        keysToRemove.forEach(key => localStorage.removeItem(key));
        
        // Reset toggle defaults again
        
        // Reset button UI again

    }

    function newStart() {
        if (confirm('Start a new session?...')) {
            cleanupForFreshStart();  // Just call shared function
            setTimeout(() => {
                window.location.href = '/new-session';
            }, 50);
        }
    }

    function appendUserMessage(text) {
        const container = document.getElementById('chat-container');
        if (!container) return;
        const div = document.createElement('div');
        div.className = 'message user-message';
        div.innerHTML = `<div class="bubble">${escapeHtml(text)}</div>`;
        container.appendChild(div);
        container.scrollTop = container.scrollHeight;
    }

    function appendAssistantMessage(text) {
        const container = document.getElementById('chat-container');
        if (!container) return;
        const div = document.createElement('div');
        div.className = 'message assistant-message';
        div.innerHTML = `<div class="bubble">${escapeHtml(text)}</div>`;
        container.appendChild(div);
        container.scrollTop = container.scrollHeight;
    }

    function escapeHtml(text) {
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }
    
    async function submitQuery() {
        // Prevent double submissions - set flag IMMEDIATELY
        if (isProcessing) {
            console.log('⚠️ Query already processing, ignoring duplicate submission');
            return;
        }
        isProcessing = true;
        
        const textarea = document.getElementById('query');
        const query = textarea.value.trim();
        if (!query) {
            isProcessing = false;  // Reset if validation fails
            return;
        }

        const queryToSubmit = query;
        
        // Add to history BEFORE submitting (since fetch doesn't trigger form submit event)
        if (window.normalInputHistory && typeof window.normalInputHistory.addToHistory === 'function') {
            window.normalInputHistory.addToHistory(queryToSubmit);
        }
        
        textarea.disabled = true;
        startProgress();  // This also sets isProcessing, but we already did it above
        startChatProgressPolling();

        const modelDropdown = document.getElementById('model');
        const selectedModel = modelDropdown.value;

        try {
            const response = await fetch('/chat', {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: new URLSearchParams({
                    'query': queryToSubmit,
                    'session_id': getSessionId(),
                    'user_directive': document.getElementById('user_directive')?.value || '',
                    'language': document.getElementById('language')?.value || 'korean',
                    'model': selectedModel,
                    'allowed_files': document.getElementById('allowed-files-input')?.value || ''
                }),
                redirect: 'manual'  // ✅ ADD ONLY THIS LINE
            });

            // ✅ REPLACE the "if (!response.ok)" block with this:
            if (response.status === 0 || response.type === 'opaqueredirect') {
                //console.log('✅ Query submitted successfully (redirect intercepted)');
            } else if (!response.ok) {
                const err = await response.text();
                throw new Error(`HTTP ${response.status}: ${err}`);
            }

            textarea.value = '';
            
            appendUserMessage(queryToSubmit);
            appendAssistantMessage('처리 중...');

        } catch (err) {
            console.error('❌ Error in submitQuery:', err);
            appendAssistantMessage('오류: 서버에 연결할 수 없습니다.');
            stopProgress();
            textarea.disabled = false;
            isProcessing = false;
        }
    }
        
    function startProgress() {
        const progressBar = document.getElementById('chat-progress');
        const progressFill = document.getElementById('progress-fill');
        const progressText = document.getElementById('progress-text');

        if (progressBar) progressBar.style.display = 'block';
        if (progressFill) progressFill.style.width = '5%';
        if (progressText) progressText.textContent = '질문 전송 중...';
        isProcessing = true;
    }


    // =====================================================
    // Document Filter Functions
    // =====================================================
    
    // Available documents from server
    const loadedFileNames = {{ loaded_file_names | tojson | safe }};
    const serverSelectedFiles = {{ selected_allowed_files | tojson | safe }};
    let selectedDocuments = serverSelectedFiles.length > 0 ? [...serverSelectedFiles] : [];
    
    // Restore button state on page load (only if button exists and multiple docs)
    (function initDocFilterButton() {
        if (loadedFileNames.length <= 1) return;  // No button if single doc
        const btn = document.getElementById('doc-filter-btn');
        if (btn && selectedDocuments.length > 0 && selectedDocuments.length < loadedFileNames.length) {
            btn.classList.add('has-filter');
            btn.textContent = `📄 ${selectedDocuments.length}/${loadedFileNames.length}`;
        }
    })();
    
    function openDocumentFilter() {
        if (loadedFileNames.length <= 1) return;  // No filter for single doc
        const modal = document.getElementById('doc-filter-modal');
        const list = document.getElementById('doc-filter-list');
        
        if (!modal || !list) {
            console.error('Document filter modal not found');
            return;
        }
        
        // Populate checkboxes
        list.innerHTML = '';
        loadedFileNames.forEach((fileName, index) => {
            const isChecked = selectedDocuments.length === 0 || selectedDocuments.includes(fileName);
            const item = document.createElement('div');
            item.className = 'doc-filter-item';
            item.innerHTML = `
                <input type="checkbox" id="doc-${index}" value="${fileName}" ${isChecked ? 'checked' : ''}>
                <label for="doc-${index}">${fileName}</label>
            `;
            item.onclick = (e) => {
                if (e.target.tagName !== 'INPUT') {
                    const checkbox = item.querySelector('input');
                    checkbox.checked = !checkbox.checked;
                }
                updateFilterStatus();
            };
            list.appendChild(item);
        });
        
        updateFilterStatus();
        modal.classList.add('show');
    }
    
    function closeDocumentFilter() {
        const modal = document.getElementById('doc-filter-modal');
        if (modal) modal.classList.remove('show');
    }
    
    function updateFilterStatus() {
        const checkboxes = document.querySelectorAll('#doc-filter-list input[type="checkbox"]');
        const checkedCount = Array.from(checkboxes).filter(cb => cb.checked).length;
        const totalCount = checkboxes.length;
        const status = document.getElementById('doc-filter-status');
        
        if (!status) return;
        
        if (checkedCount === 0) {
            status.textContent = '⚠️ 최소 1개 문서를 선택하세요';
        } else if (checkedCount === totalCount) {
            status.textContent = '전체 문서 사용 중';
        } else {
            status.textContent = `${checkedCount}/${totalCount} 문서 선택됨`;
        }
    }
    
    function toggleAllDocuments() {
        const checkboxes = document.querySelectorAll('#doc-filter-list input[type="checkbox"]');
        const allChecked = Array.from(checkboxes).every(cb => cb.checked);
        checkboxes.forEach(cb => cb.checked = !allChecked);
        updateFilterStatus();
    }
    
    function clearDocumentFilter() {
        selectedDocuments = [];
        const input = document.getElementById('allowed-files-input');
        if (input) input.value = '';
        
        // Update button appearance
        const btn = document.getElementById('doc-filter-btn');
        if (btn) {
            btn.classList.remove('has-filter');
            btn.textContent = '📄 문서 선택';
        }
        
        closeDocumentFilter();
    }
    
    function applyDocumentFilter() {
        const checkboxes = document.querySelectorAll('#doc-filter-list input[type="checkbox"]:checked');
        const checkedFiles = Array.from(checkboxes).map(cb => cb.value);
        
        if (checkedFiles.length === 0) {
            alert('최소 1개 문서를 선택하세요');
            return;
        }
        
        const btn = document.getElementById('doc-filter-btn');
        const input = document.getElementById('allowed-files-input');
        
        if (checkedFiles.length === loadedFileNames.length) {
            // All selected = no filter
            selectedDocuments = [];
            if (input) input.value = '';
            if (btn) {
                btn.classList.remove('has-filter');
                btn.textContent = '📄 문서 선택';
            }
        } else {
            // Partial selection
            selectedDocuments = checkedFiles;
            if (input) input.value = checkedFiles.join(',');
            if (btn) {
                btn.classList.add('has-filter');
                btn.textContent = `📄 ${checkedFiles.length}/${loadedFileNames.length}`;
            }
        }
        
        console.log('Document filter applied:', selectedDocuments);
        closeDocumentFilter();
    }
    
    // Initialize document filter event listeners after DOM is ready
    function initDocumentFilterListeners() {
        const modal = document.getElementById('doc-filter-modal');
        if (modal) {
            modal.addEventListener('click', function(e) {
                if (e.target === this) {
                    closeDocumentFilter();
                }
            });
        }
    }
    
    // Call initialization - safe because this runs after DOMContentLoaded in the main script
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initDocumentFilterListeners);
    } else {
        initDocumentFilterListeners();
    }
    
    // Close modal on Escape key (safe to add anytime)
    document.addEventListener('keydown', function(e) {
        if (e.key === 'Escape') {
            const modal = document.getElementById('doc-filter-modal');
            if (modal && modal.classList.contains('show')) {
                closeDocumentFilter();
            }
        }
    });

    // Submit on Enter (no Shift)
    document.getElementById('query').addEventListener('keydown', function(e) {
        if (e.key === 'Enter' && !e.shiftKey && !isProcessing) {
            e.preventDefault();
            submitQuery();
        }
    });

    function getSessionId() {
        return new URLSearchParams(window.location.search).get('session_id') || 
            localStorage.getItem('sessionId') || 'default';
    }

    function initializeMoveButton() {
        const moveBtn = document.getElementById('move-btn');
        const moveStatus = document.getElementById('move-status');
        const queryInput = document.getElementById('query');
        
        if (!moveBtn || !queryInput) return;
        
        // Show move button
        if (moveBtn.parentElement) {
            moveBtn.parentElement.style.display = 'block';
        }
        
        // Track cursor position in query input
        queryInput.addEventListener('focus', function() {
            lastQueryInputFocus = Date.now();
        });
        
        queryInput.addEventListener('selectionchange', function() {
            if (Date.now() - lastQueryInputFocus < 100) { // Only if recently focused
                savedCursorPosition = queryInput.selectionStart;
            }
        });
        
        queryInput.addEventListener('keyup', function() {
            savedCursorPosition = queryInput.selectionStart;
        });
        
        queryInput.addEventListener('click', function() {
            savedCursorPosition = queryInput.selectionStart;
        });
        
        // Enable/disable move button based on text selection
        function updateMoveButtonState() {
            const selection = window.getSelection();
            const selectedText = selection.toString().trim();
            moveBtn.disabled = !selectedText;
        }
        
        // Listen for selection changes
        document.addEventListener('selectionchange', updateMoveButtonState);
        document.addEventListener('mouseup', function() {
            setTimeout(updateMoveButtonState, 10);
        });
    }
        
    function debouncedPreservation(inputId, delay = 2000) {
        clearTimeout(preservationTimers[inputId]);
        preservationTimers[inputId] = setTimeout(() => {
            preserveInputsOptimized();
        }, delay);
    }

    function restoreInputsOptimized() {
        const isModeSwitching = performance.now() - lastModeSwitchTime < 1000;
        
        if (isModeSwitching) {
            return;
        }
        
        try {
            // Normal mode restoration
            const queryInput = document.getElementById('query');
            const savedQuery = localStorage.getItem('preserve_query');
            const savedQueryCursor = localStorage.getItem('preserve_query_cursor');
            
            if (queryInput && savedQuery && savedQuery.trim().length > 0) {
                queryInput.value = savedQuery;
                
                if (savedQueryCursor) {
                    const position = parseInt(savedQueryCursor);
                    setTimeout(() => {
                        queryInput.setSelectionRange(position, position);
                        savedCursorPosition = position;
                    }, 100);
                }
                
                localStorage.removeItem('preserve_query');
                localStorage.removeItem('preserve_query_cursor');
            }
            
            const preservedAugmented = localStorage.getItem('preserve_augmented_mode');
            const persistentAugmented = localStorage.getItem('augmentedMode');
            
            // Check server state first, then localStorage
            const shouldRestoreAugmented = isAugmented || (preservedAugmented === 'true') || (persistentAugmented === 'true');
            
            if (shouldRestoreAugmented) {
                const directiveContainer = document.getElementById('user-directive-container');
                const button = document.getElementById('window-augment-btn');
                
                if (directiveContainer) directiveContainer.classList.add('show');
                if (button) button.textContent = '일반 화면 상태로';
                isAugmented = true;
                
                // Restore user directive content if available
                const userDirective = document.getElementById('user_directive');
                const savedDirective = localStorage.getItem('preserve_user_directive');
                const savedCursor = localStorage.getItem('preserve_user_directive_cursor');
                
                if (userDirective && savedDirective && savedDirective.trim().length > 0) {
                    userDirective.value = savedDirective;
                    
                    if (savedCursor) {
                        const position = parseInt(savedCursor);
                        setTimeout(() => {
                            userDirective.setSelectionRange(position, position);
                        }, 150);
                    }
                }
                
                // Clean up temporary preservation keys
                localStorage.removeItem('preserve_augmented_mode');
                localStorage.removeItem('preserve_user_directive');
                localStorage.removeItem('preserve_user_directive_cursor');
            }
            
        } catch (error) {
            console.error('Restoration error:', error);
        }
    }
        
    function setupLightweightPreservation() {
        // Only preserve on critical events, not every interaction
        
        // Page unload - most important
        window.addEventListener('beforeunload', function() {
            preserveInputsOptimized();
            
            // Clear global polling interval to prevent memory leaks
            if (processingPollInterval) {
                clearInterval(processingPollInterval);
                processingPollInterval = null;
            }
            
            // Clear all preservation timers
            Object.values(preservationTimers).forEach(timer => clearTimeout(timer));
            preservationTimers = {};
        }, { once: false });
        
        // Form submissions that might reload
        document.addEventListener('submit', function(e) {
            const form = e.target;
            if (form && (form.method === 'post' || form.action.includes('toggle') || form.action.includes('update'))) {
                preserveInputsOptimized();
            }
        }, { passive: true });
        
        // Only specific buttons that cause reloads (exclude toggle buttons)
        const criticalButtons = document.querySelectorAll('[onclick*="location"], button[type="submit"]:not([onclick*="toggle"])');
        criticalButtons.forEach(button => {
            button.addEventListener('click', preserveInputsOptimized, { once: false, passive: true });
        });
        
    }
        
    function preserveInputsOptimized() {
        if (isPreservationActive) {
            return;
        }
        
        isPreservationActive = true;
        
        try {
            // Normal mode - only save if there's actual content
            const queryInput = document.getElementById('query');
            if (queryInput && queryInput.value.trim().length > 0) {
                localStorage.setItem('preserve_query', queryInput.value);
                localStorage.setItem('preserve_query_cursor', queryInput.selectionStart.toString());
            }
            
            // User directive only if visible AND has content
            const directiveContainer = document.getElementById('user-directive-container');
            const userDirective = document.getElementById('user_directive');
            if (directiveContainer && directiveContainer.classList.contains('show') && 
                userDirective && userDirective.value.trim().length > 0) {
                localStorage.setItem('preserve_user_directive', userDirective.value);
                localStorage.setItem('preserve_user_directive_cursor', userDirective.selectionStart.toString());
                localStorage.setItem('preserve_augmented_mode', 'true');
            }
            
        } catch (error) {
            console.error('Preservation error:', error);
        } finally {
            isPreservationActive = false;
        }
    }
        
    function preserveInputsDirectly() {
        // Normal mode - preserve query input and user directive
        const queryInput = document.getElementById('query');
        if (queryInput && queryInput.value.trim()) {
            localStorage.setItem('preserve_query', queryInput.value);
            localStorage.setItem('preserve_query_cursor', queryInput.selectionStart.toString());
        }
        
        // Only preserve user directive if augmented mode is active
        const directiveContainer = document.getElementById('user-directive-container');
        const userDirective = document.getElementById('user_directive');
        if (directiveContainer && directiveContainer.classList.contains('show') && 
            userDirective && userDirective.value.trim()) {
            localStorage.setItem('preserve_user_directive', userDirective.value);
            localStorage.setItem('preserve_user_directive_cursor', userDirective.selectionStart.toString());
            localStorage.setItem('preserve_augmented_mode', 'true');
        }
        
        // Save form selections separately
        saveAllFormSelections();
    }

    function restoreInputsDirectly() {
        // Normal mode restoration
        const queryInput = document.getElementById('query');
        const savedQuery = localStorage.getItem('preserve_query');
        const savedQueryCursor = localStorage.getItem('preserve_query_cursor');
        
        if (queryInput && savedQuery) {
            queryInput.value = savedQuery;
            
            if (savedQueryCursor) {
                const position = parseInt(savedQueryCursor);
                setTimeout(() => {
                    queryInput.setSelectionRange(position, position);
                    savedCursorPosition = position;
                }, 100);
            }
            
            // Clean up
            localStorage.removeItem('preserve_query');
            localStorage.removeItem('preserve_query_cursor');
        }
        
        // Restore augmented mode and user directive
        const savedAugmented = localStorage.getItem('preserve_augmented_mode');
        if (savedAugmented === 'true') {
            // Restore UI state first
            const directiveContainer = document.getElementById('user-directive-container');
            const button = document.getElementById('window-augment-btn');
            
            if (directiveContainer) directiveContainer.classList.add('show');
            if (button) button.textContent = '일반 모드로';
            isAugmented = true;
            
            // Then restore text content
            const userDirective = document.getElementById('user_directive');
            const savedDirective = localStorage.getItem('preserve_user_directive');
            const savedDirectiveCursor = localStorage.getItem('preserve_user_directive_cursor');
            
            if (userDirective && savedDirective) {
                userDirective.value = savedDirective;
                
                if (savedDirectiveCursor) {
                    const position = parseInt(savedDirectiveCursor);
                    setTimeout(() => {
                        userDirective.setSelectionRange(position, position);
                    }, 200);
                }
            }
            
            // Clean up
            localStorage.removeItem('preserve_augmented_mode');
            localStorage.removeItem('preserve_user_directive');
            localStorage.removeItem('preserve_user_directive_cursor');
        }
        
        // Restore form selections
        restoreAllFormSelections();
    }
        
    function saveAllCurrentInputs() {
        saveNormalModeInputs();
    }

    function restoreAllCurrentInputs() {
        restoreNormalModeInputs();
    }

    // Normal mode preservation
    function saveNormalModeInputs() {
        const queryInput = document.getElementById('query');
        if (queryInput) {
            localStorage.setItem('currentQuery', queryInput.value);
            const cursorPos = queryInput.selectionStart || queryInput.value.length;
            localStorage.setItem('savedCursorPosition', cursorPos.toString());
        }
        
        const directiveContainer = document.getElementById('user-directive-container');
        const userDirective = document.getElementById('user_directive');
        
        if (directiveContainer && directiveContainer.classList.contains('show') && userDirective) {
            const directiveText = userDirective.value.trim();
            if (directiveText) {
                localStorage.setItem('userDirective', userDirective.value);
                const cursorPos = userDirective.selectionStart || userDirective.value.length;
                localStorage.setItem('userDirectiveCursor', cursorPos.toString());
            }
            localStorage.setItem('augmentedMode', 'true');
        }
        
        saveAllFormSelections();
    }

    function restoreNormalModeInputs() {
        const queryInput = document.getElementById('query');
        const savedQuery = localStorage.getItem('currentQuery');
        const savedCursorPos = localStorage.getItem('savedCursorPosition');
        
        if (queryInput && savedQuery) {
            queryInput.value = savedQuery;
            if (savedCursorPos) {
                const position = parseInt(savedCursorPos);
                setTimeout(() => {
                    queryInput.setSelectionRange(position, position);
                    savedCursorPosition = position;
                }, 200);
            }
        }
        
        const savedAugmented = localStorage.getItem('augmentedMode');
        if (savedAugmented === 'true') {
            const directiveContainer = document.getElementById('user-directive-container');
            const button = document.getElementById('window-augment-btn');
            
            if (directiveContainer) directiveContainer.classList.add('show');
            if (button) button.textContent = '일반 모드로';
            isAugmented = true;
            
            const userDirective = document.getElementById('user_directive');
            const savedDirective = localStorage.getItem('userDirective');
            const savedCursor = localStorage.getItem('userDirectiveCursor');
            
            if (userDirective && savedDirective) {
                userDirective.value = savedDirective;
                if (savedCursor) {
                    const position = parseInt(savedCursor);
                    setTimeout(() => {
                        userDirective.setSelectionRange(position, position);
                    }, 250);
                }
            }
        }
        
        restoreAllFormSelections();
    }

    function showMessageDialog(message, type = 'success', duration = 3000) {
        const dialog = document.getElementById('message-dialog');
        const text = document.getElementById('message-dialog-text');
        
        if (!dialog || !text) return;
        
        // Reset position to center
        dialog.style.left = '';
        dialog.style.top = '';
        dialog.style.transform = 'translate(-50%, -50%)';
        
        // Set message and style
        text.textContent = message;
        dialog.className = `message-dialog message-dialog-${type}`;
        
        // Make draggable
        makeDraggable(dialog);
        
        // Show dialog
        dialog.showModal();
        dialog.classList.add('show');
        
        // Auto-close after duration
        const autoCloseTimer = setTimeout(() => {
            closeMessageDialog();
        }, duration);
        
        dialog.autoCloseTimer = autoCloseTimer;
    }

    function closeMessageDialog() {
        const dialog = document.getElementById('message-dialog');
        if (!dialog) return;
        
        // Clear auto-close timer
        if (dialog.autoCloseTimer) {
            clearTimeout(dialog.autoCloseTimer);
            dialog.autoCloseTimer = null;
        }
        
        dialog.classList.remove('show');
        setTimeout(() => {
            dialog.close();
        }, 300);
    }

    function makeDraggable(dialog) {
        const header = dialog.querySelector('.message-dialog-header');
        if (!header) return;
        
        header.addEventListener('mousedown', startDrag);
        document.addEventListener('mousemove', drag);
        document.addEventListener('mouseup', endDrag);
    }

    function startDrag(e) {
        // Don't drag if clicking the close button
        if (e.target.classList.contains('message-dialog-close')) {
            return;
        }
        
        const dialog = document.getElementById('message-dialog');
        if (!dialog) return;
        
        dragState.isDragging = true;
        dialog.classList.add('dragging');
        
        // Get current position
        const rect = dialog.getBoundingClientRect();
        dragState.initialX = rect.left;
        dragState.initialY = rect.top;
        
        // Mouse position
        dragState.startX = e.clientX;
        dragState.startY = e.clientY;
        
        e.preventDefault();
    }

    function drag(e) {
        if (!dragState.isDragging) return;
        
        const dialog = document.getElementById('message-dialog');
        if (!dialog) return;
        
        const deltaX = e.clientX - dragState.startX;
        const deltaY = e.clientY - dragState.startY;
        
        const newX = dragState.initialX + deltaX;
        const newY = dragState.initialY + deltaY;
        
        dialog.style.left = newX + 'px';
        dialog.style.top = newY + 'px';
        dialog.style.transform = 'none';
    }

    function endDrag() {
        if (!dragState.isDragging) return;
        
        const dialog = document.getElementById('message-dialog');
        if (dialog) {
            dialog.classList.remove('dragging');
        }
        
        dragState.isDragging = false;
    }          
            
    function scrollChatToBottom() {
        const chatHistory = document.querySelector('.chat-history');
        const chatBottom = document.getElementById('chat-bottom');
        
        if (chatHistory) {
            chatHistory.scrollTop = chatHistory.scrollHeight;
        }
        
        if (chatBottom) {
            chatBottom.scrollIntoView({ behavior: 'smooth', block: 'end' });
        }
    }

    // Update the chat progress completion handler
    function updateChatProgressFromServer(data, elapsedSeconds = 0) {
        let message = '질문 처리중...';
        let progress = -1;
        
        // ... existing message and progress logic ...
        
        // Use server-provided progress text with elapsed time
        if (data.progress_text) {
            message = data.progress_text;
        } else if (data.message) {
            message = data.message;
        }
        
        // Add elapsed time for long queries
        if (elapsedSeconds > 15 && data.status === 'processing_query') {
            if (!message.includes('elapsed')) {
                message += ` (${elapsedSeconds}초 경과)`;
            }
        }
        
        // ... rest of existing status mapping logic ...
        
        updateChatProgress(progress, message, isLongQuery);
    }

    window.addEventListener('pageshow', function(event) {
        const queryInput = document.getElementById('query');
        if (queryInput) {
            queryInput.value = '';
        }
    });

    function startChatProgressPolling() {
        const sessionId = getSessionId();
        longQueryStartTime = Date.now();
        isLongQuery = false;
        
        if (processingPollInterval) {
            clearInterval(processingPollInterval);
            processingPollInterval = null;
        }
        
        let pollCount = 0;
        const maxPolls = 1200;
        
        processingPollInterval = setInterval(() => {
            pollCount++;
            const elapsedSeconds = Math.floor((Date.now() - longQueryStartTime) / 1000);
            
            fetch('/processing-status/' + sessionId)
                .then(response => response.json())
                .then(data => {                    
                    if (elapsedSeconds > 10 && data.status === 'processing_query') {
                        isLongQuery = true;
                    }
                    
                    updateChatProgressFromServer(data, elapsedSeconds);
                    
                    if (data.status === 'completed') {
                        clearInterval(processingPollInterval);
                        processingPollInterval = null;
                        hideChatProgress();
                        isProcessing = false;
                        
                        // Re-enable the query input
                        const queryInput = document.getElementById('query');
                        if (queryInput) {
                            queryInput.disabled = false;
                            queryInput.style.backgroundColor = '';
                            queryInput.style.opacity = '';
                            queryInput.style.cursor = '';
                        }
                        
                        if (data.chat_history && data.chat_history.length > 0) {
                            //console.log('✅ Displaying chat history...');
                            
                            // Normal mode: use .chat-history div
                            let chatHistory = document.querySelector('.chat-history');
                            
                            // ✅ OPTION 1: Clear textarea before reload
                            if (!chatHistory) {
                                console.log('⚠️ .chat-history not found, reloading page to display result...');
                                
                                // Clear textarea before reload to prevent restoration
                                const queryInput = document.getElementById('query');
                                if (queryInput) {
                                    queryInput.value = '';
                                }
                                
                                setTimeout(() => {
                                    window.location.reload();
                                }, 500);
                                return;
                            }
                            
                            chatHistory.innerHTML = '';  // Clear existing content
                            
                            data.chat_history.forEach(msg => {
                                const msgDiv = document.createElement('div');
                                msgDiv.className = msg.type === 'human' ? 'message user-message' : 'message ai-message';
                                
                                // Add label
                                const labelDiv = document.createElement('div');
                                labelDiv.style.fontWeight = 'bold';
                                labelDiv.style.marginBottom = '5px';
                                if (msg.type === 'human') {
                                    labelDiv.textContent = 'You:';
                                } else {
                                    labelDiv.textContent = `Assistant (${msg.model || 'AI'}):`;
                                }
                                    
                                // Add content - use innerHTML to render <br> tags
                                const contentDiv = document.createElement('div');
                                contentDiv.innerHTML = msg.content;
                                
                                msgDiv.appendChild(labelDiv);
                                msgDiv.appendChild(contentDiv);
                                chatHistory.appendChild(msgDiv);
                            });
                            
                            chatHistory.scrollTop = chatHistory.scrollHeight;
                            //console.log('✅ Output displayed in .chat-history (normal mode)');
                            // 저장 버튼 표시
                            const normalSaveBtn = document.getElementById('normal-save-btn');
                            if (normalSaveBtn) {
                                normalSaveBtn.style.display = 'inline-block';
                            }
                        } else {
                            console.log('❌ No chat_history in status data');
                            
                            // ✅ OPTION 1: Clear textarea before reload
                            console.log('⚠️ Reloading page to display result...');
                            
                            // Clear textarea before reload to prevent restoration
                            const queryInput = document.getElementById('query');
                            if (queryInput) {
                                queryInput.value = '';
                            }
                            
                            setTimeout(() => {
                                window.location.reload();
                            }, 500);
                        }
                        
                    } else if (data.status === 'error') {
                        clearInterval(processingPollInterval);
                        processingPollInterval = null;
                        hideChatProgress();
                        isProcessing = false;
                        
                        const errorMsg = data.error || data.message || 'Unknown error';
                        alert(`Query processing failed after ${elapsedSeconds}s: ${errorMsg}`);
                        
                    } else if (pollCount >= maxPolls) {
                        clearInterval(processingPollInterval);
                        processingPollInterval = null;
                        hideChatProgress();
                        isProcessing = false;
                        alert(`Request timed out after ${Math.floor(maxPolls * 0.5)}s. The query may still be processing. Please check back in a moment.`);
                    }
                })
                .catch(error => {
                    console.error('Chat polling error:', error);
                    if (pollCount > 10) {
                        clearInterval(processingPollInterval);
                        processingPollInterval = null;
                        hideChatProgress();
                        isProcessing = false;
                        alert('Connection error during query processing. Please try again.');
                    }
                });
        }, 500);
    }

    function checkAndScrollToBottom() {
        const urlParams = new URLSearchParams(window.location.search);
        const hash = window.location.hash;
        
        // ONLY scroll if we have the specific hash indicating a completed query
        if (hash === '#chat-bottom') {
            setTimeout(() => {
                scrollChatToBottom();
            }, 500);
            
            // Clean up the hash after scrolling
            setTimeout(() => {
                history.replaceState(null, null, window.location.pathname + window.location.search);
            }, 1000);
        } else {
            // Don't auto-scroll for normal page loads or input editing
        }
    }

    function updateModeDisplay() {
        const modeIndicator = document.getElementById('mode-indicator');
        
        if (isAugmented) {
            // Handle augmented mode
            document.body.classList.add('augmented-mode');
            if (modeIndicator) {
                modeIndicator.textContent = '보강 모드';
                modeIndicator.className = 'mode-indicator augmented-mode';
            }
        } else {
            // Normal mode
            document.body.classList.remove('augmented-mode');
            if (modeIndicator) {
                modeIndicator.textContent = '일반 모드';
                modeIndicator.className = 'mode-indicator normal-mode';
            }
        }
    }
    function startProcessingPolling() {
            const sessionId = getSessionId();
            
            if (processingPollInterval) {
                clearInterval(processingPollInterval);
            }
            
            processingPollInterval = setInterval(function() {
                fetch('/processing-status/' + sessionId)
                    .then(function(response) { return response.json(); })
                    .then(function(data) {
                        updateProcessingDisplay(data);
                        
                        if (data.status === 'completed' || data.status === 'error') {
                            clearInterval(processingPollInterval);
                            processingPollInterval = null;
                            setTimeout(function() {
                                hideAnalyzeProgress();
                                location.reload();
                            }, 2000);
                        }
                    })
                    .catch(function(error) {
                        console.error('Polling error:', error);
                        clearInterval(processingPollInterval);
                        processingPollInterval = null;
                        hideAnalyzeProgress();
                });
        }, 1000);
    }

    function updateProcessingDisplay(data) {
        let message = '처리중...';
        let details = data.message || '';
        
        switch(data.status) {
            case 'starting':
                message = '분석 시작...';
                break;
            case 'loading_files':
                message = '파일들 읽어들임...';
                break;
            case 'preprocessing':
                message = '문서 전처리중...';
                break;
            case 'building_vectors':
                message = 'Vector Store를 만드는 중...';
                break;
            case 'finalizing':
                message = '끝마무라 하는 중...';
                break;
            case 'completed':
                message = '처리 완료!';
                break;
            case 'error':
                message = '처리중 에러!';
                details = data.error_message || '처리하는 중에 에러 발생!';
                break;
        }
        
        const progress = Math.max(0, Math.min(100, data.progress || 0));
        updateProgress(progress, message, details);
    }

    // For file analysis - uses detailed progress
    function submitAnalyzeWithLoading(event) {
        showAnalyzeProgress('Analyzing Files');
        updateProgress(0, '분석시작함...', '파일 처리 준비 중');
        startProcessingPolling(); // Uses detailed progress
        return true;
    }
        
    function submitChatQuery(event) {
        // Prevent double submissions
        if (isProcessing) {
            event.preventDefault();
            console.log('⚠️ Query already processing, ignoring duplicate submission');
            return false;
        }
        
        const queryInput = document.getElementById('query');
        const queryText = queryInput ? queryInput.value.trim() : '';
        
        if (!queryText) {
            alert('질문을 입력하세요!');
            event.preventDefault();
            return false;
        }
        
        // Set isProcessing flag
        isProcessing = true;
        
        try {
            showChatProgress();
            updateChatProgress(-1, '당신의 질문을 처리중...');
            
            if (queryInput) {
                queryInput.value = '';
            }
            clearSavedQueryText();
            
            setTimeout(() => {
                startChatProgressPolling();
            }, 100);
            
            return true;
            
        } catch (error) {
            console.error('Error in submitChatQuery:', error);
            hideChatProgress();
            isProcessing = false;
            return true;
        }
    }

    // Check if selection is within chat history
    function isSelectionInChatHistory(selection) {
        if (selection.rangeCount === 0) return false;
        
        const range = selection.getRangeAt(0);
        const chatHistory = document.querySelector('.chat-history');
        
        if (!chatHistory) return false;
        
        let container = range.commonAncestorContainer;
        while (container && container !== document) {
            if (container === chatHistory) return true;
            container = container.parentNode;
        }
        return false;
    }

    function moveSelectedText() {
        const selection = window.getSelection();
        const selectedText = selection.toString().trim();
        const queryInput = document.getElementById('query');
        const moveStatus = document.getElementById('move-status');
        
        if (!selectedText || !queryInput) {
            if (moveStatus) moveStatus.textContent = 'No text selected';
            return;
        }
        
        // NO restriction check - allow any selection
        
        const currentQuery = queryInput.value;
        const insertPosition = Math.min(savedCursorPosition || queryInput.value.length, currentQuery.length);
        
        let textToInsert = selectedText.trim();
        const beforeText = currentQuery.substring(0, insertPosition);
        const afterText = currentQuery.substring(insertPosition);
        
        const newlineChar = String.fromCharCode(10);
        if (beforeText && !beforeText.endsWith(' ') && !beforeText.endsWith(newlineChar)) {
            textToInsert = ' ' + textToInsert;
        }
        if (afterText && !afterText.startsWith(' ') && !afterText.startsWith(newlineChar)) {
            textToInsert = textToInsert + ' ';
        }
        
        queryInput.value = beforeText + textToInsert + afterText;
        
        const newCursorPosition = insertPosition + textToInsert.length;
        savedCursorPosition = newCursorPosition;
        queryInput.focus();
        queryInput.setSelectionRange(newCursorPosition, newCursorPosition);
        
        const inputEvent = new Event('input', { bubbles: true });
        queryInput.dispatchEvent(inputEvent);
        
        selection.removeAllRanges();
        if (moveStatus) {
            moveStatus.textContent = `Moved ${selectedText.length} characters to query input`;
        }
        
        queryInput.style.backgroundColor = '#d4edda';
        setTimeout(() => queryInput.style.backgroundColor = '', 1000);
    }

    // Enhanced query text saving that preserves cursor position
    function saveQueryTextWithPosition() {
        const queryInput = document.getElementById('query');
        if (queryInput) {
            localStorage.setItem('currentQuery', queryInput.value);
            localStorage.setItem('savedCursorPosition', savedCursorPosition.toString());
        }
    }

    // Enhanced query text loading that restores cursor position
    function loadQueryTextWithPosition() {
        const queryInput = document.getElementById('query');
        const savedQuery = localStorage.getItem('currentQuery');
        const savedPosition = localStorage.getItem('savedCursorPosition');
        
        if (queryInput && savedQuery) {
            queryInput.value = savedQuery;
            
            if (savedPosition) {
                const position = parseInt(savedPosition);
                savedCursorPosition = Math.min(position, savedQuery.length);
                
                // Restore cursor position after a brief delay
                setTimeout(function() {
                    queryInput.focus();
                    queryInput.setSelectionRange(savedCursorPosition, savedCursorPosition);
                }, 100);
            }
        }
    }

    // Font size management
    let currentFontSize = 16; // Default font size in pixels
    const minFontSize = 8;
    const maxFontSize = 32;

    // Spacing management
    let currentSpacing = 30; // Default section spacing in pixels
    const minSpacing = 6; // Minimum 6px spacing
    const maxSpacing = 50; // Maximum 50px spacing

    function loadFontSize() {
        const saved = localStorage.getItem('webFontSize');
        if (saved) {
            currentFontSize = parseInt(saved);
            if (currentFontSize < minFontSize || currentFontSize > maxFontSize) {
                currentFontSize = 16; // Reset to default if out of range
            }
        }
        applyFontSize(currentFontSize); // Always apply, even if not saved
    }

    function loadSpacing() {
        const saved = localStorage.getItem('webSpacing');
        if (saved) {
            currentSpacing = parseInt(saved);
            if (currentSpacing < minSpacing || currentSpacing > maxSpacing) {
                currentSpacing = 30; // Reset to default if out of range
            }
        }
        applySpacing(currentSpacing); // Always apply, even if not saved
    }

    function saveFontSize() {
        localStorage.setItem('webFontSize', currentFontSize.toString());
    }

    function saveSpacing() {
        localStorage.setItem('webSpacing', currentSpacing.toString());
    }

    function adjustFontSize(delta) {        
        
        let actualDelta;
        
        // Use ±1 steps only when both current AND target are below 15
        // Use ±2 steps when crossing the 15 threshold or operating above it
        if (currentFontSize < 15 && (currentFontSize + (delta > 0 ? 1 : -1)) < 15) {
            // Both current and next position are below 15, use small steps
            actualDelta = delta > 0 ? 1 : -1;
        } else {
            // Either current is ≥15 or we're crossing the 15 threshold, use big steps  
            actualDelta = delta > 0 ? 2 : -2;
        }
        
        const newSize = currentFontSize + actualDelta;
        if (newSize >= minFontSize && newSize <= maxFontSize) {
            currentFontSize = newSize;
            applyFontSize(currentFontSize);
            saveFontSize();
        }
    }

    function adjustSpacing(delta) {
        
        let actualDelta;
        
        // Use ±2 steps when below 16, ±3 steps when at/above 16
        if (currentSpacing < 16 && (currentSpacing + (delta > 0 ? 2 : -2)) < 16) {
            actualDelta = delta > 0 ? 2 : -2;
        } else {
            actualDelta = delta > 0 ? 3 : -3;
        }
        
        const newSpacing = currentSpacing + actualDelta;
        if (newSpacing >= minSpacing && newSpacing <= maxSpacing) {
            currentSpacing = newSpacing;
            applySpacing(currentSpacing);
            saveSpacing();
        }
    }

    function resetFontSize() {
        currentFontSize = 16;
        applyFontSize(currentFontSize);
        saveFontSize();
    }

    function resetSpacing() {
        currentSpacing = 30;
        applySpacing(currentSpacing);
        saveSpacing();
    }

    function applyFontSize(size) {
        // Update the display
        const display = document.getElementById('font-size-display');
        if (display) {
            display.textContent = size + 'px';
        }
        
        // Apply font size using CSS custom properties
        document.documentElement.style.setProperty('--base-font-size', size + 'px');
    }

    function applySpacing(spacing) {
        // Update the display
        const display = document.getElementById('spacing-display');
        if (display) {
            display.textContent = spacing + 'px';
        }
        
        // Apply spacing using CSS custom properties
        const formSpacing = Math.max(6, Math.round(spacing * 0.5)); // Form spacing is 50% of section spacing
        const containerPadding = Math.max(8, Math.round(spacing * 0.67)); // Container padding is ~67% of section spacing
        
        document.documentElement.style.setProperty('--section-spacing', spacing + 'px');
        document.documentElement.style.setProperty('--form-spacing', formSpacing + 'px');
        document.documentElement.style.setProperty('--container-padding', containerPadding + 'px');
    }


    function getSessionId() {        
        return document.documentElement.dataset.sessionId;
    }

    // Save query text to localStorage
    function saveQueryText() {
        const queryInput = document.getElementById('query');
        if (queryInput) {
            localStorage.setItem('currentQuery', queryInput.value);
        }
    }

    // Load query text from localStorage
    function loadQueryText() {
        const queryInput = document.getElementById('query');
        const savedQuery = localStorage.getItem('currentQuery');
        if (queryInput && savedQuery) {
            queryInput.value = savedQuery;
        }
    }

    // Clear query text from localStorage (only when actually submitting)
    function clearSavedQueryText() {
        localStorage.removeItem('currentQuery');
        localStorage.removeItem('savedCursorPosition');
    }

    // Save user directive content to localStorage        
    function saveUserDirective() {
        const directive = document.getElementById('user_directive');
        if (directive) {
            localStorage.setItem('userDirective', directive.value);
        }
    }

    // Load user directive content from localStorage
    function loadUserDirective() {
        const directive = document.getElementById('user_directive');
        const savedDirective = localStorage.getItem('userDirective');
        if (directive && savedDirective) {
            directive.value = savedDirective;
        }
    }

    // Clear user directive from localStorage
    function clearUserDirective() {
        localStorage.removeItem('userDirective');
        const directive = document.getElementById('user_directive');
        if (directive) {
            directive.value = '';
        }
    }

    function toggleWindowAugment() {
        const button = document.getElementById('window-augment-btn');
        const directiveContainer = document.getElementById('user-directive-container');
        
        if (!isAugmented) {
            // Switch TO augmented mode
            if (directiveContainer) {
                directiveContainer.classList.add('show');
            }
            if (button) {
                button.textContent = '일반 모드로';
            }
            
            isAugmented = true;
            localStorage.setItem('augmentedMode', 'true');
            saveAugmentedModeToServer(true);
            updateModeDisplay();
            
        } else {
            // Switch TO normal mode
            if (directiveContainer) {
                directiveContainer.classList.remove('show');
            }
            if (button) {
                button.textContent = '보강 모드로';
            }
            
            isAugmented = false;
            localStorage.setItem('augmentedMode', 'false');
            saveAugmentedModeToServer(false);
            updateModeDisplay();
        }
    }

    // ADD THIS NEW FUNCTION
    function saveAugmentedModeToServer(isAugmented) {
        const sessionId = getSessionId();
        const formData = new FormData();
        formData.append('session_id', sessionId);
        formData.append('augmented_mode', isAugmented.toString());
        
        fetch('/update-augmented-mode', {
            method: 'POST',
            body: formData
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
            }
        })
        .catch(error => console.error('Error saving augmented mode:', error));
    }

    function startAnalyzeProgressPolling() {
        const sessionId = getSessionId();
        
        if (processingPollInterval) {
            clearInterval(processingPollInterval);
            processingPollInterval = null;
        }
        
        processingPollInterval = setInterval(() => {
            fetch('/processing-status/' + sessionId)
                .then(response => response.json())
                .then(data => {
                    updateAnalyzeProgressFromServer(data); // This now updates both progress and status
                    
                    if (data.status === 'completed') {
                        // Display timing information if available
                        if (data.timing_message) {                            
                            const chatOutput = document.getElementById('chat-output');
                            if (chatOutput) {
                                chatOutput.value = data.timing_message;
                            }
                        }
                        
                        // Clean up polling
                        setTimeout(() => {
                            clearInterval(processingPollInterval);
                            processingPollInterval = null;
                            hideAnalyzeProgress();
                            
                            window.location.reload();
                            
                        }, 1500);
                        
                    } else if (data.status === 'error') {
                        // Show timing info even on errors if available
                        if (data.timing_message) {
                            const chatOutput = document.getElementById('chat-output');
                            if (chatOutput) {
                                chatOutput.value = data.timing_message;
                            }
                        }
                        
                        clearInterval(processingPollInterval);
                        processingPollInterval = null;
                        hideAnalyzeProgress();
                        alert('Analysis failed: ' + (data.error || 'Unknown error'));
                    }
                })
                .catch(error => {
                    console.error('Analyze polling error:', error);
                    clearInterval(processingPollInterval);
                    processingPollInterval = null;
                    hideAnalyzeProgress();
                });
        }, 500);
    }

        
    function updateAnalyzeProgressFromServer(data) {
        let message = 'Processing...';
        let progress = -1;
        
        switch(data.status) {
            case 'loading_files':
                message = '파일들 읽는 중...';
                progress = Math.max(data.progress_percent || 0, 10);
                break;
            case 'preprocessing': 
                message = '문서내용 전처리중...';
                progress = Math.max(data.progress_percent || 0, 30);
                break;
            case 'building_vectors':
                message = 'vector store 만드는 중...';
                progress = Math.max(data.progress_percent || 0, 60);
                break;
            case 'finalizing':
                message = '분석 끝내는 중...';
                progress = Math.max(data.progress_percent || 0, 90);
                break;
            case 'completed':
                message = '분석 완료!';
                progress = 100;
                break;
            case 'error':
                message = '분석 실패';
                progress = 0;
                break;
            default:
                message = data.status_message || data.message || '처리중...';
                progress = data.progress_percent || -1;
                break;
        }
        
        updateAnalyzeProgress(progress, message);
        
        // SIMPLIFIED: Only update button text, don't manage status display here
        const analyzeBtn = document.getElementById('analyze-btn');
        if (analyzeBtn) {
            if (data.status === 'completed') {
                analyzeBtn.textContent = '문서 재분석 하기';
            } else if (data.status === 'processing' || data.status === 'loading_files' || 
                    data.status === 'preprocessing' || data.status === 'building_vectors' || 
                    data.status === 'finalizing') {
                analyzeBtn.textContent = '처리중...';
                analyzeBtn.disabled = true;
            } else if (data.status === 'error') {
                analyzeBtn.textContent = '문서 분석 재시도';
                analyzeBtn.disabled = false;
            }
        }
    }
    
    async function saveVectorStore() {
        const saveBtn = document.getElementById('save-vectorstore-btn');
        if (!saveBtn) return;
        
        const originalText = saveBtn.textContent;
        saveBtn.textContent = '저장 중...';
        saveBtn.disabled = true;
        
        try {
            const formData = new FormData();
            formData.append('session_id', getSessionId());
            
            const response = await fetch('/save-vectorstore', {
                method: 'POST',
                body: formData
            });
            
            const result = await response.json();
            
            if (result.success) {
                // Show success message
                alert(result.message);
                
                // Freeze all GUI components
                document.querySelectorAll('button, input, select, textarea').forEach(el => {
                    el.disabled = true;
                });
                document.querySelectorAll('a').forEach(el => {
                    el.style.pointerEvents = 'none';
                    el.style.opacity = '0.5';
                });
                
                // Show frozen notice
                const notice = document.createElement('div');
                notice.style.cssText = 'position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #28a745; color: white; padding: 20px 40px; border-radius: 10px; font-size: 18px; z-index: 10000; box-shadow: 0 4px 20px rgba(0,0,0,0.3);';
                notice.innerHTML = 'Vector store가 저장되었습니다.<br><small style="opacity: 0.8;">페이지를 닫아주세요.</small>';
                document.body.appendChild(notice);
            } else {
                alert('저장 실패: ' + (result.error || '알 수 없는 오류'));
                saveBtn.textContent = originalText;
                saveBtn.disabled = false;
            }
        } catch (error) {
            console.error('Save vectorstore error:', error);
            alert('저장 중 오류가 발생했습니다: ' + error.message);
            saveBtn.textContent = originalText;
            saveBtn.disabled = false;
        }
    }
        
    function showChatProgress() {
        const progressElement = document.getElementById('chat-progress');
        
        if (progressElement) {
            progressElement.style.display = 'inline-block';
        }
        
        // Note: Don't disable submit button since there's no submit button in the chat form
        // The form submits via Enter key or programmatically
    }
        
    function hideChatProgress() {
        const progressElement = document.getElementById('chat-progress');
        const queryInput = document.getElementById('query');
        
        if (progressElement) {
            progressElement.style.display = 'none';
        }
        
        // Clear and reset the input field when processing completes
        if (queryInput) {
            queryInput.value = ''; // Clear the query text
            queryInput.disabled = false; // Re-enable input
            queryInput.style.backgroundColor = ''; // Reset background color
            queryInput.style.opacity = ''; // Reset opacity
            queryInput.style.cursor = ''; // Reset cursor
            queryInput.focus(); // Give focus back for next query
        }
        
        // Reset progress bar
        const progressBar = document.getElementById('chat-progress-bar-fill');
        if (progressBar) {
            progressBar.style.width = '0%';
            progressBar.style.animation = 'none';
        }
    }

    function updateChatProgress(percentage, message, isLongRunning = false) {
        const textElement = document.getElementById('chat-progress-text');
        const percentElement = document.getElementById('chat-progress-percent');
        const progressBar = document.getElementById('chat-progress-bar-fill');
        
        if (textElement) {
            textElement.textContent = message || 'Processing...';
            
            // Special styling for long-running queries
            if (isLongRunning) {
                textElement.style.color = '#ff8c00'; // Orange for long queries
                textElement.style.fontWeight = 'bold';
            } else if (percentage >= 75) {
                textElement.style.color = '#28a745'; // Green for final stages
                textElement.style.fontWeight = 'normal';
            } else if (percentage >= 50) {
                textElement.style.color = '#007bff'; // Blue for processing
                textElement.style.fontWeight = 'normal';
            } else {
                textElement.style.color = '#6c757d'; // Gray for initial stages
                textElement.style.fontWeight = 'normal';
            }
        }
        
        if (progressBar) {
            if (percentage >= 0 && percentage <= 100) {
                // Determinate progress with percentage display
                if (percentElement) {
                    percentElement.textContent = Math.round(percentage) + '%';
                    percentElement.style.color = '#666';
                }
                
                progressBar.style.width = percentage + '%';
                
                // Dynamic color based on progress and query type
                if (isLongRunning) {
                    // Special colors for long-running queries
                    progressBar.style.background = 'linear-gradient(90deg, #ff8c00, #ff6b35)'; // Orange gradient
                } else if (percentage >= 90) {
                    progressBar.style.background = 'linear-gradient(90deg, #28a745, #20c997)'; // Green for final
                } else if (percentage >= 50) {
                    progressBar.style.background = 'linear-gradient(90deg, #007bff, #17a2b8)'; // Blue for processing
                } else {
                    progressBar.style.background = 'linear-gradient(90deg, #ffc107, #fd7e14)'; // Orange for initial
                }
                
                progressBar.style.animation = 'none';
            } else {
                // Indeterminate progress (animated stripe)
                if (percentElement) {
                    percentElement.textContent = '';
                }
                
                progressBar.style.width = '100%';
                
                if (isLongRunning) {
                    // Slower animation for long queries
                    progressBar.style.background = 'linear-gradient(90deg, #ff8c00 25%, transparent 25%, transparent 50%, #ff6b35 50%, #ff6b35 75%, transparent 75%, transparent)';
                    progressBar.style.backgroundSize = '25px 25px';
                    progressBar.style.animation = 'progress-stripe 1.5s linear infinite';
                } else {
                    progressBar.style.background = 'linear-gradient(90deg, #007bff 25%, transparent 25%, transparent 50%, #17a2b8 50%, #17a2b8 75%, transparent 75%, transparent)';
                    progressBar.style.backgroundSize = '20px 20px';
                    progressBar.style.animation = 'progress-stripe 1s linear infinite';
                }
            }
        }
    }
            
    function checkForActiveProcessing() {
        const urlParams = new URLSearchParams(window.location.search);
        if (urlParams.get('processing') === 'true') {
            showChatProgress();
            updateChatProgress(5, 'Connecting to ongoing query processing...');
            
            // Start monitoring but don't auto-scroll yet
            setTimeout(() => {
                startChatProgressPolling();
            }, 500);
            
            // Clean up URL
            const newUrl = window.location.pathname + '?' + 
                Array.from(urlParams.entries())
                    .filter(([key]) => key !== 'processing')
                    .map(([key, value]) => key + '=' + value)
                    .join('&');
            window.history.replaceState({}, '', newUrl);
        }
    }

        
    function preventUnwantedScrolling() {
        // Make sure input focus doesn't trigger scrolling
        const inputs = document.querySelectorAll('textarea, input[type="text"]');
        inputs.forEach(input => {
            input.addEventListener('focus', function(e) {
                // Don't prevent normal focus scrolling, just don't add extra scrolling
            });
            
            input.addEventListener('input', function(e) {
                // Don't scroll when user is typing
            });
        });
        
        // Prevent scrolling on toggle switches or other UI interactions
        const toggles = document.querySelectorAll('.toggle-btn, button[onclick*="toggle"]');
        toggles.forEach(toggle => {
            toggle.addEventListener('click', function(e) {
                // Don't scroll when toggling settings
            });
        });
    }
        
    function showLongQueryNotification() {
        // Create a subtle notification for users about long queries
        const notification = document.createElement('div');
        notification.id = 'long-query-notification';
        notification.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            background: linear-gradient(45deg, #ff8c00, #ff6b35);
            color: white;
            padding: 15px 20px;
            border-radius: 8px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.2);
            z-index: 1001;
            font-size: 14px;
            max-width: 300px;
            line-height: 1.4;
        `;
        notification.innerHTML = `
            <strong>Complex Query Detected</strong><br>
            This query is taking longer than usual. Complex queries can take 30+ seconds to complete.
            <div style="margin-top: 8px; font-size: 12px; opacity: 0.9;">
                The system is working on: RAG query.
            </div>
        `;
        
        document.body.appendChild(notification);
        
        // Auto-remove after 10 seconds
        setTimeout(() => {
            if (notification.parentNode) {
                notification.parentNode.removeChild(notification);
            }
        }, 10000);
    }


    // Replace showAnalyzeProgress and related functions with:
    function showAnalyzeProgress() {
        const progressElement = document.getElementById('analyze-progress');
        const button = document.getElementById('analyze-btn');
        
        if (progressElement) {
            progressElement.style.display = 'inline-block';
        }
        
        if (button) {
            button.disabled = true;
            button.textContent = 'Processing...';
        }
    }

    function hideAnalyzeProgress() {
        const progressElement = document.getElementById('analyze-progress');
        const button = document.getElementById('analyze-btn');
        
        if (progressElement) {
            progressElement.style.display = 'none';
        }
        
        if (button) {
            button.disabled = false;
            // Don't reset button text here - let status display handle it
        }
        
        // Reset progress bar
        const progressBar = document.getElementById('analyze-progress-bar-fill');
        if (progressBar) {
            progressBar.style.width = '0%';
            progressBar.style.animation = 'none';
        }
    }

    function updateAnalyzeProgress(percentage, message) {
        const textElement = document.getElementById('analyze-progress-text');
        const percentElement = document.getElementById('analyze-progress-percent');
        const progressBar = document.getElementById('analyze-progress-bar-fill');
        
        // Make sure container is visible
        const progressElement = document.getElementById('analyze-progress');
        if (progressElement && progressElement.style.display === 'none') {
            progressElement.style.display = 'inline-block';
        }
        
        if (textElement) {
            textElement.textContent = message || 'Processing...';
        }
        
        if (progressBar) {
            if (percentage >= 0 && percentage <= 100) {
                // Determinate progress
                if (percentElement) {
                    percentElement.textContent = percentage + '%';
                }
                
                progressBar.style.width = percentage + '%';
                progressBar.style.background = 'linear-gradient(90deg, #007bff, #28a745)';
                progressBar.style.animation = 'none';
            } else {
                // Indeterminate progress (animated stripe)
                if (percentElement) {
                    percentElement.textContent = '';
                }
                
                progressBar.style.width = '100%';
                progressBar.style.background = 'linear-gradient(90deg, #007bff 25%, transparent 25%, transparent 50%, #007bff 50%, #007bff 75%, transparent 75%, transparent)';
                progressBar.style.backgroundSize = '20px 20px';
                progressBar.style.animation = 'progress-stripe 1s linear infinite';
            }
        }
    }

    function updateProgress(percent, message, details = '') {
        const progressBar = document.getElementById('progress-bar');
        const progressText = document.getElementById('progress-text');
        const progressDetails = document.getElementById('progress-details');
        
        if (progressBar) {
            if (percent === -1) {
                // Indeterminate progress - show animated stripe
                progressBar.style.width = '100%';
                progressBar.style.background = 'linear-gradient(45deg, #007bff 25%, transparent 25%, transparent 50%, #007bff 50%, #007bff 75%, transparent 75%, transparent)';
                progressBar.style.backgroundSize = '20px 20px';
                progressBar.style.animation = 'progress-stripe 1s linear infinite';
            } else {
                // Determinate progress - show normal progress
                progressBar.style.width = Math.max(0, Math.min(100, percent)) + '%';
                progressBar.style.background = 'linear-gradient(45deg, #007bff, #0056b3)';
                progressBar.style.backgroundSize = 'auto';
                progressBar.style.animation = 'none';
            }
        }
        if (progressText) progressText.textContent = message || 'Processing...';
        if (progressDetails) progressDetails.textContent = details || '';
        
    }


        
    function setupUniversalPreservation() {    }
        
    function setupUniversalPreservation() {
        // Preserve inputs before any form submission
        document.addEventListener('submit', function(e) {
            preserveInputsDirectly();
        });
        
        // Preserve inputs before page unload
        window.addEventListener('beforeunload', function(e) {
            preserveInputsDirectly();
        });
        
        // Preserve inputs on dropdown changes
        const dropdowns = document.querySelectorAll('select');
        dropdowns.forEach(dropdown => {
            dropdown.addEventListener('change', function() {
                preserveInputsDirectly();
            });
        });
        
        // Preserve inputs on button clicks that might cause navigation
        const buttons = document.querySelectorAll('button[type="submit"], button[onclick*="location"], a[href*="/"]');
        buttons.forEach(button => {
            button.addEventListener('click', function() {
                preserveInputsDirectly();
            });
        });
        
    }
        
    function updateQueryInputState() {
        const queryInput = document.getElementById('query');
        if (!queryInput) return;
        
        // Check if analysis is completed (status badge exists)
        const statusDisplay = document.getElementById('document-status-display');
        const hasProcessedFiles = statusDisplay !== null;
        
        const isAgentModeOn = true; // Fixed: was undefined
        // Respect query limit - if input has query-limit-disabled class, don't enable
        const isQueryLimitDisabled = queryInput.classList.contains('query-limit-disabled');
        const shouldEnable = !isQueryLimitDisabled && (isAgentModeOn || hasProcessedFiles);
        
        // Update textarea state
        queryInput.disabled = !shouldEnable;
        if (shouldEnable) {
            queryInput.style.backgroundColor = '';
            queryInput.style.cursor = 'text';
            queryInput.style.opacity = '1';
        } else {
            queryInput.style.backgroundColor = '#f5f5f5';
            queryInput.style.cursor = 'not-allowed';
            queryInput.style.opacity = '0.6';
        }
        
        // Update notice
        const chatDisabledNotice = document.querySelector('.chat-disabled-notice');
        if (chatDisabledNotice) {
            chatDisabledNotice.style.display = shouldEnable ? 'none' : 'block';
        }
    }



    // Update web search tool selection
    function updateWebSearchTool(tool) {
        const sessionId = getSessionId();
        fetch('/update-websearch-tool', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ session_id: sessionId, tool: tool })
        }).then(response => response.json())
          .then(data => {
              if (data.success) {
                  console.log('🔧 Web search tool updated to:', tool);
              }
          }).catch(error => console.error('Update tool error:', error));
    }

    function setSearchMode(mode) {
        const sessionId = getSessionId();
        
        fetch('/set-search-mode', {
            method: 'POST',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            body: new URLSearchParams({ session_id: sessionId, mode: mode })
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                console.log('🔍 Search mode set to:', mode);
            } else {
                console.error('Failed to set search mode:', data.error);
            }
        })
        .catch(error => console.error('Set search mode error:', error));
    }

    function toggleMode(mode, currentStateStr) {               
        const sessionId = getSessionId();
        
        const endpointMap = {
            'history': '/toggle-history',
            'websearch': '/toggle-websearch',
        };
        
        const endpoint = endpointMap[mode];
        if (!endpoint) {
            console.error('Unknown toggle mode:', mode);
            return;
        }
        
        fetch(endpoint, {
            method: 'POST',
            headers: { 'Accept': 'application/json' },
            body: new URLSearchParams({ session_id: sessionId })
        }).then(response => {        
            if (!response.ok) {
                throw new Error(`Server error: ${response.status}`);
            }
            
            return response.json();
        })
        .then(data => {
            if (data.success) {
                
                // Find the button using a more reliable method
                const button = document.querySelector(`button[data-mode="${mode}"]`);
                if (button && data.new_state !== undefined) {
                    button.textContent = data.new_state ? 'ON' : 'OFF';
                    button.setAttribute('data-value', data.new_state ? 'True' : 'False');
                    
                    button.className = data.new_state ? 'toggle-btn toggle-on' : 'toggle-btn toggle-off';
                }
                
                // Toggle handlers removed (LLM+Tools and priority display)
                
                if (data.message) {
                }
            } else {
                console.error('Toggle failed:', data);
            }
        })
        .catch(error => {
            console.error('Toggle fetch error:', error);
            
            // Only show error message, don't reload
            const userMessage = error.message.includes('fetch') || error.message.includes('Failed to fetch')
                ? 'Network error. Please check your connection and try again.' 
                : 'Setting update failed. Please try again.';
            
            if (typeof showMessageDialog === 'function') {
                showMessageDialog(userMessage, 'error', 3000);
            } else {
                alert(userMessage);
            }
        });
    }

    function saveAllFormSelections() {
        // Don't save form selections during mode switches
        const isModeSwitching = performance.now() - lastModeSwitchTime < 1000;
        if (isModeSwitching) {
            return;
        }
        
        // CHANGE: Don't save language and model individually since they're synced
        const embedModel = document.getElementById('embed_model_chat');
        
        if (embedModel) localStorage.setItem('savedEmbedModel', embedModel.value);
    }
        
    function restoreAllFormSelections() {
        // Don't restore form selections during mode switches
        const isModeSwitching = performance.now() - lastModeSwitchTime < 1000;
        if (isModeSwitching) {
            return;
        }
        
        // CHANGE: Don't restore language and model individually since they're synced
        const embedModel = document.getElementById('embed_model_chat');
        
        const savedEmbedModel = localStorage.getItem('savedEmbedModel');
        
        if (embedModel && savedEmbedModel) {
            embedModel.value = savedEmbedModel;
            updateEmbedModel(savedEmbedModel); // Call your existing update function
        }
    }

    // Check for start_progress parameter on page load
    function checkStartProgress() {
        const urlParams = new URLSearchParams(window.location.search);
        if (urlParams.get('start_progress') === 'true') {
            showAnalyzeProgress();
            updateProgress(0, 'Initializing...', 'Starting file processing');
            startProcessingPolling();
            
            // Clean up URL
            const newUrl = window.location.pathname + '?' + 
                Array.from(urlParams.entries())
                    .filter(function(entry) { return entry[0] !== 'start_progress'; })
                    .map(function(entry) { return entry[0] + '=' + entry[1]; })
                    .join('&');
            window.history.replaceState({}, '', newUrl);
        }
    }

    // HistoryTextEdit class with query preservation and immediate clearing
    class HistoryTextEdit {
        constructor(textareaId, clearOnNewSession = false, disableArrowNavigation = false) {
            this.textarea = document.getElementById(textareaId);
            this.history = [];
            this.history_index = -1;
            this._processing_query = false;
            this._temp_editing_content = null;
            this.storageKey = `queryHistory_${textareaId}`;
            this.disableArrowNavigation = disableArrowNavigation;

            // Clear history if this is a new session
            if (clearOnNewSession) {
                localStorage.removeItem(this.storageKey);
            }

            this.setupEventListeners();
            this.loadHistoryFromStorage();
        }

        setupEventListeners() {
            var self = this; // Capture 'this' context for use in traditional functions
            
            this.textarea.addEventListener('keydown', function(e) { 
                self.keyPressEvent(e); 
            });
            
            this.textarea.addEventListener('input', function() { 
                self.saveCurrentQuery(); 
            });
            
            this.textarea.addEventListener('blur', function() { 
                self.saveCurrentQuery(); 
            });
            
            window.addEventListener('beforeunload', function() {
                self.saveHistoryToStorage();
                self.saveCurrentQuery();
            });
        }

        cleanup() {
            if (this.textarea) {
                // Create bound versions of the functions to properly remove listeners
                var self = this;
                
                // Remove event listeners - note: we need to recreate the same bound functions
                // This is tricky because the original listeners were created with closures
                // A better approach is to store the bound functions during setup
                
                // For now, clone and replace the element to remove all listeners
                const newTextarea = this.textarea.cloneNode(true);
                this.textarea.parentNode.replaceChild(newTextarea, this.textarea);
                this.textarea = newTextarea;
                
                // Clear references
                this.history = [];
                this.history_index = -1;
                this._processing_query = false;
                this._temp_editing_content = null;
            }
        }
                
        addToHistory(text) {
            if (text && text.trim()) {
                const trimmedText = text.trim();
                if (!this.history.length || this.history[this.history.length - 1] !== trimmedText) {
                    this.history.push(trimmedText);
                    this.saveHistoryToStorage();
                    this.history_index = this.history.length;
                }
            }
        }

        saveCurrentQuery() {
            if (this.textarea) {
                localStorage.setItem('currentQuery', this.textarea.value);
            }
        }

        loadHistoryFromStorage() {
            try {
                const saved = localStorage.getItem(this.storageKey);
                if (saved) {
                    this.history = JSON.parse(saved);
                    this.history_index = this.history.length;
                }
            } catch (e) {
                console.warn('Failed to load history:', e);
            }
        }

        saveHistoryToStorage() {
            try {
                localStorage.setItem(this.storageKey, JSON.stringify(this.history.slice(-100)));
            } catch (e) {
                console.warn('Failed to save history:', e);
            }
        }

        set_processing_state(is_processing) {
            this._processing_query = is_processing;
        }

        keyPressEvent(event) {
            if (this.disableArrowNavigation && ['ArrowUp', 'ArrowDown'].includes(event.key)) {
                return;
            }

            if (this._processing_query && ['ArrowUp', 'ArrowDown'].includes(event.key)) {
                alert("Please wait...");
                event.preventDefault();
                return;
            }

            if (event.key === 'ArrowUp') {
                if (this.history.length > 0) {
                    const current_text = this.textarea.value.trim();
                    if (this.history_index >= this.history.length && current_text) {
                        this._temp_editing_content = current_text;
                    }
                    
                    this.history_index = Math.max(0, this.history_index - 1);
                    this.textarea.value = this.history[this.history_index];
                    this.moveToEnd();
                }
                event.preventDefault();
            }
            else if (event.key === 'ArrowDown') {
                if (this.history.length > 0) {
                    this.history_index = Math.min(this.history.length, this.history_index + 1);
                    if (this.history_index < this.history.length) {
                        this.textarea.value = this.history[this.history_index];
                        this.moveToEnd();
                    } else {
                        if (this._temp_editing_content) {
                            this.textarea.value = this._temp_editing_content;
                        } else {
                            this.textarea.value = '';
                        }
                        this.moveToEnd();
                    }
                }
                event.preventDefault();
            } 
            else if (event.key === 'Enter') {
                if (event.shiftKey) {
                    return; // Allow Shift+Enter for new line
                } else {
                    // Normal mode - submit form
                    const text = this.textarea.value.trim();
                    if (text) {
                        if (!this.history.length || this.history[this.history.length - 1] !== text) {
                            this.history.push(text);
                            this._temp_editing_content = null;
                            this.saveHistoryToStorage();
                        }
                        this.history_index = this.history.length;
                        
                        // Clear the textarea immediately after adding to history
                        //this.textarea.value = '';
                        
                        // Clear saved query
                        clearSavedQueryText();
                        
                        // Show processing dialog with appropriate title
                        showChatProgress();
                        updateChatProgress(-1, 'Processing your question...');
                        startChatProgressPolling(); 
                    }

                    event.preventDefault();
                    
                    const form = this.textarea.closest('form');
                    if (form) {
                        // Create a hidden input with the query text since textarea is now empty
                        let hiddenInput = form.querySelector('input[name="query"][type="hidden"]');
                        if (!hiddenInput) {
                            hiddenInput = document.createElement('input');
                            hiddenInput.type = 'hidden';
                            hiddenInput.name = 'query';
                            form.appendChild(hiddenInput);
                        }
                        hiddenInput.value = text;
                        
                        form.requestSubmit();
                    }
                }
            } else {
                if (this._temp_editing_content) {
                    this._temp_editing_content = null;
                }
            }
        }

        moveToEnd() {
            var self = this; // Capture the correct 'this' context
            setTimeout(function() {
                if (self.textarea && self.textarea.value !== undefined) {
                    self.textarea.selectionStart = self.textarea.value.length;
                    self.textarea.selectionEnd = self.textarea.value.length;
                } else {
                    console.error('Textarea not accessible in moveToEnd');
                }
            }, 0);
        }
    }

    function initializeCollapsibleHeader() {
        const header = document.getElementById('main-header');
        const indicator = document.getElementById('header-indicator');
        
        let isHeaderCollapsed = false;

        // Load saved states
        const savedState = localStorage.getItem('headerCollapsed');
        
        if (savedState === 'true' && header) {
            isHeaderCollapsed = true;
            // Silent collapse - don't show indicator on page load
            header.classList.add('collapsed');
            updateFirstVisibleSection();
        }

        // FIXED: Double-click to TOGGLE hide/restore
        if (header) {
            header.addEventListener('dblclick', function(e) {
                e.preventDefault();
                e.stopPropagation();

                if (isHeaderCollapsed) {
                    restoreHeader();
                    showTemporaryMessage('Header restored', 2000);
                } else {
                    collapseHeader();
                    showTemporaryMessage('Header hidden - Double-click first section to restore', 3000);
                }
            });
        }

        // Double-click handler for first visible section in normal mode
        document.addEventListener('dblclick', function(e) {
            if (!isHeaderCollapsed) return;
            
            const section = e.target.closest('.section');
            const sectionHeading = e.target.closest('.section h3');
            
            if (section && section.classList.contains('first-visible')) {
                e.preventDefault();
                e.stopPropagation();
                restoreHeader();
                showTemporaryMessage('Header restored', 2000);
            } else if (sectionHeading) {
                const parentSection = sectionHeading.closest('.section');
                if (parentSection && parentSection.classList.contains('normal-mode-only')) {
                    e.preventDefault();
                    e.stopPropagation();
                    restoreHeader();
                    showTemporaryMessage('Header restored', 2000);
                }
            }
        });

        function collapseHeader() {
            if (!header) return;
            header.classList.add('collapsed');
            
            if (indicator) {
                indicator.classList.add('show');
                setTimeout(() => indicator.classList.remove('show'), 3000);
            }
            
            isHeaderCollapsed = true;
            updateFirstVisibleSection();
            localStorage.setItem('headerCollapsed', 'true');
        }

        function restoreHeader() {
            if (!header) return;
            header.classList.remove('collapsed');
            if (indicator) indicator.classList.remove('show');
            isHeaderCollapsed = false;
            updateFirstVisibleSection();
            localStorage.setItem('headerCollapsed', 'false');
        }

        function updateFirstVisibleSection() {
            const existingFirstVisible = document.querySelector('.section.first-visible');
            if (existingFirstVisible) {
                existingFirstVisible.classList.remove('first-visible');
                const h3Direct = existingFirstVisible.querySelector(':scope > h3');
                const h3InHeader = existingFirstVisible.querySelector('.section-header h3');
                const sectionHeader = existingFirstVisible.querySelector('.section-header');
                
                if (h3Direct) {
                    h3Direct.style.cursor = '';
                    h3Direct.style.userSelect = '';
                }
                if (h3InHeader) {
                    h3InHeader.style.cursor = '';
                    h3InHeader.style.userSelect = '';
                }
                if (sectionHeader) {
                    sectionHeader.style.cursor = '';
                }
            }

            if (isHeaderCollapsed) {
                const firstSection = document.querySelector('.section');
                if (firstSection) {
                    firstSection.classList.add('first-visible');
                    const h3Direct = firstSection.querySelector(':scope > h3');
                    const h3InHeader = firstSection.querySelector('.section-header h3');
                    const sectionHeader = firstSection.querySelector('.section-header');
                    
                    if (h3Direct) {
                        h3Direct.style.cursor = 'pointer';
                        h3Direct.style.userSelect = 'none';
                    }
                    if (h3InHeader) {
                        h3InHeader.style.cursor = 'pointer';
                        h3InHeader.style.userSelect = 'none';
                    }
                    if (sectionHeader) {
                        sectionHeader.style.cursor = 'pointer';
                    }
                }
            }
        }

        function showTemporaryMessage(message, duration = 2000) {
            const messageDiv = document.createElement('div');
            messageDiv.style.cssText = `
                position: fixed;
                top: 20px;
                left: 50%;
                transform: translateX(-50%);
                background: linear-gradient(45deg, #28a745, #20c997);
                color: white;
                padding: 10px 20px;
                border-radius: 25px;
                font-weight: bold;
                font-size: 14px;
                z-index: 10000;
                box-shadow: 0 4px 12px rgba(0,0,0,0.3);
                opacity: 0;
                transition: all 0.3s ease;
            `;
            messageDiv.textContent = message;
            
            document.body.appendChild(messageDiv);
            
            setTimeout(() => {
                messageDiv.style.opacity = '1';
                messageDiv.style.transform = 'translateX(-50%) translateY(10px)';
            }, 10);
            
            setTimeout(() => {
                messageDiv.style.opacity = '0';
                messageDiv.style.transform = 'translateX(-50%) translateY(-10px)';
                setTimeout(() => {
                    if (messageDiv.parentNode) {
                        messageDiv.parentNode.removeChild(messageDiv);
                    }
                }, 300);
            }, duration);
        }
    }

    // === ADD THIS: DOUBLE-CLICK TO HIDE/SHOW HEADER ===
    document.querySelectorAll('.collapsible-header, header').forEach(header => {
        header.addEventListener('dblclick', function () {
            const chatContainer = document.querySelector('.chat-container') || document.body;
            const isHidden = chatContainer.style.marginTop && chatContainer.style.marginTop !== '0px';

            if (!isHidden) {
                // Hide header
                chatContainer.style.transition = 'margin-top 0.3s ease';
                chatContainer.style.marginTop = `-${header.offsetHeight}px`;
                header.style.opacity = '0.7';
                header.title = 'Double-click to show';
            } else {
                // Show header
                chatContainer.style.marginTop = '0px';
                header.style.opacity = '1';
                header.title = 'Double-click to hide';
            }
        });
    });

    // Add this single generic function to your existing code
    function handleAjaxFormSubmission(element, endpoint, successCallback = null, confirmMessage = null) {
        if (confirmMessage && !confirm(confirmMessage)) return;
        
        // Find the closest form or create form data from element attributes
        const form = element.closest('form') || element;
        const formData = new FormData();
        
        // Add session_id automatically
        formData.append('session_id', getSessionId());
        
        // Extract data from form elements or data attributes
        if (form.tagName === 'FORM') {
            // Use existing form data
            const existingFormData = new FormData(form);
            for (let [key, value] of existingFormData.entries()) {
                formData.append(key, value);
            }
        } else {
            // Extract from data attributes
            for (let attr of element.attributes) {
                if (attr.name.startsWith('data-')) {
                    const key = attr.name.replace('data-', '').replace(/-/g, '_');
                    formData.append(key, attr.value);
                }
            }
        }
        
        fetch(endpoint, {
            method: 'POST',
            body: formData
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                if (successCallback) {
                    successCallback(data, element);
                } else {
                    // Default success handling
                    if (data.message) {
                        showMessageDialog(data.message, 'success', 2000);
                    }
                }
            } else {
                showMessageDialog(data.error || 'Operation failed', 'error', 3000);
            }
        })
        .catch(error => {
            console.error('AJAX error:', error);
            showMessageDialog('Network error occurred', 'error', 3000);
        });
    }

    function updateRemoveButtonVisibility(selectedCount) {
        const removeForm = document.getElementById('remove-selected-form');
        const countDisplay = document.getElementById('selected-count-display');
        
        if (removeForm) {
            if (selectedCount > 0) {
                removeForm.style.display = 'inline';
            } else {
                removeForm.style.display = 'none';
            }
        }
        
        if (countDisplay) {
            countDisplay.textContent = selectedCount;
        }
    }
    
    function updateFileSelections(data, element) {
        // Update selected count displays
        if (data.selected_count !== undefined) {
            const countElements = document.querySelectorAll('[data-selected-count]');
            countElements.forEach(el => el.textContent = data.selected_count);
            
            // Update remove button visibility - ADD THIS LINE:
            updateRemoveButtonVisibility(data.selected_count);
        }
        
        // Update UI elements
        document.querySelectorAll('.files-table tbody tr').forEach(row => {
            if (data.action === 'select_all') {
                row.classList.add('selected');
                const btn = row.querySelector('button');
                if (btn) btn.textContent = '✓';
            } else if (data.action === 'deselect_all') {
                row.classList.remove('selected');
                const btn = row.querySelector('button');
                if (btn) btn.textContent = '○';
            }
        });
        
        if (data.message) showMessageDialog(data.message, 'success', 2000);
    }

    function updateSingleFileSelection(data, element) {
        const row = element.closest('tr');
        if (data.action === 'selected') {
            row.classList.add('selected');
            element.textContent = '✓';
        } else {
            row.classList.remove('selected');
            element.textContent = '○';
        }
        
        // Update count using existing pattern
        const countElements = document.querySelectorAll('[data-selected-count]');
        countElements.forEach(el => el.textContent = data.selected_count);
        
        // Update remove button visibility - ADD THIS LINE:
        updateRemoveButtonVisibility(data.selected_count);
    }

    function removeSingleFile(data, element) {
        const row = element.closest('tr');
        if (row) row.remove();
        
        // Use your existing file display update logic
        if (typeof updateFilesDisplay === 'function') {
            updateFilesDisplay();
        }
        
        if (data.message) showMessageDialog(data.message, 'success', 2000);
    }

    function updateConfigSuccess(data, element) {
        // Reuse your existing visual feedback pattern
        const originalText = element.textContent;
        element.textContent = 'Updated!';
        element.style.backgroundColor = '#28a745';
        
        setTimeout(() => {
            element.textContent = originalText;
            element.style.backgroundColor = '';
        }, 1500);
        
        if (data.message) showMessageDialog(data.message, 'success', 3000);
    }

    function reloadPage(data, element) {
        // For operations that require full reload
        location.reload();
    }

    // Synchronize language selection between modes
    function syncLanguageSelection(selectedLanguage, sourceMode) {
        const normalLanguageSelect = document.getElementById('language');
        
        // Update dropdown
        if (normalLanguageSelect && normalLanguageSelect.value !== selectedLanguage) {
            normalLanguageSelect.value = selectedLanguage;
        }
        
        // Save to localStorage for persistence
        localStorage.setItem('syncedLanguage', selectedLanguage);
        
        // Send to server (use existing endpoint)
        updateLanguageOnServer(selectedLanguage);
        
    }

    // Synchronize model selection between modes
    function syncModelSelection(selectedModel, sourceMode) {
        const normalModelSelect = document.getElementById('model');
        
        // Update dropdown
        if (normalModelSelect && normalModelSelect.value !== selectedModel) {
            normalModelSelect.value = selectedModel;
        }
        
        // Save to localStorage for persistence
        localStorage.setItem('syncedModel', selectedModel);
        
        // Send to server (use existing endpoint)
        updateModelOnServer(selectedModel);
        
    }

    // Helper function to update language on server
    function updateLanguageOnServer(language) {
        const sessionId = getSessionId();
        const formData = new FormData();
        formData.append('session_id', sessionId);
        formData.append('language', language);
        
        fetch('/update-language', {
            method: 'POST',
            body: formData
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
            }
        })
        .catch(error => console.error('Error updating language:', error));
    }

    // Helper function to update model on server
    function updateModelOnServer(model) {
        const sessionId = getSessionId();
        const formData = new FormData();
        formData.append('session_id', sessionId);
        formData.append('model', model);
        
        fetch('/update-llm-model', {
            method: 'POST',
            body: formData
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
            }
        })
        .catch(error => console.error('Error updating model:', error));
    }

    // Load and apply synced selections on page load
    function loadSyncedSelections() {
        const syncedLanguage = localStorage.getItem('syncedLanguage');
        const syncedModel = localStorage.getItem('syncedModel');
        
        if (syncedLanguage) {
            const normalLanguageSelect = document.getElementById('language');
            if (normalLanguageSelect) normalLanguageSelect.value = syncedLanguage;
        }
        
        if (syncedModel) {
            const normalModelSelect = document.getElementById('model');
            if (normalModelSelect) normalModelSelect.value = syncedModel;
        }
    }

    // Initialize sync when page loads
    function initializeModeSync() {
        loadSyncedSelections();
    }

    // Apply synced selections
    function applySyncedSelections() {
        const syncedLanguage = localStorage.getItem('syncedLanguage');
        const syncedModel = localStorage.getItem('syncedModel');
        
        if (syncedLanguage) {
            const normalLanguageSelect = document.getElementById('language');
            if (normalLanguageSelect && normalLanguageSelect.value !== syncedLanguage) {
                normalLanguageSelect.value = syncedLanguage;
            }
        }
        
        if (syncedModel) {
            const normalModelSelect = document.getElementById('model');
            if (normalModelSelect && normalModelSelect.value !== syncedModel) {
                normalModelSelect.value = syncedModel;
            }
        }
    }
    
    document.addEventListener('DOMContentLoaded', async function () {
        const htmlElement = document.documentElement;
        const isFreshServerStart = htmlElement.dataset.freshServerStart === 'true';
        
        if (isFreshServerStart) {
            cleanupForFreshStart();
            htmlElement.dataset.freshServerStart = 'false';
        }

        try {
            const urlParams = new URLSearchParams(window.location.search);
            const hasActiveQuery = urlParams.get('show_cancel') === 'true';

            loadFontSize();
            loadSpacing();

            const htmlElement = document.documentElement;
            isAugmented = htmlElement.dataset.augmentedMode === 'true';

            // Only restore from localStorage if NOT a fresh server start
            if (!isFreshServerStart) {
                const savedAugmented = localStorage.getItem('augmentedMode');
                if (savedAugmented === 'true') {
                    isAugmented = true;
                }
            }
            
            // Apply augmented mode UI immediately
            if (isAugmented) {
                const directiveContainer = document.getElementById('user-directive-container');
                const button = document.getElementById('window-augment-btn');
                
                if (directiveContainer) directiveContainer.classList.add('show');
                if (button) button.textContent = '일반 모드로';
            }
            
            // Sync with localStorage
            localStorage.setItem('augmentedMode', isAugmented.toString());
            if (typeof updateModeDisplay === 'function') {
                updateModeDisplay();
            }

            // === EARLY INPUT RESTORATION (skip on fresh server start) ===
            if (!isFreshServerStart && typeof restoreInputsOptimized === 'function') {
                restoreInputsOptimized();
            }

            /* --------------------------------------------------------------
            NEW SESSION + INPUT CLEAR
            -------------------------------------------------------------- */
            const currentSessionId = getSessionId();
            const lastSessionId = localStorage.getItem('lastSessionId');
            const forceClear = urlParams.get('force_clear') === 'true';
            const isNewSession = !lastSessionId || lastSessionId !== currentSessionId;

            if (isNewSession || forceClear) {
                const queryInput = document.getElementById('query');
                if (queryInput) queryInput.value = '';

                // ✅ Only clear query history on fresh server start or force_clear
                const shouldClearHistory = isFreshServerStart || forceClear;
                
                const keysToRemove = [];
                for (let i = 0; i < localStorage.length; i++) {
                    const key = localStorage.key(i);
                    if (key && (
                        ((isFreshServerStart || forceClear) && key.startsWith('queryHistory_')) ||  // 이 코드는 simple_bible에서는 잘 되는데 kms에서는 고쳐야 한다.
                        key === 'currentQuery' ||
                        key === 'savedCursorPosition' ||
                        key === 'syncedModel' ||
                        key === 'augmentedMode' ||
                        key === 'userDirective'
                    )) {
                        keysToRemove.push(key);
                    }
                }
                keysToRemove.forEach(k => localStorage.removeItem(k));
                
                localStorage.removeItem('headerCollapsed');
                
                // Also restore header visually
                const header = document.querySelector('.header');
                if (header) {
                    header.classList.remove('collapsed');
                }
                
                localStorage.setItem('lastSessionId', currentSessionId);

                const cleanUrl = `${window.location.pathname}?session_id=${currentSessionId}${window.location.hash}`;
                history.replaceState(null, '', cleanUrl);
            }

            /* --------------------------------------------------------------
            HISTORY TEXT EDIT INITIALIZATION
            -------------------------------------------------------------- */
            if (window.normalInputHistory) {
                if (typeof window.normalInputHistory.cleanup === 'function') {
                    window.normalInputHistory.cleanup();
                }
                window.normalInputHistory = null;
            }

            if (document.getElementById('query') && !window.normalInputHistory) {
                window.normalInputHistory = new HistoryTextEdit('query');
            }
            
            // === DIRECTION PERSISTENCE SETUP ===
            if (typeof setupDirectionPersistence === 'function') {
                setupDirectionPersistence();
            }

            // === UNIVERSAL INPUT PRESERVATION SETUP ===
            if (typeof setupLightweightPreservation === 'function') {
                setupLightweightPreservation();
            }
            
            // === SELECTION HANDLING INITIALIZATION ===
            if (typeof initializeMoveButton === 'function') {
                initializeMoveButton();
            }
            
            // === USER DIRECTIVE MANAGEMENT ===
            if (!isFreshServerStart && typeof loadUserDirective === 'function') {
                loadUserDirective();
            }
            
            const directive = document.getElementById('user_directive');
            if (directive) {
                if (typeof saveUserDirective === 'function') {
                    directive.addEventListener('input', saveUserDirective);
                    directive.addEventListener('blur', saveUserDirective);
                }
            }
            
            // === FORM RESTORATION ===
            if (typeof restoreAllFormSelections === 'function') {
                restoreAllFormSelections();
            }

            /* --------------------------------------------------------------
            PROGRESS BAR + SUBMIT LOGIC
            -------------------------------------------------------------- */
            let isProcessing = false;

            function stopProgress() {
                if (typeof hideChatProgress === 'function') {
                    hideChatProgress();
                }
                isProcessing = false;
                const queryInput = document.getElementById('query');
                if (queryInput) {
                    queryInput.disabled = false;
                    queryInput.style.backgroundColor = '';
                    queryInput.style.opacity = '';
                    queryInput.style.cursor = '';
                }
            }

            // ENTER KEY → submitQuery()
            const queryInputElement = document.getElementById('query');
            if (queryInputElement) {
                queryInputElement.addEventListener('keydown', function (e) {
                    if (e.key === 'Enter' && !e.shiftKey && !isProcessing) {
                        e.preventDefault();
                        submitQuery();
                    }
                });
            }

            // FORM SUBMIT HANDLING
            const chatForm = document.getElementById('chat-form');
            if (chatForm) {
                chatForm.addEventListener('submit', function (e) {
                    const queryInput = document.getElementById('query');
                    if (queryInput && queryInput.value.trim()) {
                        const queryText = queryInput.value.trim();
                        
                        if (window.normalInputHistory && typeof window.normalInputHistory.addToHistory === 'function') {
                            window.normalInputHistory.addToHistory(queryText);
                        }
                        
                        queryInput.disabled = true;
                        queryInput.style.backgroundColor = '#f8f9fa';
                        queryInput.style.opacity = '0.7';
                        queryInput.style.cursor = 'not-allowed';
                        
                        if (typeof clearSavedQueryText === 'function') {
                            clearSavedQueryText();
                        }
                        
                        let hiddenQueryInput = chatForm.querySelector('input[name="query"][type="hidden"]');
                        if (!hiddenQueryInput) {
                            hiddenQueryInput = document.createElement('input');
                            hiddenQueryInput.type = 'hidden';
                            hiddenQueryInput.name = 'query';
                            chatForm.appendChild(hiddenQueryInput);
                        }
                        hiddenQueryInput.value = queryText;
                        
                        if (typeof showChatProgress === 'function') {
                            showChatProgress();
                        }
                        if (typeof updateChatProgress === 'function') {
                            updateChatProgress(5, 'Submitting query...');
                        }
                        if (typeof startChatProgressPolling === 'function') {
                            setTimeout(startChatProgressPolling, 1000);
                        }
                    }
                });
            }

            // === ADDITIONAL INITIALIZATIONS ===
            if (typeof initializeModeSync === 'function') {
                initializeModeSync();
            }
            
            if (typeof updateQueryInputState === 'function') {
                setTimeout(updateQueryInputState, 500);
            }
            
            if (typeof checkStartProgress === 'function') {
                checkStartProgress();
            }
            
            if (typeof checkForActiveProcessing === 'function') {
                checkForActiveProcessing();
            }
            
            if (typeof checkAndScrollToBottom === 'function') {
                checkAndScrollToBottom();
            }
            
            if (typeof preventUnwantedScrolling === 'function') {
                preventUnwantedScrolling();
            }
            
            initializeCollapsibleHeader();

            // === LATE INPUT RESTORATION ===
            setTimeout(() => {
                if (!isFreshServerStart && typeof restoreInputsOptimized === 'function') {
                    restoreInputsOptimized();
                }
            }, 500);
            
            // === LATE AUGMENTED MODE UI APPLICATION ===
            if (!isFreshServerStart) {
                setTimeout(() => {
                    if (isAugmented) {
                        const directiveContainer = document.getElementById('user-directive-container');
                        const button = document.getElementById('window-augment-btn');
                        
                        if (directiveContainer && !directiveContainer.classList.contains('show')) {
                            directiveContainer.classList.add('show');
                        }
                        if (button && button.textContent !== '일반 모드로') {
                            button.textContent = '일반 모드로';
                        }
                    }
                }, 1000);
            }

            // === BRUTE FORCE FIX: Force hide directive window and clear query on fresh start ===
            if (isFreshServerStart) {
                const directiveContainer = document.getElementById('user-directive-container');
                const button = document.getElementById('window-augment-btn');
                const queryInput = document.getElementById('query');
                const userDirective = document.getElementById('user_directive');

                if (directiveContainer) directiveContainer.classList.remove('show');
                if (button) button.textContent = '보강 모드로';
                if (queryInput) queryInput.value = '';
                if (userDirective) userDirective.value = '';
            }

            /* --------------------------------------------------------------
            CHECK FOR ACTIVE QUERY
            -------------------------------------------------------------- */
            try {
                if (hasActiveQuery) {
                    isProcessing = true;
                    
                    if (typeof showChatProgress === 'function') {
                        showChatProgress();
                    } else {
                        console.warn('⚠️ showChatProgress not defined');
                    }
                    
                    if (typeof updateChatProgress === 'function') {
                        updateChatProgress(10, '처리 시작...');
                    } else {
                        console.warn('⚠️ updateChatProgress not defined');
                    }
                    
                    if (typeof startChatProgressPolling === 'function') {
                        startChatProgressPolling();
                    } else {
                        console.error('❌ startChatProgressPolling not defined');
                    }
                }
            } catch (pollingError) {
                console.error('❌ Polling initialization error:', pollingError);
                console.error('Stack:', pollingError.stack);
            }

        } catch (error) {
            console.error('❌ DOMContentLoaded error:', error);
            console.error('Stack:', error.stack);
        }
    });

    // Save query text before any form submission that might cause a page reload
    document.addEventListener('submit', function(e) {
        const form = e.target;
        
        // Only handle chat form submissions for query clearing
        if (form && form.id === 'chat-form') {
            // Query clearing is already handled in the form's submit event listener above
            return;
        }
        
        // For other forms (like toggle buttons), save the query text to restore after reload
        if (form && !form.action.includes('/chat')) {
            saveQueryTextWithPosition();
        }
    });

    // Android-friendly history navigation functions
    function navigateQueryHistoryUp() {
        const manager = window.normalInputHistory;
        if (!manager) {
            console.log('normalInputHistory not found');
            return;
        }
        
        if (manager.history.length > 0) {
            const current_text = manager.textarea.value.trim();
            if (manager.history_index >= manager.history.length && current_text) {
                manager._temp_editing_content = current_text;
            }
            
            manager.history_index = Math.max(0, manager.history_index - 1);
            manager.textarea.value = manager.history[manager.history_index];
            manager.moveToEnd();
        }
    }
    
    function navigateQueryHistoryDown() {
        const manager = window.normalInputHistory;
        if (!manager) {
            console.log('normalInputHistory not found');
            return;
        }
        
        if (manager.history.length > 0) {
            manager.history_index = Math.min(manager.history.length, manager.history_index + 1);
            if (manager.history_index < manager.history.length) {
                manager.textarea.value = manager.history[manager.history_index];
                manager.moveToEnd();
            } else {
                if (manager._temp_editing_content) {
                    manager.textarea.value = manager._temp_editing_content;
                } else {
                    manager.textarea.value = '';
                }
                manager.moveToEnd();
            }
        }
    }

    function testProgressDialog() {
        const modal = document.getElementById('progress-modal');
        if (modal) {
            modal.style.display = 'flex';
            document.getElementById('progress-text').textContent = 'Testing...';
            document.getElementById('progress-bar').style.width = '50%';
            setTimeout(function() { modal.style.display = 'none'; }, 3000);
        } else {
            alert('Progress modal not found in HTML');
        }
    }    

    // 대화하기 출력 저장 기능
    async function saveOutputToDocx() {
        const chatHistory = document.querySelector('.chat-history');
        if (!chatHistory || !chatHistory.innerHTML.trim()) {
            alert('저장할 대화 내용이 없습니다.');
            return;
        }

        const saveBtn = document.getElementById('normal-save-btn');
        const originalText = saveBtn.textContent;
        saveBtn.textContent = '저장 중...';
        saveBtn.disabled = true;

        try {
            const response = await fetch('/save-chat-to-pdf', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    html_content: chatHistory.innerHTML,
                    filename: 'chat_output.docx',
                    session_id: '{{ session_id }}'
                })
            });

            if (response.ok) {
                const blob = await response.blob();
                const url = window.URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = 'chat_output.pdf';
                document.body.appendChild(a);
                a.click();
                window.URL.revokeObjectURL(url);
                a.remove();
            } else {
                const error = await response.json();
                alert('저장 실패: ' + (error.detail || '알 수 없는 오류'));
            }
        } catch (error) {
            console.error('Save error:', error);
            alert('저장 중 오류가 발생했습니다: ' + error.message);
        } finally {
            saveBtn.textContent = originalText;
            saveBtn.disabled = false;
        }
    }
    </script>

    <!-- Document Filter Modal -->
    <div id="doc-filter-modal" class="doc-filter-modal">
        <div class="doc-filter-content">
            <div class="doc-filter-header">
                <h3>📄 문서 선택</h3>
                <button type="button" class="doc-filter-close" onclick="closeDocumentFilter()">&times;</button>
            </div>
            <div class="doc-filter-list" id="doc-filter-list">
                <!-- Document checkboxes will be populated by JavaScript -->
            </div>
            <div class="doc-filter-status" id="doc-filter-status">
                전체 문서 사용 중
            </div>
            <div class="doc-filter-actions">
                <button type="button" class="doc-filter-select-all" onclick="toggleAllDocuments()">전체 선택/해제</button>
                <button type="button" class="doc-filter-clear" onclick="clearDocumentFilter()">필터 해제</button>
                <button type="button" class="doc-filter-apply" onclick="applyDocumentFilter()">적용</button>
            </div>
        </div>
    </div>


<!-- Query Limit Script -->
<script>
(function() {
    // window.name is unique per window, but we use cookie to identify browser
    // Only the FIRST window of a browser gets the slot
    if (!window.name || !window.name.startsWith('qlimit_')) {
        window.name = 'qlimit_' + Math.random().toString(36).substr(2, 9) + '_' + Date.now();
    }
    const windowId = window.name;
    console.log('🔑 Window ID: ' + windowId);
    
    // Intercept fetch to add headers for /chat requests
    const originalFetch = window.fetch;
    window.fetch = function(url, options = {}) {
        if (url && (url.includes('/chat') || url.includes('/can-query'))) {
            options.headers = options.headers || {};
            if (options.headers instanceof Headers) {
                options.headers.set('X-Window-Id', windowId);
            } else {
                options.headers['X-Window-Id'] = windowId;
            }
        }
        return originalFetch(url, options);
    };
    
    async function checkQueryPermission() {
        try {
            const response = await fetch('/can-query?window_id=' + encodeURIComponent(windowId));
            const data = await response.json();
            const queryInput = document.getElementById('query');
            const submitBtn = document.querySelector('button[type="submit"]');
            if (!data.can_query) {
                if (queryInput) {
                    queryInput.disabled = true;
                    queryInput.classList.add('query-limit-disabled');
                    queryInput.placeholder = data.reason || '쿼리 사용자 수 제한(' + data.max + '명)에 도달했습니다.';
                    queryInput.style.backgroundColor = '#f0f0f0';
                }
                if (submitBtn) { submitBtn.disabled = true; submitBtn.style.opacity = '0.5'; }
                console.log('⚠️ ' + (data.reason || 'Query limit reached') + ' (' + data.active + '/' + data.max + ')');
            } else {
                if (queryInput) {
                    queryInput.disabled = false;
                    queryInput.classList.remove('query-limit-disabled');
                    queryInput.placeholder = '';
                    queryInput.style.backgroundColor = '';
                }
                if (submitBtn) { submitBtn.disabled = false; submitBtn.style.opacity = '1'; }
                console.log('✅ Query allowed: ' + data.active + '/' + data.max);
            }
        } catch (e) { console.error('Failed to check query permission:', e); }
    }
    
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', function() {
            setTimeout(checkQueryPermission, 100);
        });
    } else { 
        setTimeout(checkQueryPermission, 100);
    }
    setInterval(checkQueryPermission, 5000);
})();
</script>

<!-- Window ID Generation & Header Injection -->
<script>
if (typeof isAgentModeOn === 'undefined') var isAgentModeOn = false;
if (!window.name || !window.name.startsWith('qlimit_')) {
    window.name = 'qlimit_' + Math.random().toString(36).substr(2, 9) + '_' + Date.now();
}
const WINDOW_ID = window.name;

// Intercept ALL fetch calls to add X-Window-Id header
const _originalFetch = window.fetch;
window.fetch = function(url, options = {}) {
    if (!options.headers) {
        options.headers = {};
    }
    if (options.headers instanceof Headers) {
        options.headers.set('X-Window-Id', WINDOW_ID);
    } else {
        options.headers['X-Window-Id'] = WINDOW_ID;
    }
    return _originalFetch.apply(this, [url, options]);
};

// Update user code display after window_id is set
function updateUserCodeDisplay() {
    const urlParams = new URLSearchParams(window.location.search);
    const sessionId = urlParams.get('session_id');
    if (sessionId && WINDOW_ID) {
        fetch('/get-user-code?session_id=' + encodeURIComponent(sessionId), {
            headers: { 'X-Window-Id': WINDOW_ID }
        })
            .then(r => r.json())
            .then(data => {
                const el = document.getElementById('user-code-indicator');
                if (el && data.user_code && data.user_code !== '?') {
                    el.textContent = '(' + data.user_code + ')';
                }
            })
            .catch(e => console.log('User code fetch error:', e));
    }
}
setTimeout(updateUserCodeDisplay, 100);
</script>

</body>
</html>

