<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Terminal - %s</title>
    <link rel="icon" href="/favicon.ico" type="image/x-icon">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://unpkg.com/xterm@5.3.0/css/xterm.css">
    <script src="/xterm.js"></script>
    <script src="/xterm-addon-fit.js"></script>
    <script>
        // Ensure libraries are loaded
        function checkLibraries() {
            if (typeof Terminal === 'undefined') {
                console.error('Terminal not loaded from CDN');
                return false;
            }
            if (typeof FitAddon === 'undefined') {
                console.error('FitAddon not loaded from CDN');
                return false;
            }
            console.log('All xterm libraries loaded successfully');
            return true;
        }

        // Check immediately and after a delay
        if (!checkLibraries()) {
            setTimeout(checkLibraries, 1000);
        }
    </script>
    <style>
        .navbar-brand {
            font-weight: bold;
        }
        .client-card {
            transition: transform 0.2s;
        }
        .client-card:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 8px rgba(0,0,0,0.1);
        }
        .terminal-container {
            background-color: #1e1e1e;
            color: #f8f8f2;
            font-family: 'Courier New', monospace;
            border-radius: 8px;
            height: calc(100vh - 200px);
            min-height: 400px;
            overflow: hidden;
            position: relative;
        }
        .terminal-input {
            background: transparent;
            border: none;
            color: #f8f8f2;
            font-family: 'Courier New', monospace;
            width: 100%;
            outline: none;
        }
        .terminal-input:focus {
            box-shadow: none;
        }
        /* GNOME-like window decorations */
        .terminal-window {
            border: 1px solid #ccc;
            border-radius: 8px;
            overflow: hidden;
            box-shadow: 0 2px 10px rgba(0,0,0,0.2);
        }
        .window-titlebar {
            background: linear-gradient(to bottom, #f0f0f0, #e0e0e0);
            border-bottom: 1px solid #ccc;
            padding: 4px 8px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            height: 32px;
        }
        .window-title {
            font-weight: bold;
            color: #333;
            font-size: 14px;
        }
        .window-controls {
            display: flex;
            align-items: center;
            gap: 4px;
        }
        .window-btn {
            width: 24px;
            height: 24px;
            border: none;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 14px;
            font-weight: bold;
            cursor: pointer;
            transition: all 0.2s;
        }
        .window-btn:hover {
            transform: scale(1.1);
        }
        .close-btn {
            background: #ff605c;
            color: white;
        }
        .close-btn:hover {
            background: #ff403c;
        }
        .maximize-btn {
            background: #28ca42;
            color: white;
        }
        .maximize-btn:hover {
            background: #24b83a;
        }
        .minimize-btn {
            background: #ffbd44;
            color: white;
            display: none; /* Hidden by default, shown in fullscreen */
        }
        .minimize-btn:hover {
            background: #ffad2c;
        }
        .window-content {
            background: #1e1e1e;
            padding: 8px;
        }
        /* Fullscreen styles */
        .terminal-window.fullscreen {
            position: fixed;
            top: 0;
            left: 0;
            width: 100vw;
            height: 100vh;
            border: none;
            border-radius: 0;
            z-index: 9999;
        }
        .terminal-window.fullscreen .terminal-container {
            height: calc(100vh - 40px) !important;
            min-height: calc(100vh - 40px) !important;
        }
        .terminal-window.fullscreen .minimize-btn {
            display: flex;
        }
    </style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="container">
<a class="navbar-brand" href="/">
<i class="fas fa-terminal"></i> WSSSHD control panel</a>
<div class="navbar-nav ms-auto">
<span class="navbar-text me-3">SSH Terminal - %s</span>
<a class="nav-link" href="/logout">Logout</a>
</div></div></nav>
<div id="notification-area" class="position-fixed top-0 end-0 p-3" style="z-index: 1050;"></div>
<div class="container mt-4">
<div class="row">
    <div class="col-12">
        <div class="terminal-window">
            <div class="window-titlebar">
                <div class="window-title">
                    <i class="fas fa-terminal"></i> SSH Terminal - %s
                </div>
                <div class="window-controls">
                    <input type="text" id="sshUsername" class="form-control form-control-sm d-inline-block w-auto me-2" placeholder="Username" value="root" style="height: 24px; font-size: 12px; border: none; background: rgba(255,255,255,0.1); color: white;">
                    <button id="connectBtn" class="btn btn-success btn-sm me-1" style="height: 24px; font-size: 12px; padding: 0 8px;">
                        <i class="fas fa-play"></i> Connect
                    </button>
                    <button id="disconnectBtn" class="btn btn-danger btn-sm me-1" disabled style="height: 24px; font-size: 12px; padding: 0 8px;">
                        <i class="fas fa-stop"></i> Disconnect
                    </button>
                    <button class="window-btn minimize-btn" title="Exit Fullscreen">_</button>
                    <button class="window-btn maximize-btn" title="Fullscreen"><span class="maximize-icon">□</span></button>
                    <button class="window-btn close-btn" title="Disconnect">×</button>
                </div>
            </div>
            <div class="window-content">
                <div id="terminal" class="terminal-container w-100"></div>
            </div>
        </div>
    </div>
</div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
console.log('Terminal script starting...');
console.log('xterm available:', typeof Terminal);
console.log('xterm-fit available:', typeof FitAddon);

let term = null;
let fitAddon = null;
let connected = false;
let requestId = null;
let websocket = null;

console.log('Terminal page loaded, adding event listeners');
document.getElementById('connectBtn').addEventListener('click', connect);
document.getElementById('disconnectBtn').addEventListener('click', disconnect);

// Window control buttons
document.querySelector('.close-btn').addEventListener('click', disconnect);
document.querySelector('.maximize-btn').addEventListener('click', toggleFullscreen);
document.querySelector('.minimize-btn').addEventListener('click', toggleFullscreen);
console.log('Event listeners added');

// Fullscreen functionality
function toggleFullscreen() {
    const terminalWindow = document.querySelector('.terminal-window');
    const maximizeBtn = document.querySelector('.maximize-btn');
    const maximizeIcon = maximizeBtn.querySelector('.maximize-icon');

    if (terminalWindow.classList.contains('fullscreen')) {
        // Exit fullscreen
        terminalWindow.classList.remove('fullscreen');
        maximizeIcon.textContent = '□';
        maximizeBtn.title = 'Fullscreen';
    } else {
        // Enter fullscreen
        terminalWindow.classList.add('fullscreen');
        maximizeIcon.textContent = '▭'; // Restore icon
        maximizeBtn.title = 'Exit Fullscreen';
    }

    // Resize terminal after fullscreen change
    setTimeout(() => {
        if (window.fitTerminal) {
            window.fitTerminal();
        }
        // Update backend terminal size if connected
        if (connected && requestId && fitAddon) {
            const newDimensions = fitAddon.proposeDimensions();
            const newCols = newDimensions.cols || 80;
            const newRows = newDimensions.rows || 24;

            fetch('/terminal/%s/xterm/resize', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: 'request_id=' + encodeURIComponent(requestId) +
                      '&cols=' + encodeURIComponent(newCols) +
                      '&rows=' + encodeURIComponent(newRows)
            }).catch(error => {
                console.error('Resize error during fullscreen toggle:', error);
            });
        }
    }, 100);
}


