<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Corporate Memory - Data Analyst Portal</title>
    {% if not config.THEME_FONT_URL %}
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
    {% endif %}
    <link rel="stylesheet" href="{{ url_for('static', filename='style-custom.css') }}">
    <style>
        /* Corporate Memory Page - Design System Styles */
        .container-memory {
            max-width: 1000px;
            margin: 0 auto;
            padding: var(--space-6);
        }

        /* Header */
        .page-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding-bottom: var(--space-5);
            border-bottom: 1px solid var(--border);
            margin-bottom: var(--space-6);
        }

        .header-left {
            display: flex;
            align-items: center;
            gap: var(--space-4);
        }

        .back-link {
            display: flex;
            align-items: center;
            gap: var(--space-2);
            color: var(--text-secondary);
            text-decoration: none;
            font-size: var(--text-sm);
            padding: var(--space-2) var(--space-3);
            border-radius: var(--radius-md);
            transition: all 0.15s;
        }

        .back-link:hover {
            background: var(--border-light);
            color: var(--text-primary);
        }

        .page-title {
            display: flex;
            align-items: center;
            gap: var(--space-3);
        }

        .page-title h1 {
            font-size: var(--text-xl);
            font-weight: var(--font-semibold);
        }

        .page-icon {
            width: 36px;
            height: 36px;
            background: var(--warning);
            border-radius: var(--radius-lg);
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
        }

        /* Stats Bar */
        .stats-bar {
            display: flex;
            gap: var(--space-6);
            padding: var(--space-5);
            background: var(--surface);
            border: 1px solid var(--border);
            border-radius: var(--radius-xl);
            box-shadow: var(--shadow-sm);
            margin-bottom: var(--space-6);
        }

        .stat-item {
            text-align: center;
        }

        .stat-item .value {
            font-size: var(--text-xl);
            font-weight: var(--font-bold);
            color: var(--text-primary);
        }

        .stat-item .label {
            font-size: var(--text-xs);
            color: var(--text-secondary);
            text-transform: uppercase;
        }

        .stat-item.highlight .value {
            color: var(--warning);
        }

        .stat-divider {
            width: 1px;
            background: var(--border);
        }

        .stats-bar-right {
            margin-left: auto;
            display: flex;
            align-items: center;
            gap: var(--space-3);
        }

        .sync-info {
            font-size: var(--text-sm);
            color: var(--success);
            display: flex;
            align-items: center;
            gap: var(--space-2);
        }

        /* Toolbar */
        .toolbar {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: var(--space-5);
            gap: var(--space-4);
        }

        .search-box {
            flex: 1;
            max-width: 320px;
            position: relative;
        }

        .search-box input {
            width: 100%;
            padding: var(--space-2) var(--space-3) var(--space-2) 36px;
            border: 1px solid var(--border);
            border-radius: var(--radius-md);
            font-size: var(--text-base);
            background: var(--surface);
        }

        .search-box input:focus {
            outline: none;
            border-color: var(--primary);
            box-shadow: 0 0 0 2px var(--primary-light);
        }

        .search-box svg {
            position: absolute;
            left: var(--space-3);
            top: 50%;
            transform: translateY(-50%);
            color: var(--text-secondary);
        }

        .filter-group {
            display: flex;
            gap: var(--space-2);
        }

        .filter-btn {
            padding: var(--space-2) var(--space-3);
            background: var(--surface);
            border: 1px solid var(--border);
            border-radius: var(--radius-md);
            font-size: var(--text-sm);
            color: var(--text-secondary);
            cursor: pointer;
            transition: all 0.15s;
        }

        .filter-btn:hover {
            border-color: var(--text-secondary);
        }

        .filter-btn.active {
            background: var(--primary-light);
            border-color: var(--primary);
            color: var(--primary);
        }

        .sort-select {
            padding: var(--space-2) var(--space-3);
            border: 1px solid var(--border);
            border-radius: var(--radius-md);
            font-size: var(--text-sm);
            background: var(--surface);
            color: var(--text-primary);
            cursor: pointer;
        }

        /* Knowledge List */
        .knowledge-list {
            display: flex;
            flex-direction: column;
            gap: var(--space-4);
        }

        .knowledge-item {
            background: var(--surface);
            border: 1px solid var(--border);
            border-radius: var(--radius-xl);
            box-shadow: var(--shadow-sm);
            padding: var(--space-5);
            transition: all 0.15s;
        }

        .knowledge-item:hover {
            border-color: var(--primary);
            box-shadow: var(--shadow-md);
        }

        .knowledge-item.synced {
            border-left: 3px solid var(--success);
        }

        .knowledge-header {
            display: flex;
            justify-content: space-between;
            align-items: flex-start;
            margin-bottom: var(--space-3);
        }

        .knowledge-title {
            font-size: var(--text-md);
            font-weight: var(--font-semibold);
            color: var(--text-primary);
            margin-bottom: var(--space-1);
        }

        .knowledge-meta {
            display: flex;
            align-items: center;
            gap: var(--space-3);
            font-size: var(--text-xs);
            color: var(--text-secondary);
        }

        .category-badge {
            padding: 2px 8px;
            border-radius: var(--radius-full);
            font-size: var(--text-xs);
            font-weight: var(--font-medium);
        }

        .category-badge.data_analysis { background: rgba(16, 183, 127, 0.1); color: var(--success); }
        .category-badge.api_integration { background: var(--primary-light); color: var(--primary); }
        .category-badge.debugging { background: rgba(234, 88, 12, 0.1); color: var(--error); }
        .category-badge.performance { background: rgba(245, 159, 10, 0.1); color: #b45309; }
        .category-badge.workflow { background: rgba(139, 92, 246, 0.1); color: #7c3aed; }
        .category-badge.infrastructure { background: rgba(107, 114, 128, 0.1); color: var(--text-secondary); }
        .category-badge.business_logic { background: rgba(16, 183, 127, 0.1); color: #0d9668; }

        .domain-badge {
            display: inline-block;
            padding: 2px 8px;
            background: var(--primary-light, #e8f0fe);
            color: var(--primary, #1a73e8);
            border-radius: var(--radius-full, 999px);
            font-size: var(--text-xs);
            font-weight: var(--font-medium);
        }

        .confidence-badge {
            display: inline-block;
            padding: 2px 8px;
            background: #f0fdf4;
            color: #16a34a;
            border-radius: var(--radius-full, 999px);
            font-size: var(--text-xs);
            font-weight: var(--font-medium);
        }

        .source-badge {
            display: inline-block;
            padding: 2px 8px;
            border-radius: var(--radius-full, 999px);
            font-size: var(--text-xs);
            font-weight: var(--font-medium);
        }

        .source-badge.verification {
            background: #dbeafe;
            color: #1d4ed8;
        }

        .source-badge.mandatory {
            background: #fef3c7;
            color: #92400e;
        }

        .status-badge {
            display: inline-block;
            padding: 2px 8px;
            border-radius: var(--radius-full, 999px);
            font-size: var(--text-xs);
            font-weight: var(--font-medium);
        }
        .status-badge.approved { background: #dcfce7; color: #166534; }
        .status-badge.pending { background: #fef9c3; color: #854d0e; }
        .status-badge.mandatory { background: #dbeafe; color: #1e40af; }
        .status-badge.rejected { background: #fee2e2; color: #991b1b; }

        .knowledge-content {
            font-size: var(--text-base);
            color: var(--text-secondary);
            line-height: 1.7;
            margin-bottom: var(--space-4);
        }

        .knowledge-content code {
            font-family: var(--font-mono);
            font-size: var(--text-sm);
            background: var(--background);
            padding: 2px 6px;
            border-radius: var(--radius-sm);
            color: var(--text-primary);
        }

        .knowledge-footer {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding-top: var(--space-3);
            border-top: 1px solid var(--border-light);
        }

        .knowledge-tags {
            display: flex;
            gap: var(--space-2);
        }

        .tag {
            font-size: var(--text-xs);
            color: var(--text-secondary);
            background: var(--background);
            padding: 2px 8px;
            border-radius: var(--radius-sm);
        }

        .contributors {
            font-size: var(--text-xs);
            color: var(--text-secondary);
            display: flex;
            align-items: center;
            gap: var(--space-2);
        }

        .contributor-avatars {
            display: flex;
        }

        .contributor-avatar {
            width: 20px;
            height: 20px;
            border-radius: var(--radius-full);
            background: var(--primary-light);
            border: 2px solid var(--surface);
            margin-left: -6px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 8px;
            font-weight: var(--font-semibold);
            color: var(--primary);
        }

        .contributor-avatar:first-child {
            margin-left: 0;
        }

        /* Voting */
        .vote-section {
            display: flex;
            align-items: center;
            gap: var(--space-4);
        }

        .vote-buttons {
            display: flex;
            align-items: center;
            gap: var(--space-2);
        }

        .vote-btn {
            display: flex;
            align-items: center;
            gap: var(--space-1);
            padding: var(--space-2) var(--space-3);
            border: 1px solid var(--border);
            border-radius: var(--radius-md);
            background: var(--surface);
            font-size: var(--text-sm);
            color: var(--text-secondary);
            cursor: pointer;
            transition: all 0.15s;
        }

        .vote-btn:hover {
            border-color: var(--text-secondary);
        }

        .vote-btn.upvote.active {
            background: rgba(16, 183, 127, 0.1);
            border-color: var(--success);
            color: var(--success);
        }

        .vote-btn.downvote.active {
            background: rgba(234, 88, 12, 0.1);
            border-color: var(--error);
            color: var(--error);
        }

        .vote-btn svg {
            width: 16px;
            height: 16px;
        }

        .synced-badge {
            display: flex;
            align-items: center;
            gap: var(--space-1);
            font-size: var(--text-xs);
            color: var(--success);
            background: rgba(16, 183, 127, 0.1);
            padding: var(--space-1) var(--space-2);
            border-radius: var(--radius-full);
        }

        /* Pagination */
        .pagination {
            display: flex;
            justify-content: center;
            gap: var(--space-2);
            margin-top: var(--space-6);
        }

        .page-btn {
            padding: var(--space-2) var(--space-3);
            border: 1px solid var(--border);
            border-radius: var(--radius-md);
            background: var(--surface);
            font-size: var(--text-sm);
            color: var(--text-secondary);
            cursor: pointer;
            transition: all 0.15s;
        }

        .page-btn:hover:not(:disabled) {
            border-color: var(--primary);
            color: var(--primary);
        }

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

        .page-btn.active {
            background: var(--primary);
            border-color: var(--primary);
            color: white;
        }

        /* Empty State */
        .empty-state {
            text-align: center;
            padding: var(--space-8);
            color: var(--text-secondary);
        }

        .empty-state svg {
            width: 48px;
            height: 48px;
            margin-bottom: var(--space-4);
            opacity: 0.5;
        }

        /* Admin Link Button */
        .admin-link-btn {
            display: flex;
            align-items: center;
            gap: var(--space-2);
            padding: var(--space-2) var(--space-3);
            background: var(--surface);
            border: 1px solid var(--primary);
            border-radius: var(--radius-md);
            color: var(--primary);
            text-decoration: none;
            font-size: var(--text-sm);
            font-weight: var(--font-medium);
            transition: all 0.15s;
        }

        .admin-link-btn:hover {
            background: var(--primary-light);
        }

        .pending-badge {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            min-width: 18px;
            height: 18px;
            padding: 0 5px;
            border-radius: var(--radius-full);
            background: var(--warning);
            color: white;
            font-size: 10px;
            font-weight: var(--font-bold);
        }

        /* Responsive */
        @media (max-width: 768px) {
            .page-header {
                flex-direction: column;
                align-items: flex-start;
                gap: var(--space-3);
            }

            .stats-bar {
                flex-wrap: wrap;
                gap: var(--space-4);
            }

            .toolbar {
                flex-direction: column;
                align-items: stretch;
            }

            .search-box {
                max-width: none;
            }

            .filter-group {
                flex-wrap: wrap;
            }

            .knowledge-header {
                flex-direction: column;
                gap: var(--space-3);
            }

            .knowledge-footer {
                flex-direction: column;
                gap: var(--space-3);
                align-items: flex-start;
            }
        }
    </style>
    {% include '_theme.html' %}
</head>
<body>
    <!-- Header (outside container so it spans full viewport, matching dashboard) -->
    {% include '_app_header.html' %}

    <div class="container-memory">
        {% if pending_review_count and pending_review_count > 0 %}
        <!-- Admin-only review-queue banner (#176). Hidden when 0; non-admins
             never see this because the route zeroes pending_review_count for
             them server-side. -->
        <div class="pending-review-banner" style="display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); margin-bottom: var(--space-4); background: #fef9c3; border: 1px solid #facc15; border-radius: var(--radius-md); color: #854d0e; font-size: var(--text-sm);">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <circle cx="12" cy="12" r="10"/>
                <line x1="12" y1="8" x2="12" y2="12"/>
                <line x1="12" y1="16" x2="12.01" y2="16"/>
            </svg>
            <span>
                <strong>{{ pending_review_count }} pending item{{ 's' if pending_review_count != 1 else '' }}</strong>
                awaiting review —
                <a href="/corporate-memory/admin" style="color: #854d0e; text-decoration: underline; font-weight: var(--font-medium);">review them at /corporate-memory/admin</a>
            </span>
        </div>
        {% endif %}
        <!-- Stats Bar -->
        <div class="stats-bar">
            <div class="stat-item">
                <div class="value">{{ stats.contributors }}</div>
                <div class="label">Contributors</div>
            </div>
            <div class="stat-divider"></div>
            <div class="stat-item">
                <div class="value">{{ stats.knowledge_count }}</div>
                <div class="label">Knowledge Items</div>
            </div>
            <div class="stat-divider"></div>
            <div class="stat-item highlight">
                <div class="value">{{ user_stats.authored }}</div>
                <div class="label">My Contributions</div>
            </div>
            <div class="stats-bar-right">
                {% if user_contributions %}
                <a href="#my-contributions" style="display: inline-flex; align-items: center; gap: 6px; padding: 6px 14px; background: var(--primary, #1a73e8); color: white; border-radius: var(--radius-md); font-size: var(--text-sm); text-decoration: none; font-weight: var(--font-medium);">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                        <path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/>
                        <circle cx="8.5" cy="7" r="4"/>
                        <line x1="20" y1="8" x2="20" y2="14"/>
                        <line x1="23" y1="11" x2="17" y2="11"/>
                    </svg>
                    My Contributions ({{ user_contributions|length }})
                </a>
                {% endif %}
            </div>
        </div>

        <!-- Toolbar -->
        <div class="toolbar">
            <div class="search-box">
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                    <circle cx="11" cy="11" r="8"/>
                    <path d="M21 21l-4.35-4.35"/>
                </svg>
                <input type="text" id="searchInput" placeholder="Search knowledge..." onkeyup="debounceSearch()">
            </div>
            <div class="filter-group">
                <button class="filter-btn active" data-category="" onclick="setFilter(this)">All</button>
                <button class="filter-btn" data-category="my_rules" onclick="setFilter(this)">My Rules</button>
                {% for cat in categories %}
                <button class="filter-btn" data-category="{{ cat }}" onclick="setFilter(this)">{{ cat|replace('_', ' ')|title }}</button>
                {% endfor %}
            </div>
            <select class="sort-select" id="sortSelect" onchange="applyFilters()">
                <option value="score">Most Popular</option>
                <option value="updated_at">Most Recent</option>
                <option value="contributors">Most Contributors</option>
            </select>
            <select class="sort-select" id="domainFilter" onchange="onDomainChange()">
                <option value="">All Domains</option>
                {% for d in domains %}
                <option value="{{ d }}">{{ d|title }}</option>
                {% endfor %}
            </select>
            <!-- Group-by select (issue #62) — switches the flat list to a tree
                 grouped by the chosen axis. ``none`` keeps the existing flat
                 render. -->
            <select class="sort-select" id="groupBySelect" onchange="onGroupByChange()" title="Group items by axis">
                <option value="none">No grouping</option>
                <option value="domain">Group by domain</option>
                <option value="category">Group by category</option>
                <option value="tag">Group by tag</option>
                <option value="audience">Group by audience</option>
            </select>
        </div>

        <!-- Knowledge List -->
        <div id="knowledgeList" class="knowledge-list">
            {% for item in knowledge['items'] %}
            <div class="knowledge-item {% if item.synced %}synced{% endif %}" data-id="{{ item.id }}">
                <div class="knowledge-header">
                    <div>
                        <div class="knowledge-title">{{ item.title }}</div>
                        <div class="knowledge-meta">
                            <span class="category-badge {{ item.category }}">{{ item.category.replace('_', ' ').title() }}</span>
                            {% if item.domain %}<span class="domain-badge">{{ item.domain|title }}</span>{% endif %}
                            {% if item.confidence %}<span class="confidence-badge" title="Confidence: {{ '%.0f'|format(item.confidence * 100) }}%">{{ '%.0f'|format(item.confidence * 100) }}%</span>{% endif %}
                            {% if item.source_type == 'user_verification' %}<span class="source-badge verification">Verified</span>{% endif %}
                            {% if item.status == 'mandatory' %}<span class="source-badge mandatory">Mandatory</span>{% endif %}
                            <span>Added {{ item.created_at.strftime('%Y-%m-%d') if item.created_at else 'recently' }}</span>
                        </div>
                    </div>
                    <div class="vote-section">
                        <div class="vote-buttons">
                            <button class="vote-btn upvote {% if user_votes.get(item.id, 0) == 1 %}active{% endif %}"
                                    onclick="vote('{{ item.id }}', 1)" title="Upvote">
                                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                    <path d="M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3H14z"/>
                                    <path d="M7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3"/>
                                </svg>
                                <span>{{ item.upvotes or 0 }}</span>
                            </button>
                            <button class="vote-btn downvote {% if user_votes.get(item.id, 0) == -1 %}active{% endif %}"
                                    onclick="vote('{{ item.id }}', -1)" title="Downvote">
                                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                    <path d="M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3H10z"/>
                                    <path d="M17 2h3a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2h-3"/>
                                </svg>
                                <span>{{ item.downvotes or 0 }}</span>
                            </button>
                        </div>
                        {% if item.synced %}
                        <span class="synced-badge">
                            <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                <polyline points="20 6 9 17 4 12"/>
                            </svg>
                            In your rules
                        </span>
                        {% endif %}
                    </div>
                </div>
                <div class="knowledge-content">{{ item.content }}</div>
                <div class="knowledge-footer">
                    <div class="knowledge-tags">
                        {% for tag in item.tags %}
                        <span class="tag">{{ tag }}</span>
                        {% endfor %}
                    </div>
                    <div class="contributors">
                        <div class="contributor-avatars">
                            {% for user_info in item.source_users_display[:3] %}
                            <span class="contributor-avatar" title="{{ user_info.name }}">{{ user_info.initials }}</span>
                            {% endfor %}
                            {% if item.source_users_display|length > 3 %}
                            <span class="contributor-avatar">+{{ item.source_users_display|length - 3 }}</span>
                            {% endif %}
                        </div>
                        <span>{{ item.source_users_display|length }} contributor{{ 's' if item.source_users_display|length != 1 else '' }}</span>
                    </div>
                </div>
            </div>
            {% else %}
            <div class="empty-state">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
                    <path d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"/>
                </svg>
                <p>No knowledge items yet.</p>
                <p style="font-size: var(--text-sm);">Knowledge is extracted from team CLAUDE.local.md files every 30 minutes.</p>
            </div>
            {% endfor %}
        </div>

        <!-- Pagination -->
        <div id="pagination" class="pagination">
            {% if knowledge.total_pages > 1 %}
            <button class="page-btn" onclick="goToPage({{ knowledge.page - 1 }})" {% if knowledge.page == 1 %}disabled{% endif %}>Prev</button>
            {% for p in range(1, knowledge.total_pages + 1) %}
            <button class="page-btn {% if p == knowledge.page %}active{% endif %}" onclick="goToPage({{ p }})">{{ p }}</button>
            {% endfor %}
            <button class="page-btn" onclick="goToPage({{ knowledge.page + 1 }})" {% if knowledge.page >= knowledge.total_pages %}disabled{% endif %}>Next</button>
            {% endif %}
        </div>

        <!-- My Contributions Section -->
        {% if user_contributions %}
        <div id="my-contributions" style="margin-top: var(--space-8); scroll-margin-top: 20px;">
            <h2 style="font-size: var(--text-lg); font-weight: var(--font-semibold); margin-bottom: var(--space-4);">My Contributions</h2>
            <p style="font-size: var(--text-sm); color: var(--text-secondary); margin-bottom: var(--space-4);">
                Items you contributed via session corrections or notes. Flag items as personal to exclude from enterprise memory.
            </p>
            <div class="knowledge-list">
                {% for item in user_contributions %}
                <div class="knowledge-item" data-id="{{ item.id }}" style="{% if item.is_personal %}opacity: 0.6; border-left: 3px solid var(--warning);{% endif %}">
                    <div class="knowledge-header">
                        <div>
                            <div class="knowledge-title">{{ item.title }}</div>
                            <div class="knowledge-meta">
                                <span class="category-badge {{ item.category }}">{{ item.category.replace('_', ' ').title() if item.category else 'N/A' }}</span>
                                {% if item.domain %}<span class="domain-badge">{{ item.domain|title }}</span>{% endif %}
                                {% if item.confidence %}<span class="confidence-badge">{{ '%.0f'|format(item.confidence * 100) }}%</span>{% endif %}
                                <span class="status-badge {{ item.status }}">{{ item.status|title }}</span>
                                {% if item.is_personal %}<span class="source-badge" style="background: var(--warning); color: white;">Personal</span>{% endif %}
                            </div>
                        </div>
                        <button class="btn {% if item.is_personal %}btn-approve{% else %}btn-reject{% endif %}"
                                onclick="togglePersonal('{{ item.id }}', {{ 'false' if item.is_personal else 'true' }})"
                                style="padding: 6px 12px; font-size: var(--text-xs); white-space: nowrap;">
                            {{ 'Unmark Personal' if item.is_personal else 'Mark Personal' }}
                        </button>
                    </div>
                    <div class="knowledge-content">{{ item.content }}</div>
                </div>
                {% endfor %}
            </div>
        </div>
        {% endif %}
    </div>

    <script>
    // Store user votes locally for UI updates
    let userVotes = {{ user_votes | tojson }};
    let currentPage = {{ knowledge.page }};
    let currentCategory = '';
    let searchTimeout = null;

    function debounceSearch() {
        clearTimeout(searchTimeout);
        searchTimeout = setTimeout(applyFilters, 300);
    }

    function setFilter(btn) {
        document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
        btn.classList.add('active');
        currentCategory = btn.dataset.category;
        currentPage = 1;
        // Issue #62: domain + category compose, do not reset each other.
        applyFilters();
    }

    function onDomainChange() {
        // Issue #62: domain + category compose. Previously this reset the
        // category to "All" which silently dropped the operator's filter.
        currentPage = 1;
        applyFilters();
    }

    function onGroupByChange() {
        // Issue #62: switch between flat list (current) and grouped tree.
        currentPage = 1;
        applyFilters();
    }

    async function applyFilters() {
        const search = document.getElementById('searchInput').value;
        const sort = document.getElementById('sortSelect').value;
        const domain = document.getElementById('domainFilter').value;
        const groupBy = (document.getElementById('groupBySelect') || {}).value || 'none';
        if (groupBy && groupBy !== 'none') {
            await loadTree(groupBy, currentCategory, search, domain);
        } else {
            await loadKnowledge(currentCategory, search, currentPage, sort, domain);
        }
    }

    async function goToPage(page) {
        currentPage = page;
        await applyFilters();
    }

    async function loadTree(axis, category, search, domain) {
        // Issue #62 — operator's grouped view. Uses /api/memory/tree which
        // applies the same RBAC + privacy filters as /api/memory.
        const params = new URLSearchParams({ axis });
        if (search) params.append('q', search);
        params.append('_t', Date.now());
        try {
            const resp = await fetch(`/api/memory/tree?${params}`);
            const data = await resp.json();
            // Operator-level filters (category + domain) are applied
            // client-side over the tree; the server does not currently take
            // a category param for the tree endpoint to keep the SQL simple.
            renderTree(data, category, domain);
        } catch (e) {
            console.error('Failed to load tree:', e);
        }
    }

    function renderTree(data, categoryFilter, domainFilter) {
        const list = document.getElementById('knowledgeList');
        const pagination = document.getElementById('pagination');
        pagination.innerHTML = '';
        if (!data.groups || data.groups.length === 0) {
            list.innerHTML = `<div class="empty-state"><p>No groups to show.</p></div>`;
            return;
        }
        const stateKey = `cm_tree_open_${data.axis}`;
        let openSet = new Set();
        try { openSet = new Set(JSON.parse(localStorage.getItem(stateKey) || '[]')); } catch {}

        const html = data.groups.map(g => {
            const filtered = (g.items || []).filter(it => {
                if (categoryFilter && categoryFilter !== 'my_rules' && it.category !== categoryFilter) return false;
                if (domainFilter && it.domain !== domainFilter) return false;
                return true;
            });
            if (filtered.length === 0) return '';
            const isOpen = openSet.has(g.key);
            const itemsHtml = filtered.map(item => `
                <div class="knowledge-item" data-id="${escapeHtml(item.id)}" style="margin-bottom: var(--space-3);">
                    <div class="knowledge-header">
                        <div>
                            <div class="knowledge-title">${escapeHtml(item.title || '')}</div>
                            <div class="knowledge-meta">
                                ${item.category ? `<span class="category-badge ${escapeHtml(item.category)}">${escapeHtml((item.category || '').replace('_', ' '))}</span>` : ''}
                                ${item.domain ? `<span class="domain-badge">${escapeHtml(item.domain)}</span>` : ''}
                                ${item.status === 'mandatory' ? '<span class="source-badge mandatory">Mandatory</span>' : ''}
                            </div>
                        </div>
                    </div>
                    <div class="knowledge-content">${escapeHtml(item.content || '')}</div>
                </div>`).join('');
            return `
                <details ${isOpen ? 'open' : ''} data-key="${escapeHtml(g.key)}" onToggle="onTreeToggle(this, '${escapeHtml(stateKey)}')" style="margin-bottom: var(--space-4); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-3);">
                    <summary style="cursor: pointer; font-weight: var(--font-semibold);">
                        ${escapeHtml(g.label)} <span style="color: var(--text-secondary); font-weight: normal;">(${filtered.length})</span>
                    </summary>
                    <div style="margin-top: var(--space-3);">${itemsHtml}</div>
                </details>`;
        }).join('');
        list.innerHTML = html || `<div class="empty-state"><p>No matching items.</p></div>`;
    }

    function onTreeToggle(detailsEl, stateKey) {
        const key = detailsEl.dataset.key;
        let s = new Set();
        try { s = new Set(JSON.parse(localStorage.getItem(stateKey) || '[]')); } catch {}
        if (detailsEl.open) s.add(key); else s.delete(key);
        try { localStorage.setItem(stateKey, JSON.stringify(Array.from(s))); } catch {}
    }

    async function loadKnowledge(category, search, page, sort, domain) {
        const params = new URLSearchParams();
        if (category && category !== 'my_rules') params.append('category', category);
        if (category === 'my_rules') params.append('my_rules', 'true');
        if (search) params.append('search', search);
        if (sort) params.append('sort', sort);
        if (domain) params.append('domain', domain);
        params.append('page', page);

        try {
            params.append('_t', Date.now());
            const resp = await fetch(`/api/memory?${params}`);
            const data = await resp.json();
            renderKnowledge(data);
        } catch (e) {
            console.error('Failed to load knowledge:', e);
        }
    }

    function renderKnowledge(data) {
        const list = document.getElementById('knowledgeList');
        const pagination = document.getElementById('pagination');

        if (data.items.length === 0) {
            list.innerHTML = `
                <div class="empty-state">
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
                        <path d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"/>
                    </svg>
                    <p>No matching knowledge items found.</p>
                </div>`;
            pagination.innerHTML = '';
            return;
        }

        list.innerHTML = data.items.map(item => `
            <div class="knowledge-item ${item.synced ? 'synced' : ''}" data-id="${item.id}">
                <div class="knowledge-header">
                    <div>
                        <div class="knowledge-title">${escapeHtml(item.title)}</div>
                        <div class="knowledge-meta">
                            <span class="category-badge ${item.category}">${escapeHtml((item.category || '').replace('_', ' '))}</span>
                            ${item.domain ? `<span class="domain-badge">${escapeHtml(item.domain)}</span>` : ''}
                            ${item.confidence ? `<span class="confidence-badge">${Math.round(item.confidence * 100)}%</span>` : ''}
                            ${item.source_type === 'user_verification' ? '<span class="source-badge verification">Verified</span>' : ''}
                            ${item.status === 'mandatory' ? '<span class="source-badge mandatory">Mandatory</span>' : ''}
                            <span>Added ${item.created_at ? item.created_at.substring(0, 10) : 'recently'}</span>
                        </div>
                    </div>
                    <div class="vote-section">
                        <div class="vote-buttons">
                            <button class="vote-btn upvote ${userVotes[item.id] === 1 ? 'active' : ''}"
                                    onclick="vote('${item.id}', 1)" title="Upvote">
                                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                    <path d="M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3H14z"/>
                                    <path d="M7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3"/>
                                </svg>
                                <span>${item.upvotes || 0}</span>
                            </button>
                            <button class="vote-btn downvote ${userVotes[item.id] === -1 ? 'active' : ''}"
                                    onclick="vote('${item.id}', -1)" title="Downvote">
                                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                    <path d="M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3H10z"/>
                                    <path d="M17 2h3a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2h-3"/>
                                </svg>
                                <span>${item.downvotes || 0}</span>
                            </button>
                        </div>
                        ${item.synced ? `
                        <span class="synced-badge">
                            <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                <polyline points="20 6 9 17 4 12"/>
                            </svg>
                            In your rules
                        </span>` : ''}
                    </div>
                </div>
                <div class="knowledge-content">${escapeHtml(item.content)}</div>
                <div class="knowledge-footer">
                    <div class="knowledge-tags">
                        ${(typeof item.tags === 'string' ? JSON.parse(item.tags || '[]') : (item.tags || [])).map(tag => `<span class="tag">${escapeHtml(tag)}</span>`).join('')}
                    </div>
                    <div class="contributors">
                        <div class="contributor-avatars">
                            ${(item.source_users_display || []).slice(0, 3).map(u =>
                                `<span class="contributor-avatar" title="${escapeHtml(u.name)}">${escapeHtml(u.initials)}</span>`
                            ).join('')}
                            ${(item.source_users_display || []).length > 3 ?
                                `<span class="contributor-avatar">+${item.source_users_display.length - 3}</span>` : ''}
                        </div>
                        <span>${(item.source_users_display || []).length} contributor${item.source_users_display?.length !== 1 ? 's' : ''}</span>
                    </div>
                </div>
            </div>
        `).join('');

        // Render pagination
        if (data.total_pages > 1) {
            let paginationHtml = `
                <button class="page-btn" onclick="goToPage(${data.page - 1})" ${data.page === 1 ? 'disabled' : ''}>Prev</button>
            `;
            for (let p = 1; p <= data.total_pages; p++) {
                paginationHtml += `<button class="page-btn ${p === data.page ? 'active' : ''}" onclick="goToPage(${p})">${p}</button>`;
            }
            paginationHtml += `
                <button class="page-btn" onclick="goToPage(${data.page + 1})" ${data.page >= data.total_pages ? 'disabled' : ''}>Next</button>
            `;
            pagination.innerHTML = paginationHtml;
        } else {
            pagination.innerHTML = '';
        }
    }

    async function vote(itemId, voteValue) {
        // Toggle vote if clicking same button
        const currentVote = userVotes[itemId] || 0;
        const newVote = currentVote === voteValue ? 0 : voteValue;

        try {
            const resp = await fetch(`/api/memory/${itemId}/vote`, {
                method: 'POST',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify({vote: newVote})
            });

            if (resp.ok) {
                userVotes[itemId] = newVote;
                // Reload to get updated scores
                applyFilters();
            } else {
                const err = await resp.json().catch(() => ({}));
                console.error('Vote failed:', resp.status, err);
            }
        } catch (e) {
            console.error('Failed to vote:', e);
        }
    }

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

    async function togglePersonal(itemId, isPersonal) {
        try {
            const resp = await fetch(`/api/memory/${itemId}/personal`, {
                method: 'POST',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify({is_personal: isPersonal})
            });
            if (resp.ok) {
                location.reload();
            }
        } catch(e) {
            console.error('Failed to toggle personal flag:', e);
        }
    }
    </script>
    {% include "_version_badge.html" %}
</body>
</html>
