<template id="tx-data">
    <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='styles.css') }}">
    <style>
        .tx-data-table td {
            text-align: left;
        }
        .tx_info {
            padding: 1em;
            border: 1px solid #506072;
            border-radius: 4px;
            text-align: center;
            margin-bottom: 2em;
        }
    </style>
    <div class="tx-data">
        <h2>{{ _("Transaction details") }}</h2><br>
        <div class="tx-data-info"></div>
        <div class="note"></div>
    </div>
</template>
  
<script type="text/javascript">
    class TxDataElement extends HTMLElement {
        constructor() {
            super();
            // Create a shadow root
            var shadow = this.attachShadow({mode: 'open'});
            var style = document.getElementById('tx-data').content;
            var clone = style.cloneNode(true);

            this.el = clone.querySelector(".tx-data");
            this.note = clone.querySelector(".note");
            this.info = clone.querySelector(".tx-data-info");
            this.txid = this.getAttribute('data-txid');
            this.wallet = this.getAttribute('data-tx-wallet');
            this.btcUnit = this.getAttribute('data-btc-unit');
            this.price = this.getAttribute('data-price');
            this.symbol = this.getAttribute('data-symbol');
            this.note.innerText = `{{ _("Loading transaction details...\n\nTransaction ID:") }}" ${this.txid}`;
            this.fetchTxData();
        
            // Attach the created element to the shadow dom
            shadow.appendChild(clone);
        }
        
        async fetchRawTx(txid) {
            let url = `{{ url_for('wallets_endpoint.decoderawtx', wallet_alias='WALLET_ALIAS') }}`.replace("WALLET_ALIAS", this.wallet);
            var formData = new FormData();
            formData.append('txid', txid);
            formData.append('csrf_token', '{{ csrf_token() }}');
            try {
                const response = await fetch(
                    url,
                    {
                        method: 'POST',
                        body: formData
                    }
                );
                if(response.status != 200){
                    showError(await response.text());
                    return null;
                }
                const jsonResponse = await response.json();
                return jsonResponse;
            } catch(e) {
                this.note.innerText = '{{ _("Failed to load transaction details...") }}';
                console.log("Caught error fetching decoded transaction: ", e);
                showError(`{{ _("Failed to fetch data. Please refresh the page and retry.") }}`);
            }
            return null;
        }

        async fetchTxData() {
            let jsonResponse = await this.fetchRawTx(this.txid);
            if (jsonResponse !== null && jsonResponse.success) {
                console.log(jsonResponse);
                let rawtx = jsonResponse.rawtx;
                let walletName = jsonResponse.walletName;
                let tx = jsonResponse.tx;
                let walletLink = `{{ url_for('wallets_endpoint.wallet', wallet_alias='WALLET_ALIAS') }}`.replace("WALLET_ALIAS", this.wallet);
                let rawtxHTML = "";
                if(tx.is_purged) {
                    rawtxHTML += `
                    <div class="warning">
                        <p><b>{{ _( "This transaction (aka \"tx\") could not be found in your node's mempool!") }}</b></p>
                        <p style="text-align:left;">{{ _( "If the bitcoin network is very busy, nodes will start purging the pending txs with the lowest fees. Txs older than two weeks are also purged.") }}</p>
                        <p style="text-align:left;">{{ _( "A purged tx will never complete. Abandoning this tx will clear it from your wallet, making those funds spendable once again.") }}</p>
                        <p style="text-align:left;">{{ _( "But first verify that other nodes have also purged your tx! Enter the tx id into a public block explorer (warning: slight privacy leak). If the tx cannot be found, it is safe to abandon this tx.") }}</p>

                        <br/><br/>
                        <form method="POST" action="${walletLink}history/">
                            <input type="hidden" class="csrf-token" name="csrf_token" value="{{ csrf_token() }}"/>
                            <input type="hidden" name="action" value="abandon_tx"/>
                            <input type="hidden" name="txid" value="${this.txid}"/>
                            <button type="submit" name="action" value="abandontx" class="btn danger centered" style="max-width: 160px;">{{ _("Abandon transaction") }}</button>
                        </form>
                    </div>
                    `;
                }
                rawtxHTML += `
                <table class="tx-data-table">
                <tbody>
                <tr><td><span class="optional">{{ _("Transaction id") }}:</span><span class="mobile-only">TxID:</span></td><td style="word-break: break-all;"><explorer-link data-type="tx" data-value="${this.txid}"></explorer-link></td></tr>
                <tr><td>From wallet:</td><td><a href=${walletLink}>${walletName}<a></td></tr>
                <tr><td>Size:</td><td>${rawtx.vsize} vbytes <span class="note">(${rawtx.size} bytes)</span></td></tr>
                `;
                if (tx.fee) {
                    let fee = tx.fee;
                    if(typeof tx.fee == "object"){
                        if("bitcoin" in tx.fee){
                            fee = tx.fee.bitcoin;
                        }
                    }
                    rawtxHTML += `
                        <tr><td>{{ _("Fee") }}:</td><td>${parseInt(-1e8 * fee)} sats</td></tr>
                        <tr><td>{{ _("Fee rate") }}:</td><td>${parseFloat((-1e8 * fee / rawtx.vsize).toFixed(2)).toString()} sat/vbyte</td></tr>
                    `;
                }
                if (tx.confirmations && tx.confirmations > 0) {
                    rawtxHTML += `
                        <tr><td>{{ _("Mined at block") }}:</td><td>${tx.blockheight}</td></tr>
                        <tr><td>{{ _("Block hash") }}:</td><td style="word-break: break-all;">${tx.blockhash}</td></tr>
                        <tr><td>{{ _("Block time") }}:</td><td>${new Date(tx.blocktime * 1000)} <span style="font-size: 0.9em;color: #ccc;">(${tx.blocktime})</span></td></tr>
                    `;
                }
                rawtxHTML += `
                    <tr><td>{{ _("Inputs count") }}:</td><td>${rawtx.vin.length}</td></tr>
                    <tr><td>{{ _("Outputs count") }}:</td><td>${rawtx.vout.length}</td></tr>
                `;
                rawtxHTML += `
                </tbody>
                </table>
                `;
                rawtxHTML += `<h3>Inputs</h3>`;
                for (let i in rawtx.vin) {
                    let bgColor = '#131a24';
                    let addressAndValue = '';
                    let jsonResponse = await this.fetchRawTx(rawtx.vin[i].txid);
                    if (jsonResponse !== null && jsonResponse.success) {
                        let spentOutput = jsonResponse.rawtx.vout[rawtx.vin[i].vout];
                        let address = (spentOutput.addresses && spentOutput.addresses.length == 1) ? spentOutput.addresses[0] : 'Unknown';
                        if (address == 'Unknown') {
                            address = (spentOutput.scriptPubKey.addresses && spentOutput.scriptPubKey.addresses.length == 1) ? spentOutput.scriptPubKey.addresses[0] : 'Unknown';
                        }
                        if (address == 'Unknown') {
                            address = spentOutput.scriptPubKey.address ? spentOutput.scriptPubKey.address : 'Unknown';
                        }
                        if (address == 'Unknown') {
                            address = spentOutput.address ? spentOutput.address : 'Unknown';
                        }
                        let isMine = await this.fetchAddressIsMine(address);
                        if (isMine) {
                            bgColor = '#925d07';
                        }


                        let value = "Confidential";
                        let price = '';
                        let assetlabel = "";
                        if("assetlabel" in spentOutput){
                            assetlabel = spentOutput.assetlabel;
                        }
                        if (spentOutput.value) {
                            value = parseFloat(spentOutput.value.toFixed(8));
                            if(assetlabel == "LBTC" || assetlabel == ""){
                                if (this.price && this.symbol) {
                                    price = `<span class="note">(${this.symbol}${numberWithCommas((parseFloat(this.price) * value).toFixed(2))})</span>`;
                                }

                                if (this.btcUnit == 'sat') {
                                    assetlabel = "sat";
                                    value = parseInt(value * 1e8);
                                }
                            }
                            value = `${numberWithCommas(value.toString())}`;
                        }

                        addressAndValue = `<br>
                            {{ _("Address:") }} <address-label data-copy-hidden="true" data-address="${address}" data-wallet="${this.wallet}"></address-label><br>
                            {{ _("Value:") }} ${value} ${assetlabel} ${price}`;
                    }

                    if ('coinbase' in rawtx.vin[i]) {
                        rawtxHTML += `
                        <p class="tx_info" style="text-align: left; background-color: ${bgColor};">
                            <b>{{ _("Input #") }}${i}</b><br><br>
                            <b>{{ _("Coinbase transaction") }}</b>
                            <br>
                        </p>
                        `;
                        continue;
                    }
                    rawtxHTML += `
                        <p class="tx_info" style="text-align: left; background-color: ${bgColor};">
                            <b>{{ _("Input #") }}${i}</b><br><br>
                            {{ _("Transaction id") }}: <explorer-link style="word-break: break-all;" data-type="tx" data-value="${rawtx.vin[i].txid}"></explorer-link><br>
                            {{ _("Output #") }}" ${rawtx.vin[i].vout}
                            ${addressAndValue}
                        </p>
                    `;
                }

                rawtxHTML += `<h3>{{ _("Outputs") }}</h3>`;
                for (let i in rawtx.vout) {
                    let address = rawtx.vout[i].addresses && rawtx.vout[i].addresses.length == 1 ? rawtx.vout[i].addresses[0] : 'Unknown';
                    if (address == 'Unknown') {
                        address = rawtx.vout[i].scriptPubKey.addresses && rawtx.vout[i].scriptPubKey.addresses.length == 1 ? rawtx.vout[i].scriptPubKey.addresses[0] : 'Unknown';
                    
                    }
                    if (address == 'Unknown') {
                        address = rawtx.vout[i].scriptPubKey.address ? rawtx.vout[i].scriptPubKey.address : 'Unknown';
                    }
                    if (address == 'Unknown') {
                        address = rawtx.vout[i].address ? rawtx.vout[i].address : 'Unknown';
                    }
                    let value = "Confidential";
                    let price = '';
                    let assetlabel = "";
                    if("assetlabel" in rawtx.vout[i]){
                        assetlabel = rawtx.vout[i].assetlabel;
                    }
                    if (rawtx.vout[i].value) {
                        value = parseFloat(rawtx.vout[i].value.toFixed(8));
                        if(assetlabel == "LBTC" || assetlabel == ""){
                            if (this.price && this.symbol) {
                                price = `<span class="note">(${this.symbol}${numberWithCommas((parseFloat(this.price) * value).toFixed(2))})</span>`;
                            }

                            if (this.btcUnit == 'sat') {
                                assetlabel = "sat";
                                value = parseInt(value * 1e8)
                            }
                        }
                        value = `${numberWithCommas(value.toString())}`;
                    }

                    let bgColor = '#131a24';
                    let isMine = await this.fetchAddressIsMine(address);
                    if (isMine) {
                        bgColor = '#154984';
                    }

                    rawtxHTML += `
                    <p class="tx_info" style="text-align: left; background-color: ${bgColor};">
                        <b>{{ _("Output #${i}") }}</b><br><br>
                        {{ _("Address:") }} <address-label data-copy-hidden="true" data-address="${address}" data-wallet="${this.wallet}"></address-label><br>
                        {{ _("Value:") }} ${value} ${assetlabel} ${price}
                    </p>
                    `;
                }
                
                this.info.innerHTML = rawtxHTML;
                this.note.innerText = "";
                return;
            };
            this.note.innerText = '{{ _("Failed to load transaction details...") }}';
        }
        
        async fetchAddressIsMine(address) {
            let url = `{{ url_for('wallets_endpoint.addressinfo', wallet_alias='WALLET_ALIAS') }}`.replace("WALLET_ALIAS", this.wallet);
            var formData = new FormData();
            formData.append('address', address)
            formData.append('csrf_token', '{{ csrf_token() }}');
            try {
                const response = await fetch(
                    url,
                    {
                        method: 'POST',
                        body: formData
                    }
                );
                if(response.status != 200){
                    showError(await response.text());
                    return false;
                }
                const jsonResponse = await response.json();
                if (jsonResponse.success) {
                    return jsonResponse.isMine;
                }
            }  catch(e) {
                showError(`{{ _("Failed to load address data...") }}`);
                showError(e);
            }
            return false;
        }
    }
    customElements.define('tx-data', TxDataElement);
</script>
