<div class="standardContainer">
    <div class="ui basic segment">
        <h2>TLS / SSL Certificates</h2>
        <p>Setup TLS cert for different domains of your reverse proxy server names</p>
    </div>
    
    <div class="ui divider"></div>
    <h4>Default Certificates</h4>
        <small>When there are no matching certificate for the requested server name, reverse proxy router will always fallback to this one.<br>Note that you need both of them uploaded for it to fallback properly</small></p>
        <table class="ui very basic unstackable celled table">
            <thead>
                <tr><th class="no-sort">Key Type</th>
                <th  class="no-sort">Exists</th>
            </tr></thead>
            <tbody>
                <tr>
                    <td><i class="globe icon"></i> Default Public Key</td>
                    <td id="pubkeyExists"></td>
                </tr>
                <tr>
                    <td><i class="lock icon"></i> Default Private Key</td>
                    <td id="prikeyExists"></td>
                </tr>
            </tbody>
        </table>
        <p style="margin-bottom: 0.4em;"><i class="ui upload icon"></i> Upload Default Keypairs</p>
        <div class="ui buttons">
            <button class="ui basic grey button" onclick="uploadPublicKey();"><i class="globe icon"></i> Public Key</button>
            <button class="ui basic black button" onclick="uploadPrivateKey();"><i class="black lock icon"></i> Private Key</button>
        </div>
 
    <div class="ui divider"></div>
    <h4>Sub-domain Certificates</h4>
    <p>Provide certificates for multiple domains reverse proxy</p>
    <div class="ui fluid form">
        <div class="three fields">
            <div class="field">
            <label>Server Name (Domain)</label>
            <input type="text" id="certdomain" placeholder="example.com / blog.example.com">
            </div>
            <div class="field">
                <label>Public Key (.pem)</label>
                <input type="file" id="pubkeySelector" onchange="handleFileSelect(event, 'pub')">
            </div>
            <div class="field">
                <label>Private Key (.key)</label>
                <input type="file" id="prikeySelector" onchange="handleFileSelect(event, 'pri')">
            </div>
        </div>
        <button class="ui basic button" onclick="handleDomainUploadByKeypress();"><i class="ui teal upload icon"></i> Upload</button><br>
        <small>You have intermediate certificate? <a style="cursor:pointer;" onclick="showSideWrapper('snippet/intermediateCertConv.html');">Open Conversion Tool</a></small>
    </div>
    <div id="certUploadSuccMsg" class="ui green message" style="display:none;">
        <i class="ui checkmark icon"></i> Certificate for domain <span id="certUploadingDomain"></span> uploaded.
    </div>
    <br>
    <div>
        <table class="ui sortable unstackable celled table">
            <thead>
            <tr><th>Domain</th>
            <th>Last Update</th>
            <th>Expire At</th>
            <th class="no-sort">Remove</th>
            </tr></thead>
        <tbody id="certifiedDomainList">

        </tbody>
        </table>
        <button class="ui basic button" onclick="initManagedDomainCertificateList();"><i class="green refresh icon"></i> Refresh List</button>
        <button class="ui basic button" onclick="openACMEManager();"><i class="yellow refresh icon"></i> Auto Renew (ACME) Settings</button>
    </div>
    <div class="ui message">
        <h4><i class="info circle icon"></i> Sub-domain Certificates</h4>
        If you have 3rd or even 4th level subdomains like <code>blog.example.com</code> or <code>en.blog.example.com</code> ,
        depending on your certificates coverage, you might need to setup them one by one (i.e. having two seperate certificate for <code>a.example.com</code> and <code>b.example.com</code>).<br>
        If you have a wildcard certificate that covers <code>*.example.com</code>, you can just enter <code>example.com</code> as server name in the form below to add a certificate.
    </div>