function connect() {
    console.log('Connect button clicked');
    console.log('Connect function called');
    if (typeof Terminal === 'undefined') {
        alert('xterm.js library failed to load. Please check your internet connection or refresh the page.');
        return;
    }
    const username = document.getElementById('sshUsername').value;
    console.log('Username value:', username);
    if (!username) {
        alert('Please enter a username');
        return;
    }
    console.log('Username validation passed');

    // Initialize xterm with proper configuration
    if (!term) {
        term = new Terminal({
            cursorBlink: true,
            cursorStyle: 'block',
            fontSize: 14,
            fontFamily: 'Monaco, Menlo, "Ubuntu Mono", monospace',
            theme: {
                background: '#1e1e1e',
                foreground: '#f8f8f2',
                cursor: '#f8f8f2',
                cursorAccent: '#1e1e1e',
                selection: 'rgba(248, 248, 242, 0.3)'
            },
            allowTransparency: true,
            scrollback: 1000,
            tabStopWidth: 4,
            convertEol: true,
            disableStdin: false,
            cursorWidth: 2,
            bellStyle: 'none',
            rightClickSelectsWord: true,
            fastScrollModifier: 'alt',
            fastScrollSensitivity: 5,
            screenReaderMode: false,
            macOptionIsMeta: false,
            macOptionClickForcesSelection: false,
            minimumContrastRatio: 1
        });
        term.open(document.getElementById('terminal'));

        // Load fit addon
        try {
            if (typeof FitAddon !== 'undefined') {
                fitAddon = new FitAddon.FitAddon();
                term.loadAddon(fitAddon);
                console.log('FitAddon loaded successfully');
            } else {
                console.error('FitAddon is not available');
                throw new Error('FitAddon not loaded');
            }
        } catch (e) {
            console.error('Failed to load FitAddon:', e);
            term.write('Warning: Terminal auto-resizing not available\r\n');
            // Continue without fit addon - terminal will still work
        }

        // Initial fit after a short delay to ensure DOM is ready
        setTimeout(() => {
            window.fitTerminal();
            // Calculate dimensions after initial fit
            let initialDimensions = { cols: 80, rows: 24 };
            if (fitAddon) {
                initialDimensions = fitAddon.proposeDimensions();
            }
            term._initialCols = initialDimensions.cols || 80;
            term._initialRows = initialDimensions.rows || 24;
        }, 100);

        // Fit on window resize and update backend terminal size
        window.addEventListener('resize', () => {
            window.fitTerminal();
            // Update terminal size on backend if connected
            if (connected && requestId && fitAddon) {
                const newDimensions = fitAddon.proposeDimensions();
                const newCols = newDimensions.cols || 80;
                const newRows = newDimensions.rows || 24;

                fetch('/terminal/%s/xterm/resize', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                    },
                    body: 'request_id=' + encodeURIComponent(requestId) +
                          '&cols=' + encodeURIComponent(newCols) +
                          '&rows=' + encodeURIComponent(newRows)
                }).catch(error => {
                    console.error('Resize error:', error);
                });
            }
        });

        term.focus();
    }

    // Define fitTerminal function globally for fullscreen handling
    window.fitTerminal = function() {
        if (fitAddon) {
            fitAddon.fit();
        }
    };

    term.write('Connecting to ' + username + '@%s...\r\n');

    connected = true;
    document.getElementById('connectBtn').disabled = true;
    document.getElementById('disconnectBtn').disabled = false;
    document.getElementById('sshUsername').disabled = true;

    // Use calculated dimensions (either from initial fit or current)
    let cols = term._initialCols || 80;
    let rows = term._initialRows || 24;
    if (fitAddon) {
        const dimensions = fitAddon.proposeDimensions();
        cols = dimensions.cols || cols;
        rows = dimensions.rows || rows;
    }

    // Establish WebSocket connection first
    const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
    const wsUrl = wsProtocol + '//' + window.location.host + '/terminal/%s/ws';
    console.log('Connecting WebSocket to:', wsUrl);

    websocket = new WebSocket(wsUrl);
    websocket.binaryType = 'arraybuffer';

    websocket.onopen = function(event) {
        console.log('WebSocket connected');
        term.write('WebSocket connected, establishing terminal...\r\n');

        // Now send connect request with terminal dimensions
        const connectUrl = '/terminal/%s/xterm/connect';
        console.log('Sending connect request to:', connectUrl);

        fetch(connectUrl, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            body: 'username=' + encodeURIComponent(username) +
                  '&cols=' + encodeURIComponent(cols) +
                  '&rows=' + encodeURIComponent(rows),
            credentials: 'same-origin'
        })
        .then(response => {
            console.log('Connect response status:', response.status);
            if (!response.ok) {
                throw new Error(`HTTP ${response.status}: ${response.statusText}`);
            }
            return response.json();
        })
        .then(data => {
            console.log('Connect response data:', data);
            if (data.request_id) {
                requestId = data.request_id;
                if (data.command) {
                    console.log('Launching command:', data.command);
                }
                term.write('Terminal connected successfully!\r\n');

                // Send resize with current dimensions to ensure correct sizing
                if (fitAddon) {
                    const dimensions = fitAddon.proposeDimensions();
                    const newCols = dimensions.cols || 80;
                    const newRows = dimensions.rows || 24;
                    fetch('/terminal/%s/xterm/resize', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/x-www-form-urlencoded',
                        },
                        body: 'request_id=' + encodeURIComponent(requestId) +
                              '&cols=' + encodeURIComponent(newCols) +
                              '&rows=' + encodeURIComponent(newRows)
                    }).catch(error => {
                        console.error('Initial resize error:', error);
                    });
                }
            } else {
                term.write('Error: ' + (data.error || 'Unknown error') + '\r\n');
                disconnect();
            }
        })
        .catch(error => {
            console.error('Terminal connection failed:', error);
            term.write('Terminal connection failed: ' + error.message + '\r\n');
            disconnect();
        });
    };

    websocket.onmessage = function(event) {
        console.log('WebSocket message received:', event.data);
        if (typeof event.data === 'string') {
            // JSON message (like session ended)
            try {
                const data = JSON.parse(event.data);
                if (data.ended) {
                    console.log('Session ended');
                    disconnect();
                }
            } catch (e) {
                console.error('Failed to parse JSON message:', e);
            }
        } else {
            // Binary data (terminal output)
            term.write(new Uint8Array(event.data));
        }
    };

    websocket.onerror = function(error) {
        console.error('WebSocket error:', error);
        term.write('WebSocket error occurred\r\n');
        disconnect();
    };

    websocket.onclose = function(event) {
        console.log('WebSocket closed:', event.code, event.reason);
        term.write('Connection closed\r\n');
        disconnect();
    };

    // Handle input - send all keystrokes to server via WebSocket
    term.onKey(e => {
        if (!connected || !websocket || websocket.readyState !== WebSocket.OPEN) return;

        let data = e.key;
        console.log('Sending input data via WebSocket:', data);

        // Send input data via WebSocket
        websocket.send(data);

        // Prevent local display of input
        e.domEvent.preventDefault();
    });
}

function disconnect() {
    connected = false;
    document.getElementById('connectBtn').disabled = false;
    document.getElementById('disconnectBtn').disabled = true;
    document.getElementById('sshUsername').disabled = false;

    if (websocket && websocket.readyState === WebSocket.OPEN) {
        websocket.close();
    }
    websocket = null;

    if (requestId) {
        fetch('/terminal/%s/xterm/disconnect', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            body: 'request_id=' + encodeURIComponent(requestId)
        });
        requestId = null;
    }

    if (term) {
        term.write('\r\nDisconnected\r\n');
        setTimeout(() => {
            location.reload();
        }, 3000);
    }
}


// Focus on terminal when connected
document.addEventListener('keydown', function(e) {
    if (connected && term) {
        term.focus();
    }
});
</script>
</body>
</html>
