<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ catalog_uri }} - Faceberg Catalog</title>
    <meta name="description" content="Interactive Apache Iceberg catalog browser with DuckDB-WASM query capabilities">
    <script src="https://cdn.tailwindcss.com"></script>

    <!-- XTerm.js CSS for DuckDB shell -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@5.3.0/css/xterm.css" />

    <!-- Google Fonts: DM Sans -->
    <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=DM+Sans:ital,opsz,wght@0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700;1,9..40,400&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">

    <style>
        :root {
            --primary-blue: #1E88E5;
            --primary-blue-dark: #1565C0;
            --primary-blue-darker: #0D47A1;
            --primary-blue-light: #64B5F6;
            --accent-yellow: #FFC107;
            --accent-yellow-dark: #FFA000;
            --light-blue-bg: #E3F2FD;
            --light-blue: #90CAF9;
            --gray-50: #FAFAFA;
            --gray-100: #F3F4F6;
            --gray-200: #E5E7EB;
            --gray-300: #D1D5DB;
            --gray-600: #4B5563;
            --gray-700: #374151;
            --gray-800: #1F2937;
            --gray-900: #111827;
            --terminal-bg: #0F1419;
        }

        * {
            box-sizing: border-box;
        }

        body {
            margin: 0;
            overflow: hidden;
            height: 100vh;
            display: flex;
            flex-direction: column;
            font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
            background: var(--gray-50);
            color: var(--gray-900);
        }

        /* Header */
        .app-header {
            background: var(--primary-blue);
            flex-shrink: 0;
            border-bottom: 2px solid var(--accent-yellow);
        }

        .header-content {
            padding: 0.5rem 0.75rem;
            display: flex;
            align-items: center;
            justify-content: space-between;
        }

        .header-title {
            font-size: 1rem;
            font-weight: 700;
            color: white;
            margin: 0;
            display: flex;
            align-items: center;
            gap: 0.5rem;
        }

        .logo-icon {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            width: 28px;
            height: 28px;
            background: white;
            border-radius: 50%;
            overflow: hidden;
            padding: 2px;
            flex-shrink: 0;
        }

        .logo-icon img {
            width: 100%;
            height: 100%;
            object-fit: contain;
        }

        .header-meta {
            display: flex;
            gap: 0.75rem;
            align-items: center;
            font-size: 0.75rem;
            color: rgba(255, 255, 255, 0.9);
        }

        .header-catalog-badge {
            background: rgba(255, 193, 7, 0.2);
            color: var(--accent-yellow);
            padding: 0.125rem 0.375rem;
            border-radius: 3px;
            font-family: 'JetBrains Mono', monospace;
            font-size: 0.625rem;
            border: 1px solid rgba(255, 193, 7, 0.4);
        }

        /* Main layout container */
        .main-container {
            display: flex;
            height: calc(100vh - 48px);
            overflow: hidden;
            gap: 0;
        }

        /* Left sidebar - 1/3 width */
        .left-sidebar {
            width: 35%;
            display: flex;
            flex-direction: column;
            background: white;
            border-right: 1px solid var(--gray-200);
            overflow-y: auto;
        }

        /* Right sidebar - 2/3 width */
        .right-sidebar {
            width: 65%;
            display: flex;
            flex-direction: column;
            background: var(--light-blue-bg);
        }

        /* Catalog hierarchy section */
        .catalog-hierarchy {
            padding: 0.75rem;
        }

        .section-title {
            font-size: 0.6875rem;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 0.05em;
            color: var(--primary-blue-dark);
            margin-bottom: 0.5rem;
            padding: 0.25rem 0.5rem;
            background: var(--light-blue-bg);
            border-radius: 4px;
        }

        /* Shell container */
        #shell-container {
            flex: 1;
            background-color: var(--terminal-bg);
            overflow: hidden;
            border-radius: 6px;
            margin: 0.5rem;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        }

        /* XTerm.js overrides */
        .xterm {
            height: 100%;
            padding: 10px;
        }

        .xterm .xterm-viewport {
            overflow-y: auto;
        }

        /* Table list item */
        details.table-item {
            margin-bottom: 0.25rem;
        }

        details.table-item > summary {
            cursor: pointer;
            transition: all 0.15s ease;
            list-style: none;
            padding: 0.375rem 0.5rem;
            border-radius: 4px;
            font-weight: 500;
            font-size: 0.75rem;
            color: var(--gray-800);
            background: white;
            border: 1px solid var(--gray-200);
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        details.table-item > summary::-webkit-details-marker {
            display: none;
        }

        details.table-item > summary:hover {
            background-color: #FFF9E6;
            border-color: var(--accent-yellow);
        }

        details.table-item > summary::before {
            content: '▶';
            display: inline-block;
            transition: transform 0.15s ease;
            margin-right: 0.375rem;
            color: var(--accent-yellow-dark);
            font-size: 0.5rem;
        }

        details.table-item[open] > summary::before {
            transform: rotate(90deg);
        }

        details.table-item[open] > summary {
            background: var(--primary-blue);
            color: white;
            border-color: var(--primary-blue-dark);
            margin-bottom: 0.375rem;
        }

        .table-name {
            font-weight: 600;
            font-family: 'JetBrains Mono', monospace;
        }

        .table-row-count {
            font-size: 0.625rem;
            opacity: 0.7;
        }

        details.table-item[open] > summary .table-row-count {
            opacity: 0.9;
        }

        /* Table content area */
        .table-content {
            padding: 0.5rem;
            background: var(--light-blue-bg);
            border-radius: 4px;
            border: 1px solid var(--light-blue);
            margin-bottom: 0.25rem;
        }


        /* Schema table */
        .schema-table {
            font-size: 0.6875rem;
            border-collapse: separate;
            border-spacing: 0;
            width: 100%;
            border-radius: 4px;
            overflow: hidden;
            border: 1px solid var(--gray-200);
            margin-bottom: 0.5rem;
        }

        .schema-table th,
        .schema-table td {
            padding: 0.25rem 0.375rem;
            text-align: left;
        }

        .schema-table th {
            background: var(--primary-blue-darker);
            color: white;
            font-weight: 600;
            text-transform: uppercase;
            font-size: 0.5625rem;
            letter-spacing: 0.05em;
        }

        .schema-table th:first-child {
            border-top-left-radius: 4px;
        }

        .schema-table th:last-child {
            border-top-right-radius: 4px;
        }

        .schema-table td {
            background: white;
            border-bottom: 1px solid var(--gray-200);
        }

        .schema-table tbody tr:last-child td {
            border-bottom: none;
        }

        .schema-table tbody tr:hover td {
            background: var(--light-blue-bg);
        }

        .column-name {
            font-family: 'JetBrains Mono', monospace;
            font-size: 0.625rem;
            color: var(--gray-900);
            font-weight: 500;
        }

        .column-type {
            color: var(--gray-600);
            font-size: 0.625rem;
        }

        /* Quick tips section */
        .quick-tips {
            background: linear-gradient(135deg, #FFF9E6 0%, #FFECB3 100%);
            border: 1px solid var(--accent-yellow);
            border-radius: 4px;
            padding: 0.5rem;
            margin: 0.5rem;
            flex-shrink: 0;
            font-size: 0.6875rem;
            color: var(--gray-700);
            line-height: 1.3;
        }

        .tips-extensions {
            display: inline-flex;
            gap: 0.25rem;
        }

        .extension-badge {
            background: white;
            padding: 0.0625rem 0.25rem;
            border-radius: 2px;
            font-family: 'JetBrains Mono', monospace;
            font-size: 0.625rem;
            color: var(--primary-blue-dark);
            border: 1px solid var(--primary-blue-light);
        }

        .example-query-code {
            display: inline;
            background: var(--gray-900);
            color: #A3E635;
            padding: 0.125rem 0.25rem;
            border-radius: 2px;
            font-family: 'JetBrains Mono', monospace;
            font-size: 0.625rem;
            border: 1px solid var(--gray-700);
        }

        /* Metadata grid */
        .metadata-grid {
            display: flex;
            gap: 0.5rem;
            flex-wrap: wrap;
            margin-bottom: 0.5rem;
            padding: 0.375rem;
            background: white;
            border-radius: 4px;
            border: 1px solid var(--gray-200);
            font-size: 0.625rem;
        }

        .metadata-item {
            display: flex;
            align-items: baseline;
            gap: 0.25rem;
        }

        .metadata-label {
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 0.025em;
            color: var(--primary-blue-dark);
        }

        .metadata-value {
            font-weight: 600;
            color: var(--gray-900);
        }

        .dataset-link {
            color: var(--primary-blue);
            text-decoration: none;
            font-weight: 500;
            transition: color 0.2s ease;
        }

        .dataset-link:hover {
            color: var(--primary-blue-dark);
            text-decoration: underline;
        }

        /* Action button */
        .action-button {
            width: 100%;
            background: linear-gradient(135deg, var(--accent-yellow) 0%, var(--accent-yellow-dark) 100%);
            color: var(--gray-900);
            font-weight: 600;
            padding: 0.375rem 0.5rem;
            border-radius: 4px;
            border: none;
            cursor: pointer;
            transition: all 0.15s ease;
            font-size: 0.6875rem;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 0.25rem;
            box-shadow: 0 1px 3px rgba(255, 193, 7, 0.3);
        }

        .action-button:hover {
            transform: translateY(-1px);
            box-shadow: 0 2px 4px rgba(255, 193, 7, 0.4);
        }

        .action-button:active {
            transform: translateY(0);
        }

        /* Empty state */
        .empty-state {
            text-align: center;
            padding: 1.5rem 1rem;
            color: var(--gray-600);
        }

        .empty-state-icon {
            font-size: 1.5rem;
            margin-bottom: 0.5rem;
            opacity: 0.5;
        }

        .empty-state-title {
            font-size: 0.8125rem;
            font-weight: 600;
            margin-bottom: 0.25rem;
            color: var(--primary-blue-dark);
        }

        .empty-state-text {
            font-size: 0.6875rem;
            margin-top: 0.25rem;
        }

        .empty-state-code {
            background: var(--light-blue-bg);
            padding: 0.0625rem 0.25rem;
            border-radius: 2px;
            font-family: 'JetBrains Mono', monospace;
            font-size: 0.625rem;
        }

        /* Loading spinner */
        .spinner {
            border: 3px solid var(--gray-200);
            border-top: 3px solid var(--primary-blue);
            border-radius: 50%;
            width: 24px;
            height: 24px;
            animation: spin 0.8s linear infinite;
            display: inline-block;
        }

        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }

        /* Scrollbar styling */
        ::-webkit-scrollbar {
            width: 10px;
            height: 10px;
        }

        ::-webkit-scrollbar-track {
            background: var(--gray-100);
        }

        ::-webkit-scrollbar-thumb {
            background: var(--primary-blue-light);
            border-radius: 5px;
            border: 2px solid var(--gray-100);
        }

        ::-webkit-scrollbar-thumb:hover {
            background: var(--primary-blue);
        }

        /* Subsection title within table details */
        .subsection-title {
            font-size: 0.625rem;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 0.05em;
            color: var(--primary-blue-dark);
            margin-bottom: 0.375rem;
            padding: 0.125rem 0.25rem;
            background: white;
            border-radius: 3px;
            display: inline-block;
        }

        /* Responsive adjustments */
        @media (max-width: 1024px) {
            .left-sidebar {
                width: 40%;
            }
            .right-sidebar {
                width: 60%;
            }
        }
    </style>
</head>
<body>
    <!-- Header -->
    <header class="app-header">
        <div class="header-content">
            <h1 class="header-title">
                <span class="logo-icon">
                    <img src="https://raw.githubusercontent.com/kszucs/faceberg/main/faceberg.png" alt="Faceberg Logo">
                </span>
                <span>Faceberg</span>
            </h1>
            <div class="header-meta">
                <code class="header-catalog-badge">{{ catalog_uri }}</code>
                <span>{{ total_tables }} tables</span>
            </div>
        </div>
    </header>

    <!-- Main Container -->
    <div class="main-container">
        <!-- Left Sidebar: Table List -->
        <div class="left-sidebar">
            <div class="catalog-hierarchy">
                <h2 class="section-title">Tables ({{ total_tables }})</h2>

                {% if namespaces|length == 0 %}
                <div class="empty-state">
                    <div class="empty-state-icon">📂</div>
                    <div class="empty-state-title">No tables found</div>
                    <p class="empty-state-text">Add datasets using <code class="empty-state-code">faceberg add</code></p>
                </div>
                {% else %}
                <div>
                    {% for namespace in namespaces %}
                        {% for table in namespace.tables %}
                        <details class="table-item" data-table-id="{{ namespace.name }}.{{ table.name }}">
                            <summary>
                                <span class="table-name">{{ namespace.name }}.{{ table.name }}</span>
                                <span class="table-row-count">{{ table.row_count }} rows</span>
                            </summary>
                            <div class="table-content">
                                <!-- Metadata -->
                                <div class="metadata-grid">
                                    <div class="metadata-item">
                                        <span class="metadata-label">Rows:</span>
                                        <span class="metadata-value">{{ table.row_count }}</span>
                                    </div>
                                    <div class="metadata-item">
                                        <span class="metadata-label">Files:</span>
                                        <span class="metadata-value">{{ table.file_count }}</span>
                                    </div>
                                    <div class="metadata-item">
                                        <span class="metadata-label">Cols:</span>
                                        <span class="metadata-value">{{ table.columns|length }}</span>
                                    </div>
                                    {% if table.dataset_repo %}
                                    <div class="metadata-item">
                                        <a href="https://huggingface.co/datasets/{{ table.dataset_repo }}"
                                           target="_blank"
                                           class="dataset-link">
                                            {{ table.dataset_repo }} →
                                        </a>
                                    </div>
                                    {% endif %}
                                </div>

                                <!-- Schema -->
                                <div class="subsection-title">Schema</div>
                                <div style="overflow-x: auto;">
                                    <table class="schema-table">
                                        <thead>
                                            <tr>
                                                <th>Column</th>
                                                <th>Type</th>
                                                <th>Req</th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                            {% for col in table.columns %}
                                            <tr>
                                                <td class="column-name">{{ col.name }}</td>
                                                <td class="column-type">{{ col.type }}</td>
                                                <td style="text-align: center;">
                                                    {% if col.required %}
                                                    <span style="color: #10B981; font-weight: 600;">✓</span>
                                                    {% else %}
                                                    <span style="color: var(--gray-400);">-</span>
                                                    {% endif %}
                                                </td>
                                            </tr>
                                            {% endfor %}
                                        </tbody>
                                    </table>
                                </div>

                                <!-- Query Button -->
                                <button onclick="insertQuery('{{ namespace.name }}.{{ table.name }}')" class="action-button">
                                    <span>🔍</span>
                                    <span>Query</span>
                                </button>
                            </div>
                        </details>
                        {% endfor %}
                    {% endfor %}
                </div>
                {% endif %}
            </div>
        </div>

        <!-- Right Sidebar: DuckDB Shell -->
        <div class="right-sidebar">
            <!-- Quick Tips -->
            <div class="quick-tips">
                <strong>💡 DuckDB Shell</strong> • Extensions:
                <span class="tips-extensions">
                    <span class="extension-badge">iceberg</span>
                    <span class="extension-badge">httpfs</span>
                </span>
                {% if namespaces|length > 0 %}
                • Example: <code class="example-query-code">{% set first_ns = namespaces[0] %}{% set first_table = first_ns.tables[0] %}SELECT * FROM catalog.{{ first_ns.name }}.{{ first_table.name }} LIMIT 10;</code>
                {% endif %}
            </div>

            <!-- Shell Container -->
            <div id="shell-container"></div>
        </div>
    </div>

    <!-- JavaScript -->
    <script type="module">
        // Global state
        let shellInitialized = false;

        // Insert query into shell
        window.insertQuery = function(tableName) {
            const query = `SELECT * FROM catalog.${tableName} LIMIT 10;`;
            navigator.clipboard.writeText(query).then(() => {
                alert('Query copied to clipboard! Paste it into the shell with Cmd/Ctrl+V');
            }).catch(err => {
                console.error('Failed to copy query:', err);
            });
        };

        // Initialize DuckDB Shell
        async function initializeShell() {
            if (shellInitialized) return;

            try {
                // Load DuckDB modules using jsdelivr +esm (handles dependencies automatically)
                const duckdb = await import('https://cdn.jsdelivr.net/npm/@duckdb/duckdb-wasm@1.31.1-dev35.0/+esm');

                // Get shell container
                const container = document.getElementById('shell-container');

                // Initialize DuckDB
                const JSDELIVR_BUNDLES = duckdb.getJsDelivrBundles();
                const bundle = await duckdb.selectBundle(JSDELIVR_BUNDLES);

                const worker_url = URL.createObjectURL(
                    new Blob([`importScripts("${bundle.mainWorker}");`], {type: 'text/javascript'})
                );
                const worker = new Worker(worker_url);
                const logger = new duckdb.ConsoleLogger();

                const db = new duckdb.AsyncDuckDB(logger, worker);
                await db.instantiate(bundle.mainModule);
                URL.revokeObjectURL(worker_url);

                // Install extensions and attach catalog
                const conn = await db.connect();
                await conn.query(`INSTALL httpfs; LOAD httpfs;`);
                await conn.query(`INSTALL iceberg; LOAD iceberg;`);

                // Attach the REST catalog
                const catalogEndpoint = window.location.origin;
                await conn.query(`
                    ATTACH 'warehouse' AS catalog (
                        TYPE ICEBERG,
                        ENDPOINT '${catalogEndpoint}',
                        AUTHORIZATION_TYPE 'none'
                    );
                `);
                await conn.close();

                // Load XTerm.js for terminal UI
                const xtermModule = await import('https://cdn.jsdelivr.net/npm/xterm@5.3.0/+esm');
                const Terminal = xtermModule.Terminal;
                const fitModule = await import('https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.8.0/+esm');
                const FitAddon = fitModule.FitAddon;

                // Create terminal
                const terminal = new Terminal({
                    cursorBlink: true,
                    fontSize: 14,
                    fontFamily: 'JetBrains Mono, monospace',
                    theme: {
                        background: '#0F1419',
                        foreground: '#E6E1CF',
                    }
                });

                const fitAddon = new FitAddon();
                terminal.loadAddon(fitAddon);
                terminal.open(container);
                fitAddon.fit();

                // Simple command prompt
                let currentLine = '';
                let historyIndex = -1;
                const history = [];

                const prompt = () => terminal.write('\r\n\x1b[32mD\x1b[0m ');

                terminal.writeln('DuckDB v1.31.1 Shell (WASM)');
                terminal.writeln('Connected to in-memory database');
                terminal.writeln('Extensions loaded: iceberg, httpfs');
                terminal.writeln('Catalog attached: Use catalog.namespace.table to query');
                terminal.writeln('');
                prompt();

                terminal.onData(async (data) => {
                    const code = data.charCodeAt(0);

                    // Handle Enter
                    if (code === 13) {
                        const query = currentLine.trim();
                        if (query) {
                            history.unshift(query);
                            terminal.write('\r\n');

                            try {
                                const conn = await db.connect();
                                const result = await conn.query(query);
                                terminal.writeln(result.toString());
                                await conn.close();
                            } catch (err) {
                                terminal.writeln(`\x1b[31mError: ${err.message}\x1b[0m`);
                            }
                        }
                        currentLine = '';
                        historyIndex = -1;
                        prompt();
                    }
                    // Handle Backspace
                    else if (code === 127) {
                        if (currentLine.length > 0) {
                            currentLine = currentLine.slice(0, -1);
                            terminal.write('\b \b');
                        }
                    }
                    // Handle Ctrl+C
                    else if (code === 3) {
                        terminal.write('^C');
                        currentLine = '';
                        prompt();
                    }
                    // Handle printable characters
                    else if (code >= 32 && code <= 126) {
                        currentLine += data;
                        terminal.write(data);
                    }
                });

                // Handle window resize
                window.addEventListener('resize', () => fitAddon.fit());

                shellInitialized = true;
            } catch (error) {
                console.error('Shell initialization error:', error);
                document.getElementById('shell-container').innerHTML = `
                    <div class="p-4 bg-red-50 border border-red-200 rounded text-red-700">
                        <strong>Error initializing shell:</strong> ${error.message}
                        <p class="text-sm mt-2">Please refresh the page and try again.</p>
                    </div>
                `;
            }
        }

        // Auto-initialize shell on page load
        window.addEventListener('DOMContentLoaded', async () => {
            await initializeShell();
        });
    </script>
</body>
</html>
