{% extends "base.html" %}
{% from "macros/icons.html" import icon %}

{% block content %}
<section>
    <div class="flex items-center justify-between" style="margin-bottom: var(--space-lg);">
        <h1 class="section-title" style="margin-bottom:0;">
            <span class="icon">{{ icon('server') }}</span>
            {{ _('nav_servers') }}
        </h1>
        <button class="btn btn-primary" onclick="openModal('addServerModal')">
            {{ icon('plus') }} {{ _('add_server') }}
        </button>
    </div>

    {% if servers %}
    <div class="server-grid" id="serverGrid">
        {% for server in servers %}
        <div class="card card-hover server-card" id="server-{{ loop.index0 }}" data-idx="{{ loop.index0 }}"
            data-name="{{ server.name }}" data-host="{{ server.host }}" data-port="{{ server.ssh_port }}"
            data-username="{{ server.username }}" data-auth="{{ 'key' if server.private_key else 'password' }}"
            data-ssl-domain="{{ (server.server_info or {}).get('ssl_domain', '') }}"
            data-ssl-email="{{ (server.server_info or {}).get('ssl_email', '') }}"
            draggable="true">
            <div class="server-meta">
                <div class="server-icon">{{ icon('server') }}</div>
                <div style="min-width: 0; flex: 1;">
                    <div class="server-name">
                        <span class="ping-dot ping-pending" id="ping-{{ loop.index0 }}"
                            title="{{ _('ping_checking') }}"></span>
                        <span>{{ server.name }}</span>
                        <span class="ping-ms text-muted" id="ping-ms-{{ loop.index0 }}"></span>
                    </div>
                    <div class="server-host">{{ server.host }}:{{ server.ssh_port }}</div>
                </div>
            </div>

            <div class="server-protocols" id="server-protocols-{{ loop.index0 }}">
                {% if server.protocols %}
                {% for proto_key, proto_val in server.protocols.items() %}
                {% if proto_val.get('installed') %}
                <span class="badge badge-success">
                    <span class="badge-dot"></span>
                    {{ 'AWG' if proto_key == 'awg' else ('AWG-Legacy' if proto_key == 'awg_legacy' else ('Xray' if
                    proto_key == 'xray' else proto_key | upper)) }}
                </span>
                {% endif %}
                {% endfor %}
                {% else %}
                <span class="badge badge-warn">
                    <span class="badge-dot"></span>
                    {{ _('no_protocols') }}
                </span>
                {% endif %}
            </div>

            <div class="server-actions">
                <a href="/server/{{ loop.index0 }}" class="btn btn-secondary btn-sm" style="flex:1">
                    {{ _('manage') }}
                </a>
                <button class="btn btn-secondary btn-sm btn-icon" onclick="openEditServer(this)"
                    title="{{ _('edit') }}">
                    {{ icon('pencil') }}
                </button>
                <button class="btn btn-danger btn-sm btn-icon" onclick="deleteServer({{ loop.index0 }})"
                    title="{{ _('delete') }}">
                    {{ icon('trash') }}
                </button>
            </div>
        </div>
        {% endfor %}
    </div>
    {% else %}
    <div class="empty-state">
        <div class="empty-icon">{{ icon('shield') }}</div>
        <div class="empty-title">{{ _('no_servers') }}</div>
        <div class="empty-desc">
            {{ _('add_server_desc') }}
        </div>
        <button class="btn btn-primary" onclick="openModal('addServerModal')">
            {{ icon('plus') }} {{ _('add_server') }}
        </button>
    </div>
    {% endif %}
</section>

