{% extends "base.html" %}
{% block page_custom_head %}
    <style>
        .peer-extra-info {
            display: none;
        }
    </style>
{% endblock %}


{% block content %}
    {% if wireguard_instances %}
        <div class="card card-primary card-outline">
            <div class="card-body">
                <ul class="nav nav-tabs" role="tablist">
                    {% for wgconf in wireguard_instances %}
                        <li class="nav-item">
                            <a class="nav-link {% if wgconf == current_instance %}active{% endif %}" href="/peer/list/?uuid={{ wgconf.uuid }}" role="tab">
                                wg{{ wgconf.instance_id }} {% if wgconf.name %}({{ wgconf.name }}){% endif %}
                            </a>
                        </li>
                    {% endfor %}
                </ul>
                <div class="tab-content" id="custom-content-below-tabContent">
                    <div class="tab-pane fade show active" id="custom-content-below-home" role="tabpanel" aria-labelledby="custom-content-below-home-tab">
                        <div class="row" style="padding-top: 15px">
                            {% for peer in peer_list %}
                                <div class="col-md-6" id="peer-{{ peer.public_key }}" data-uuid="{{ peer.uuid }}">
                                    <div class="callout">
                                        <div class="d-flex justify-content-between align-items-start">
                                            <h5>
                                                <a href="#" onclick="openPeerModal('{{ peer.uuid }}');" style="text-decoration: none">
                                                    {{ peer }}
                                                </a>
                                            </h5>
                                            <span>
                                              {% if user_acl.user_level >= 30 %}
                                                  <div class="d-inline-flex flex-column">
                                                <a href="/peer/sort/?peer={{ peer.uuid }}&direction=up" style="line-height:0px">
                                                  <i class="fas fa-sort-up"></i>
                                                </a>
                                                <div style="overflow:hidden;margin-top: -9px">
                                                  <a href="/peer/sort/?peer={{ peer.uuid }}&direction=down" style="position:relative;top:-11px">
                                                    <i class="fas fa-sort-down"></i>
                                                  </a>
                                                </div>
                                              </div>
                                              {% endif %}
                                                {% comment %}
                                                <a href="/peer/manage/?peer={{ peer.uuid }}">
                                                    <i class="far fa-edit"></i>
                                                </a>
                                                {% endcomment %}
                                            </span>
                                        </div>
                                        <p>
                                            <b class="peer-extra-info">Throughput: </b> <span id="peer-throughput-{{ peer.public_key }}"></span><br>
                                            <span class="peer-extra-info"><b>Transfer:</b> <span id="peer-transfer-{{ peer.public_key }}"></span><br></span>
                                            <span class="peer-extra-info"><b>Latest Handshake:</b> <span id="peer-latest-handshake-{{ peer.public_key }}"></span></span>
                                            <span class="peer-extra-info"><span style="display: none;" id="peer-stored-latest-handshake-{{ peer.public_key }}">{% if peer.peerstatus.last_handshake %}{{ peer.peerstatus.last_handshake|date:"U" }}{% else %}0{% endif %}</span><br></span>

                                            <span class="peer-extra-info"><b>Endpoints:</b> <span id="peer-endpoints-{{ peer.public_key }}"></span><br></span>
                                            <span class="peer-extra-info" id="peer-extra-info-allowed-ips-{{ peer.public_key }}">
                                            <b>Allowed IPs:</b>
                                            <span id="peer-allowed-ips-{{ peer.public_key }}">
                                                 {% for address in peer.peerallowedip_set.all %}
                                                     {% if address.priority == 0 and address.config_file == 'server' %}
                                                         {{ address }}
                                                     {% endif %}
                                                 {% endfor %}
                                                {% for address in peer.peerallowedip_set.all %}
                                                    {% if address.priority >= 1 and address.config_file == 'server' %}
                                                        {{ address }}
                                                    {% endif %}
                                                {% endfor %}
                                            </span>
                                            </span>
                                        </p>
                                    </div>
                                </div>
                            {% endfor %}
                        </div>
                        {% if add_peer_enabled %}
                            <a class="btn btn-primary" href="/peer/manage/?instance={{ current_instance.uuid }}" onclick="return confirm('Are you sure you want to create a new peer?');">Create Peer</a>
                        {% else %}
                            <a class="btn btn-primary disabled" href="">Create Peer</a>
                        {% endif %}
                        <button id="toggleExtraInfo" class="btn btn-outline-primary">Show extras</button>
                    </div>
                </div>
            </div>
        </div>

        <!-- Peer Preview Modal -->
        <div class="modal fade" id="peerPreviewModal" tabindex="-1" aria-labelledby="peerPreviewModalLabel" aria-hidden="true">
            <div class="modal-dialog modal-lg">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="peerPreviewModalLabel">Peer Preview</h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">&times;</span>
                        </button>
                    </div>
                    <div class="modal-body">
                        <!-- Info content section -->
                        <div class="info-content">
                            <p><b><i class="fas fa-arrows-alt-v nav-icon"></i> Throughput:</b> <span id="peerThroughput">--</span></p>
                            <p><b><i class="fas fa-dolly nav-icon"></i> Transfer:</b> <span id="peerTransfer">--</span></p>
                            <p><b><i class="far fa-clock nav-icon"></i></i> Latest Handshake:</b> <span id="peerHandshake">--</span></p>
                            <p><b><i class="far fa-address-card nav-icon"></i> Endpoints:</b> <span id="peerEndpoints">--</span></p>
                            <p><b><i class="fas fa-network-wired nav-icon"></i> Allowed IPs:</b> <span id="peerAllowedIPs">--</span></p>

                            <!-- Traffic Graph -->
                            <div class="graph-container" style="margin-top:20px;">
                                <div class="d-flex justify-content-between align-items-center">
                                    <label>
                                        <i class="fas fa-chart-area nav-icon"></i>
                                        Peer Traffic
                                    </label>
                                    <div class="btn-group" role="group" aria-label="Graph interval">
                                        <a href="#" data-period="1h" class="btn btn-outline-primary btn-xs">1h</a>
                                        <a href="#" data-period="3h" class="btn btn-outline-primary btn-xs">3h</a>
                                        <a href="#" data-period="6h" class="btn btn-outline-primary btn-xs">6h</a>
                                        <a href="#" data-period="1d" class="btn btn-outline-primary btn-xs">1d</a>
                                        <a href="#" data-period="7d" class="btn btn-outline-primary btn-xs">7d</a>
                                        <a href="#" data-period="30d" class="btn btn-outline-primary btn-xs">1m</a>
                                        <a href="#" data-period="90d" class="btn btn-outline-primary btn-xs">3m</a>
                                        <a href="#" data-period="180d" class="btn btn-outline-primary btn-xs">6m</a>
                                        <a href="#" data-period="365d" class="btn btn-outline-primary btn-xs">1y</a>
                                    </div>
                                </div>
                                <center style="margin-top:10px;">
                                    <img id="graphImg" src="" class="img-fluid" alt="No traffic history, please wait a few minutes" style="display:block;">
                                </center>
                            </div>
                        </div>

                        <!-- QR Code content section (initially hidden) -->
                        <div class="qr-code-content" style="display:none; ">
                            <button class="btn btn-secondary" id="backButton"><i class="fas fa-times"></i> Close QR Code</button><br>
                            <div style="text-align: center;">
                                <img id="qrCodeImg" src="" alt="QR Code" class="img-fluid" style="max-width: 400px" />
                            </div>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-dismiss="modal"><i class="fas fa-times"></i>  Close</button>
                        <a href="#" class="btn btn-info" id="downloadConfigButton"><i class="fas fa-download"></i> Config</a>
                        <a href="#" class="btn btn-info" id="qrcodeButton"><i class="fas fa-qrcode"></i> QR Code</a>
                        <a href="#" class="btn btn-outline-primary" id="editPeerButton"><i class="far fa-edit"></i> Edit</a>
                    </div>
                </div>
            </div>
        </div>

    {% else %}
        <div class="alert alert-warning" role="alert">
            <h4 class="alert-heading">No WireGuard Instances Found</h4>
            <p>There are no WireGuard instances configured. You can add a new instance by clicking the button below.</p>
        </div>
        <p>
            <a href="/server/manage/" class="btn btn-primary">Add WireGuard Instance</a>
        </p>
    {% endif %}
{% endblock %}