</div>
<script>
    var uploadPendingPublicKey = undefined;
    var uploadPendingPrivateKey = undefined;

    //Delete the certificate by its domain
    function deleteCertificate(domain){
        if (confirm("Confirm delete certificate for " + domain + " ?")){
            $.ajax({
                url: "/api/cert/delete",
                method: "POST",
                data: {domain: domain},
                success: function(data){
                    if (data.error != undefined){
                        msgbox(data.error, false, 5000);
                    }else{
                        initManagedDomainCertificateList();
                        initDefaultKeypairCheck();
                    }
                }
            });
        }
        
    }

    //List the stored certificates
    function initManagedDomainCertificateList(){
        $.get("/api/cert/list?date=true", function(data){
            if (data.error != undefined){
                msgbox(data.error, false, 5000);
            }else{
                $("#certifiedDomainList").html("");
                data.sort((a,b) => {
                    return a.Domain > b.Domain
                });
                data.forEach(entry => {
                    $("#certifiedDomainList").append(`<tr>
                        <td>${entry.Domain}</td>
                        <td>${entry.LastModifiedDate}</td>
                        <td>${entry.ExpireDate} (${entry.RemainingDays} days left)</td>
                        <td><button title="Delete key-pair" class="ui mini basic red icon button" onclick="deleteCertificate('${entry.Domain}');"><i class="ui red trash icon"></i></button></td>
                    </tr>`);
                });

                if (data.length == 0){
                    $("#certifiedDomainList").append(`<tr>
                        <td colspan="4"><i class="ui times circle icon"></i> No valid keypairs found</td>
                    </tr>`);
                }
            }
        })
    }
    initManagedDomainCertificateList();

    function openACMEManager(){
        showSideWrapper('snippet/acme.html');
    }

    function handleDomainUploadByKeypress(){
        handleDomainKeysUpload(function(){
            $("#certUploadingDomain").text($("#certdomain").val().trim());
            //After uploaded, reset the file selector
            document.getElementById('pubkeySelector').value = '';
            document.getElementById('prikeySelector').value = '';
            document.getElementById('certdomain').value = '';

            uploadPendingPublicKey = undefined;
            uploadPendingPrivateKey = undefined;

            //Show succ
            $("#certUploadSuccMsg").stop().finish().slideDown("fast").delay(3000).slideUp("fast");
            initManagedDomainCertificateList();
        });
    }
    //Handle domain keys upload
    function handleDomainKeysUpload(callback=undefined){
        let domain = $("#certdomain").val();
        if (domain.trim() == ""){
            msgbox("Missing domain", false, 5000);
            return;
        }
        if (uploadPendingPublicKey && uploadPendingPrivateKey && typeof uploadPendingPublicKey === 'object' && typeof uploadPendingPrivateKey === 'object') {
            const publicKeyForm = new FormData();
            publicKeyForm.append('file', uploadPendingPublicKey, 'publicKey');

            const privateKeyForm = new FormData();
            privateKeyForm.append('file', uploadPendingPrivateKey, 'privateKey');

            const publicKeyRequest = new XMLHttpRequest();
            publicKeyRequest.open('POST', '/api/cert/upload?ktype=pub&domain=' + domain);
            publicKeyRequest.onreadystatechange = function() {
            if (publicKeyRequest.readyState === XMLHttpRequest.DONE) {
                if (publicKeyRequest.status !== 200) {
                    msgbox('Error uploading public key: ' + publicKeyRequest.statusText, false, 5000);
                }

                if (callback != undefined){
                    callback();
                }
                
            }
            };
            publicKeyRequest.send(publicKeyForm);

            const privateKeyRequest = new XMLHttpRequest();
            privateKeyRequest.open('POST', '/api/cert/upload?ktype=pri&domain=' + domain);
            privateKeyRequest.onreadystatechange = function() {
            if (privateKeyRequest.readyState === XMLHttpRequest.DONE) {
                if (privateKeyRequest.status !== 200) {
                    msgbox('Error uploading private key: ' + privateKeyRequest.statusText, false, 5000);
                }
                if (callback != undefined){
                    callback();
                }
            }
            };
            privateKeyRequest.send(privateKeyForm);
        } else {
            msgbox('One or both of the files is missing or not a file object');
        }
    }

    //Handlers for selecting domain based key pairs
    //ktype = {"pub" / "pri"}
    function handleFileSelect(event, ktype="pub") {
        const file = event.target.files[0];
        //const fileNameInput = document.getElementById('selected-file-name');
        if (ktype == "pub"){
            uploadPendingPublicKey = file;
        }else if (ktype == "pri"){
            uploadPendingPrivateKey = file;
        }
        
        
        //fileNameInput.value = file.name;
    }

    //Check if the default keypairs exists
    function initDefaultKeypairCheck(){
        $.get("/api/cert/checkDefault", function(data){
            let tick = `<i class="ui green checkmark icon"></i>`;
            let cross = `<i class="ui red times icon"></i>`;
            $("#pubkeyExists").html(data.DefaultPubExists?tick:cross);
            $("#prikeyExists").html(data.DefaultPriExists?tick:cross);
        });
    }
    initDefaultKeypairCheck();

    function uploadPrivateKey(){
        // create file input element
        const input = document.createElement('input');
        input.type = 'file';
        
        // add change listener to file input
        input.addEventListener('change', () => {
            // create form data object
            const formData = new FormData();
            
            // add selected file to form data
            formData.append('file', input.files[0]);

            // send form data to server
            fetch('/api/cert/upload?ktype=pri', {
                method: 'POST',
                body: formData
            })
            .then(response => {
                initDefaultKeypairCheck();
                if (response.ok) {
                    msgbox('File upload successful!');
                } else {
                    response.text().then(text => {
                        msgbox(text, false, 5000);
                    });
                    //console.log(response.text());
                    //alert('File upload failed!');
                }
                })
            .catch(error => {
                msgbox('An error occurred while uploading the file.', false, 5000);
                console.error(error);
            });
        });
        
        // click file input to open file selector
        input.click();
    }

    function uploadPublicKey() {
        // create file input element
        const input = document.createElement('input');
        input.type = 'file';
        
        // add change listener to file input
        input.addEventListener('change', () => {
            // create form data object
            const formData = new FormData();
            
            // add selected file to form data
            formData.append('file', input.files[0]);

            // send form data to server
            fetch('/api/cert/upload?ktype=pub', {
                method: 'POST',
                body: formData
            })
            .then(response => {
                if (response.ok) {
                    msgbox('File upload successful!');
                    initDefaultKeypairCheck();
                } else {
                    response.text().then(text => {
                        msgbox(text, false, 5000);
                    });
                    //console.log(response.text());
                    //alert('File upload failed!');
                }
                })
            .catch(error => {
                msgbox('An error occurred while uploading the file.', false, 5000);
                console.error(error);
            });
        });
        
        // click file input to open file selector
        input.click();
    }
</script>