<!-- ===== Edit Server Modal ===== -->
<div class="modal-backdrop" id="editServerModal">
    <div class="modal">
        <div class="modal-header">
            <h2 class="modal-title">{{ _('edit_server_title') }}</h2>
            <button class="modal-close" onclick="closeModal('editServerModal')">×</button>
        </div>

        <form id="editServerForm" onsubmit="return submitEditServer(event)">
            <input type="hidden" id="editServerIdx">

            <div class="form-group">
                <label class="form-label">{{ _('name') }}</label>
                <input class="form-input" type="text" id="editServerName">
            </div>

            <div class="form-row">
                <div class="form-group">
                    <label class="form-label">{{ _('ssh_host') }}</label>
                    <input class="form-input" type="text" id="editServerHost" required>
                </div>
                <div class="form-group">
                    <label class="form-label">{{ _('ssh_port') }}</label>
                    <input class="form-input" type="number" id="editServerPort" min="1" max="65535">
                </div>
            </div>

            <div class="form-group">
                <label class="form-label">{{ _('ssh_user') }}</label>
                <input class="form-input" type="text" id="editServerUser" required>
            </div>

            <div class="tabs" style="margin-top: var(--space-md)">
                <button type="button" class="tab active" onclick="switchEditAuthTab('password', this)">{{ _('ssh_password') }}</button>
                <button type="button" class="tab" onclick="switchEditAuthTab('key', this)">{{ _('ssh_key') }}</button>
            </div>

            <div id="editAuthPassword">
                <div class="form-group">
                    <label class="form-label">{{ _('ssh_password') }}</label>
                    <input class="form-input" type="password" id="editServerPassword"
                        placeholder="{{ _('edit_keep_credential') }}">
                    <div class="form-hint">{{ _('edit_keep_credential') }}</div>
                </div>
            </div>

            <div id="editAuthKey" class="hidden">
                <div class="form-group">
                    <label class="form-label">{{ _('ssh_key') }}</label>
                    <textarea class="form-textarea" id="editServerKey"
                        placeholder="{{ _('edit_keep_credential') }}"></textarea>
                    <div class="form-hint">{{ _('edit_keep_credential') }}</div>
                </div>
            </div>

            <div class="form-group" style="margin-top: var(--space-md)">
                <label class="form-label">{{ _('server_ssl_domain') }}</label>
                <input class="form-input" type="text" id="editServerSslDomain" placeholder="vpn.example.com">
                <div class="form-hint">{{ _('server_ssl_hint') }}</div>
            </div>
            <div class="form-group">
                <label class="form-label">{{ _('server_ssl_email') }}</label>
                <input class="form-input" type="email" id="editServerSslEmail" placeholder="admin@example.com">
            </div>

            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" onclick="closeModal('editServerModal')">{{ _('cancel')
                    }}</button>
                <button type="submit" class="btn btn-primary" id="editServerBtn">
                    <span id="editServerBtnText">{{ _('save') }}</span>
                    <div class="spinner hidden" id="editServerSpinner"></div>
                </button>
            </div>
        </form>
    </div>
</div>

<!-- ===== Add Server Modal ===== -->
<div class="modal-backdrop" id="addServerModal">
    <div class="modal">
        <div class="modal-header">
            <h2 class="modal-title">{{ _('add_server') }}</h2>
            <button class="modal-close" onclick="closeModal('addServerModal')">×</button>
        </div>

        <form id="addServerForm" onsubmit="return addServer(event)">
            <div class="form-group">
                <label class="form-label">{{ _('name') }}</label>
                <input class="form-input" type="text" id="serverName" placeholder="My VPN Server">
            </div>

            <div class="form-row">
                <div class="form-group">
                    <label class="form-label">{{ _('ssh_host') }}</label>
                    <input class="form-input" type="text" id="serverHost" placeholder="192.168.1.1" required>
                </div>
                <div class="form-group">
                    <label class="form-label">{{ _('ssh_port') }}</label>
                    <input class="form-input" type="number" id="serverPort" value="22" min="1" max="65535">
                </div>
            </div>

            <div class="form-group">
                <label class="form-label">{{ _('ssh_user') }}</label>
                <input class="form-input" type="text" id="serverUser" placeholder="root" required>
            </div>

            <!-- Tabs for auth method -->
            <div class="tabs" style="margin-top: var(--space-md)">
                <button type="button" class="tab active" onclick="switchAuthTab('password', this)">{{ _('ssh_password')
                    }}</button>
                <button type="button" class="tab" onclick="switchAuthTab('key', this)">{{ _('ssh_key') }}</button>
            </div>

            <div id="authPassword">
                <div class="form-group">
                    <label class="form-label">{{ _('ssh_password') }}</label>
                    <input class="form-input" type="password" id="serverPassword" placeholder="••••••••">
                </div>
            </div>

            <div id="authKey" class="hidden">
                <div class="form-group">
                    <label class="form-label">{{ _('ssh_key') }}</label>
                    <textarea class="form-textarea" id="serverKey"
                        placeholder="{{ _('ssh_key_placeholder') }}"></textarea>
                    <div class="form-hint">{{ _('ssh_key_hint') }}</div>
                </div>
            </div>

            <div class="form-group" style="margin-top: var(--space-md)">
                <label class="form-label">{{ _('server_ssl_domain') }}</label>
                <input class="form-input" type="text" id="serverSslDomain" placeholder="vpn.example.com">
                <div class="form-hint">{{ _('server_ssl_hint') }}</div>
            </div>
            <div class="form-group">
                <label class="form-label">{{ _('server_ssl_email') }}</label>
                <input class="form-input" type="email" id="serverSslEmail" placeholder="admin@example.com">
            </div>

            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" onclick="closeModal('addServerModal')">{{ _('cancel')
                    }}</button>
                <button type="submit" class="btn btn-primary" id="addServerBtn">
                    <span id="addServerBtnText">{{ _('connect') }}</span>
                    <div class="spinner hidden" id="addServerSpinner"></div>
                </button>
            </div>
        </form>
    </div>