{% block custom_page_scripts %}
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            $("#qrcodeButton").on("click", function(e) {
                e.preventDefault();
                var uuid = $("#peerPreviewModal").data("peer-uuid");
                $("#qrCodeImg").attr("src", "/tools/download_peer_config/?uuid=" + uuid + "&format=qrcode");
                $(".info-content").hide();
                $(".qr-code-content").show();
            });

            $("#backButton").on("click", function(e) {
                e.preventDefault();
                $(".qr-code-content").hide();
                $(".info-content").show();
            });
        });
    </script>

    <script>
        function openPeerModal(uuid) {
            $(".qr-code-content").hide();
            $(".info-content").show();
            $("#qrCodeImg").attr("src", "");
            $('#graphImg').attr('src', '').hide();
            // Find the peer element by its data-uuid attribute
            var peerElem = document.querySelector('[data-uuid="' + uuid + '"]');
            if (peerElem) {
                var peerNameFromCard = peerElem.querySelector('h5').innerText;
                var peerThroughput = peerElem.querySelector('[id^="peer-throughput-"]').innerHTML;
                var peerTransfer = peerElem.querySelector('[id^="peer-transfer-"]').innerText;
                var peerHandshake = peerElem.querySelector('[id^="peer-latest-handshake-"]').innerText;
                var peerEndpoints = peerElem.querySelector('[id^="peer-endpoints-"]').innerText;
                var peerAllowedIPs = peerElem.querySelector('[id^="peer-allowed-ips-"]').innerHTML;

                // Update the modal fields with the card values
                $('#peerPreviewModalLabel').text(peerNameFromCard);
                $('#peerThroughput').html(peerThroughput);
                $('#peerTransfer').text(peerTransfer);
                $('#peerHandshake').text(peerHandshake);
                $('#peerEndpoints').text(peerEndpoints);
                $('#peerAllowedIPs').html(peerAllowedIPs);
                $('#editPeerButton').attr('href', '/peer/manage/?peer=' + uuid);
                $('#downloadConfigButton').attr('href', '/tools/download_peer_config/?uuid=' + uuid);
                $('#qrcodeButton').attr('href', '/tools/download_peer_config/?uuid=' + uuid + '&format=qrcode');
                $('#graphImg').attr('src', '/rrd/graph/?peer=' + uuid).show();
                $('#peerPreviewModal').data('peer-uuid', uuid);

                $.ajax({
                    url: '/api/peer_info/',
                    data: { uuid: uuid },
                    type: 'GET',
                    dataType: 'json',
                    success: function(data) {
                        if (data.name) {
                            $('#peerPreviewModalLabel').text(data.name);
                        }
                        // Future additional peer information can be handled here.
                    },
                    error: function(xhr, status, error) {
                        console.error("Error fetching peer info:", error);
                    }
                });
                $('#peerPreviewModal').modal('show');
            } else {
                console.error('Peer element not found for uuid: ' + uuid);
            }
        }

        $(document).on('click', '.graph-container .btn-group a', function(e) {
            e.preventDefault();
            var period = $(this).data('period');
            var uuid = $('#peerPreviewModal').data('peer-uuid');
            var newSrc = '/rrd/graph/?peer=' + uuid + '&period=' + period;
            $('#graphImg').attr('src', newSrc);
        });
    </script>

    <script>
        var previousMeasurements = {};
        var toastShownThisCycle = false;

        const updateThroughput = (peerId, peerInfo) => {
            const throughputElement = document.getElementById(`peer-throughput-${peerId}`);
            const currentTime = Date.now() / 1000; // current timestamp in seconds
            let formattedThroughput = '';

            if (previousMeasurements[peerId]) {
                const prev = previousMeasurements[peerId];
                const timeDiff = currentTime - prev.timestamp; // time difference in seconds

                // For peer perspective: download corresponds to tx and upload to rx
                let downloadDiff = peerInfo.transfer.tx - prev.transfer.tx;
                let uploadDiff = peerInfo.transfer.rx - prev.transfer.rx;

                // If counters have been reset (current < previous), show toast (only once per cycle)
                if (downloadDiff < 0 || uploadDiff < 0) {
                    if (!toastShownThisCycle) {
                        $(document).Toasts('create', {
                            class: 'bg-info',
                            title: 'info',
                            body: 'Throughput discarded due to counter reset',
                            delay: 10000,
                            autohide: true
                        });
                        toastShownThisCycle = true;
                    }
                    downloadDiff = 0;
                    uploadDiff = 0;
                }

                // Calculate throughput in bytes per second
                const downloadThroughput = downloadDiff / timeDiff;
                const uploadThroughput = uploadDiff / timeDiff;

                // Format throughput values (using convertBytes function)
                let downloadDisplay = convertBytes(downloadThroughput) + '/s';
                let uploadDisplay = convertBytes(uploadThroughput) + '/s';
                // Threshold: 1mb (1 megabit/s = 125000 bytes per second)
                const threshold = 125000;

                if (downloadThroughput > threshold) {
                    downloadDisplay = `<strong>${downloadDisplay}</strong>`;
                }
                if (uploadThroughput > threshold) {
                    uploadDisplay = `<strong>${uploadDisplay}</strong>`;
                }

                formattedThroughput = `<i class="fas fa-arrow-down"></i> ${downloadDisplay}, <i class="fas fa-arrow-up"></i> ${uploadDisplay}`;
                throughputElement.innerHTML = formattedThroughput;
            } else {
                // First cycle: no previous measurement available.
                formattedThroughput = `<i class="fas fa-arrow-down"></i> -.- B/s, <i class="fas fa-arrow-up"></i> -.- B/s`;
                throughputElement.innerHTML = formattedThroughput;
            }

            previousMeasurements[peerId] = {
                timestamp: currentTime,
                transfer: {
                    tx: peerInfo.transfer.tx,
                    rx: peerInfo.transfer.rx
                }
            };

            return formattedThroughput;
        };

        // Convert bytes to human-readable format with abbreviated units
        const convertBytes = (bytes) => {
            if (bytes === 0) return '0 B';
            const k = 1024;
            const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
            const i = Math.floor(Math.log(bytes) / Math.log(k));
            return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
        };

        // Fetch Wireguard status and update UI
        document.addEventListener('DOMContentLoaded', function() {
            const fetchWireguardStatus = async () => {
                try {
                    const response = await fetch('/api/wireguard_status/');
                    let data = await response.json();

                    // If latest-handshakes is 0, use the stored value
                    for (const [interfaceName, peers] of Object.entries(data)) {
                        for (const [peerId, peerInfo] of Object.entries(peers)) {
                            const peerElementId = `peer-stored-latest-handshake-${peerId}`;
                            const storedHandshakeElement = document.getElementById(peerElementId);
                            if (peerInfo['latest-handshakes'] === '0' && storedHandshakeElement) {
                                peerInfo['latest-handshakes'] = storedHandshakeElement.textContent;
                            }
                        }
                    }

                    updateUI(data);
                } catch (error) {
                    console.error('Error fetching Wireguard status:', error);
                }
            };

            fetchWireguardStatus();
            setInterval(fetchWireguardStatus, {{ current_instance.peer_list_refresh_interval }} * 1000);
        });

        const updateUI = (data) => {
            // Reset the toast flag for this update cycle
            toastShownThisCycle = false;

            for (const [interfaceName, peers] of Object.entries(data)) {
                for (const [peerId, peerInfo] of Object.entries(peers)) {
                    const peerDiv = document.getElementById(`peer-${peerId}`);
                    if (peerDiv) {
                        updatePeerInfo(peerDiv, peerId, peerInfo);
                        updateCalloutClass(peerDiv, peerInfo['latest-handshakes']);
                        // Calculate throughput and update the card
                        const throughputHTML = updateThroughput(peerId, peerInfo);

                        // If the modal is active for this peer, update its fields as well
                        const peerUuid = peerDiv.getAttribute("data-uuid");
                        if ($('#peerPreviewModal').is(':visible') && $('#peerPreviewModal').data('peer-uuid') === peerUuid) {
                            $('#peerThroughput').html(throughputHTML);
                            $('#peerTransfer').text(`${convertBytes(peerInfo.transfer.tx)} TX, ${convertBytes(peerInfo.transfer.rx)} RX`);
                            $('#peerHandshake').text(
                                peerInfo['latest-handshakes'] !== '0'
                                    ? new Date(parseInt(peerInfo['latest-handshakes']) * 1000).toLocaleString()
                                    : '0'
                            );
                            $('#peerEndpoints').text(peerInfo.endpoints);
                            const allowedIpsModalElement = document.getElementById('peerAllowedIPs');
                            checkAllowedIps(allowedIpsModalElement, peerInfo['allowed-ips']);
                        }
                    }
                }
            }
        };

        const updatePeerInfo = (peerDiv, peerId, peerInfo) => {
            const escapedPeerId = peerId.replace(/([!"#$%&'()*+,.\/:;<=>?@[\]^`{|}~])/g, '\\$1');
            const transfer = peerDiv.querySelector(`#peer-transfer-${escapedPeerId}`);
            const latestHandshake = peerDiv.querySelector(`#peer-latest-handshake-${escapedPeerId}`);
            const endpoints = peerDiv.querySelector(`#peer-endpoints-${escapedPeerId}`);
            const allowedIps = peerDiv.querySelector(`#peer-allowed-ips-${escapedPeerId}`);

            transfer.textContent = `${convertBytes(peerInfo.transfer.tx)} TX, ${convertBytes(peerInfo.transfer.rx)} RX`;
            latestHandshake.textContent = `${peerInfo['latest-handshakes'] !== '0' ? new Date(parseInt(peerInfo['latest-handshakes']) * 1000).toLocaleString() : '0'}`;
            endpoints.textContent = `${peerInfo.endpoints}`;
            checkAllowedIps(allowedIps, peerInfo['allowed-ips']);
        };

        const checkAllowedIps = (allowedIpsElement, allowedIpsApiResponse) => {
            const apiIps = allowedIpsApiResponse[0].split(' ');
            const htmlIpsText = allowedIpsElement.textContent.trim();
            const htmlIpsArray = htmlIpsText.match(/\b(?:\d{1,3}\.){3}\d{1,3}\/\d{1,2}\b/g) || [];

            allowedIpsElement.innerHTML = '';
            let showExtraInfo = false;

            htmlIpsArray.forEach((ip, index, array) => {
                const ipSpan = document.createElement('span');
                ipSpan.textContent = ip;
                allowedIpsElement.appendChild(ipSpan);

                if (!apiIps.includes(ip)) {
                    ipSpan.style.color = 'red';
                    ipSpan.style.textDecoration = 'underline';
                    ipSpan.title = 'This address does not appear in the wg show command output, likely indicating that another peer has an IP overlapping this network or that the configuration file is outdated.';
                    showExtraInfo = true;
                }

                if (index < array.length - 1) {
                    allowedIpsElement.appendChild(document.createTextNode(', '));
                }
            });

            if (showExtraInfo) {
                const extraInfoContainerId = allowedIpsElement.id.replace('peer-allowed-ips-', 'peer-extra-info-allowed-ips-');
                const extraInfoContainer = document.getElementById(extraInfoContainerId);
                if (extraInfoContainer) {
                    extraInfoContainer.style.display = 'block';
                }
            }
        };


        const updateCalloutClass = (peerDiv, latestHandshake) => {
            const calloutDiv = peerDiv.querySelector('.callout');
            calloutDiv.classList.remove('callout-success', 'callout-info', 'callout-warning', 'callout-danger');
            const handshakeAge = Date.now() / 1000 - parseInt(latestHandshake);

            if (latestHandshake === '0') {
                calloutDiv.classList.add('callout-danger');
            } else if (handshakeAge < 600) {
                calloutDiv.classList.add('callout-success');
            } else if (handshakeAge < 1800) {
                calloutDiv.classList.add('callout-info');
            } else if (handshakeAge < 21600) {
                calloutDiv.classList.add('callout-warning');
            }
            calloutDiv.style.transition = 'all 5s';
        };
    </script>

    <script>
        $(document).ready(function(){
            $("#toggleExtraInfo").click(function(){
                $(".peer-extra-info").toggle();
                if($(".peer-extra-info").is(":visible")){
                    $(this).text("Hide extras");
                } else {
                    $(this).text("Show extras");
                }
            });
        });
    </script>


{% endblock %}