</div>
{% endblock %}

{% block scripts %}
<script>
    function switchAuthTab(tab, btn) {
        document.querySelectorAll('.tabs .tab').forEach(t => t.classList.remove('active'));
        btn.classList.add('active');

        document.getElementById('authPassword').classList.toggle('hidden', tab !== 'password');
        document.getElementById('authKey').classList.toggle('hidden', tab !== 'key');
    }

    async function addServer(e) {
        e.preventDefault();

        const btn = document.getElementById('addServerBtn');
        const btnText = document.getElementById('addServerBtnText');
        const spinner = document.getElementById('addServerSpinner');

        btn.disabled = true;
        btnText.textContent = _('connecting');
        spinner.classList.remove('hidden');

        try {
            const data = {
                name: document.getElementById('serverName').value,
                host: document.getElementById('serverHost').value,
                ssh_port: parseInt(document.getElementById('serverPort').value) || 22,
                username: document.getElementById('serverUser').value,
                password: document.getElementById('serverPassword').value,
                private_key: document.getElementById('serverKey').value,
                ssl_domain: document.getElementById('serverSslDomain').value.trim(),
                ssl_email: document.getElementById('serverSslEmail').value.trim(),
            };

            const result = await apiCall('/api/servers/add', 'POST', data);
            showToast(_('server_added'), 'success');
            setTimeout(() => window.location.reload(), 800);

        } catch (err) {
            showToast(err.message, 'error');
        } finally {
            btn.disabled = false;
            btnText.textContent = _('connect');
            spinner.classList.add('hidden');
        }
    }

    async function deleteServer(serverId) {
        if (!confirm(_('delete_confirm'))) return;

        try {
            await apiCall(`/api/servers/${serverId}/delete`, 'POST');
            showToast(_('server_deleted'), 'success');
            setTimeout(() => window.location.reload(), 500);
        } catch (err) {
            showToast(err.message, 'error');
        }
    }

    /* ========== Edit server ========== */

    function switchEditAuthTab(tab, btn) {
        const tabs = btn.parentElement.querySelectorAll('.tab');
        tabs.forEach(t => t.classList.remove('active'));
        btn.classList.add('active');
        document.getElementById('editAuthPassword').classList.toggle('hidden', tab !== 'password');
        document.getElementById('editAuthKey').classList.toggle('hidden', tab !== 'key');
    }

    function openEditServer(btn) {
        // Prefill from data-* on the parent server-card so we don't have to round-trip.
        const card = btn.closest('.server-card');
        if (!card) return;
        document.getElementById('editServerIdx').value = card.dataset.idx;
        document.getElementById('editServerName').value = card.dataset.name || '';
        document.getElementById('editServerHost').value = card.dataset.host || '';
        document.getElementById('editServerPort').value = card.dataset.port || '22';
        document.getElementById('editServerUser').value = card.dataset.username || '';
        document.getElementById('editServerPassword').value = '';
        document.getElementById('editServerKey').value = '';
        document.getElementById('editServerSslDomain').value = card.dataset.sslDomain || '';
        document.getElementById('editServerSslEmail').value = card.dataset.sslEmail || '';

        // Pre-select the tab matching the server's current auth method.
        const authIsKey = card.dataset.auth === 'key';
        const tabsEl = document.querySelector('#editServerForm .tabs');
        const passTab = tabsEl.children[0];
        const keyTab = tabsEl.children[1];
        switchEditAuthTab(authIsKey ? 'key' : 'password', authIsKey ? keyTab : passTab);

        openModal('editServerModal');
    }

    async function submitEditServer(e) {
        e.preventDefault();
        const idx = document.getElementById('editServerIdx').value;
        const btn = document.getElementById('editServerBtn');
        const btnText = document.getElementById('editServerBtnText');
        const spinner = document.getElementById('editServerSpinner');
        btn.disabled = true;
        btnText.textContent = _('saving') || 'Saving...';
        spinner.classList.remove('hidden');
        try {
            const body = {
                name: document.getElementById('editServerName').value,
                host: document.getElementById('editServerHost').value,
                ssh_port: parseInt(document.getElementById('editServerPort').value) || 22,
                username: document.getElementById('editServerUser').value,
                // Empty -> null means "leave unchanged" on the backend.
                password: document.getElementById('editServerPassword').value || null,
                private_key: document.getElementById('editServerKey').value || null,
                ssl_domain: document.getElementById('editServerSslDomain').value.trim(),
                ssl_email: document.getElementById('editServerSslEmail').value.trim(),
            };
            await apiCall(`/api/servers/${idx}/edit`, 'POST', body);
            showToast(_('server_saved'), 'success');
            setTimeout(() => window.location.reload(), 500);
        } catch (err) {
            showToast(err.message, 'error');
        } finally {
            btn.disabled = false;
            btnText.textContent = _('save');
            spinner.classList.add('hidden');
        }
        return false;
    }

    /* ========== Ping indicators ========== */

    async function pingServer(idx) {
        const dot = document.getElementById(`ping-${idx}`);
        const ms = document.getElementById(`ping-ms-${idx}`);
        if (!dot) return;
        try {
            const res = await fetch(`/api/servers/${idx}/ping`, { credentials: 'same-origin' });
            const data = await res.json();
            dot.classList.remove('ping-pending');
            if (data.alive) {
                dot.classList.add('ping-ok');
                dot.title = `${data.ms} ms`;
                if (ms) ms.textContent = `${data.ms} ms`;
            } else {
                dot.classList.add('ping-fail');
                dot.title = data.error || _('offline');
                if (ms) ms.textContent = _('offline');
            }
        } catch {
            dot.classList.remove('ping-pending');
            dot.classList.add('ping-fail');
            if (ms) ms.textContent = _('offline');
        }
    }

    function startAllPings() {
        // Browsers will fan these out concurrently; the page never blocks waiting
        // for results because each card updates independently.
        document.querySelectorAll('.server-card').forEach(card => {
            const idx = card.dataset.idx;
            if (idx !== undefined) pingServer(idx);
        });
    }

    /* ========== Drag-and-drop reorder ========== */

    let draggedCard = null;

    function setupDragAndDrop() {
        const grid = document.getElementById('serverGrid');
        if (!grid) return;

        grid.addEventListener('dragstart', e => {
            const card = e.target.closest('.server-card');
            if (!card) return;
            // Don't initiate drag from a button/link inside the card — those have
            // their own click semantics (Edit/Delete/Manage).
            if (e.target.closest('button, a')) {
                e.preventDefault();
                return;
            }
            draggedCard = card;
            card.classList.add('dragging');
            e.dataTransfer.effectAllowed = 'move';
            // Some browsers require this for dragstart to fire with text payload.
            try { e.dataTransfer.setData('text/plain', card.dataset.idx); } catch {}
        });

        grid.addEventListener('dragend', e => {
            const card = e.target.closest('.server-card');
            if (card) card.classList.remove('dragging');
            grid.querySelectorAll('.server-card.drag-over').forEach(c => c.classList.remove('drag-over'));
            draggedCard = null;
        });

        grid.addEventListener('dragover', e => {
            e.preventDefault();
            e.dataTransfer.dropEffect = 'move';
            const card = e.target.closest('.server-card');
            if (!card || card === draggedCard) return;
            grid.querySelectorAll('.server-card.drag-over').forEach(c => {
                if (c !== card) c.classList.remove('drag-over');
            });
            card.classList.add('drag-over');
        });

        grid.addEventListener('dragleave', e => {
            const card = e.target.closest('.server-card');
            if (card && !card.contains(e.relatedTarget)) card.classList.remove('drag-over');
        });

        grid.addEventListener('drop', async e => {
            e.preventDefault();
            const target = e.target.closest('.server-card');
            grid.querySelectorAll('.server-card.drag-over').forEach(c => c.classList.remove('drag-over'));
            if (!target || !draggedCard || target === draggedCard) return;

            // Insert before/after target depending on cursor position relative
            // to the target's vertical centre, which feels natural in a grid.
            const rect = target.getBoundingClientRect();
            const insertAfter = (e.clientY - rect.top) > rect.height / 2;
            grid.insertBefore(draggedCard, insertAfter ? target.nextSibling : target);

            const newOrder = Array.from(grid.querySelectorAll('.server-card'))
                .map(c => parseInt(c.dataset.idx, 10));

            try {
                await apiCall('/api/servers/reorder', 'POST', { order: newOrder });
                showToast(_('servers_reordered'), 'success');
                // Reload so onclick indices and per-card data-idx attrs realign with
                // the new server array — simpler and safer than rewriting every handler.
                setTimeout(() => window.location.reload(), 400);
            } catch (err) {
                showToast(err.message, 'error');
                // Rollback the visual move — backend rejected.
                window.location.reload();
            }
        });
    }

    document.addEventListener('DOMContentLoaded', () => {
        startAllPings();
        setupDragAndDrop();
    });
</script>
{% endblock %}