<template>
    <div class="container">
        <div class="banner-top">
            <img src="@/assets/images/bg.png" alt="">
        </div>
        <div class="cannect-wallet" v-if="walletConnected">{{$hideMoreText(currentWalletAddress, 7, 0)}}</div>
        <div class="cannect-wallet pointer" v-else @click="toCannectWallet">{{$t('connectWallet')}}</div>
        <div class="redemption-wrap">
            <div class="redemption-window hold">
                <div class="redemption-tit">
                    <div class="redemption-name">{{holdItem.name}}</div>
                    <div class="redemption-over">{{$t('balance')}}：{{$toRegularNumber(balance)}}</div>
                </div>
                <div class="redemption-money">
                    <div class="token-name pointer" @click="changeToken('holdItem', holdItem.chainName)">
                        <img :src="holdItem.coinData.url || require(`@/assets/images/logo.png`)" alt="">
                        <span>{{holdItem.coinData.name}}</span>
                    </div>
                    <input type="text" :placeholder="$t('placeholder1')" v-positiveInt class="number-input">
                </div>
            </div>
            <div class="change-img pointer">
                <img src="@/assets/images/exchange.png" alt="">
                <div @click="exchange"></div>
            </div>
            <div class="redemption-window exchange">
                <div class="redemption-tit">
                    <div class="redemption-name">{{exchangeItem.name}}</div>
                    <div class="redemption-over">{{$t('expectedGet')}}</div>
                </div>
                <div class="redemption-money">
                    <div class="token-name pointer" @click="changeToken('exchangeItem', exchangeItem.chainName)">
                        <img :src="exchangeItem.coinData.url || require(`@/assets/images/logo.png`)" alt="">
                        <span>{{exchangeItem.coinData.name}}</span>
                    </div>
                    <div class="number">{{obtain}}</div>
                </div>
            </div>
            <div class="handling-fee">{{$t('handlingFee')}}<span>0.3%</span></div>
        </div>
        <div class="convert-btn pointer" @click="transfer">{{$t('transfer')}}</div>
        <EDialog :title="$t('chooseToken')" :visible="dialogVisible" @close="dialogVisible = false" v-if="dialogVisible">
            <ul class="select-list">
                <li class="select-item" v-for="(item, index) in tokenList" :key="index" @click="changeSelect(index,item)" :class="selectIndex === index ? 'active' : ''">
                    <div class="item-left">
                        <img :src="item.url || require(`@/assets/images/logo.png`)" alt="">
                        <span class="item-name">{{item.name}}</span>
                    </div>
                    <img v-if="selectIndex === index" src="../../assets/images/select.png" alt="">
                </li>
            </ul>
        </EDialog>
        <van-loading class="loading-bg" type="spinner" color="#303030" size="24px" v-show="pageLoading" />
    </div>
</template>

<script>
import {
    desc,
    MINTER_ROLE,
    expandTo18Decimals,
    BN,
    getHash,
    gasLeft,
} from "@/utils/constant";
import { BigNumber } from 'bignumber.js'
import * as metaMask from '@/api/demoMETAMASK';
import EDialog from '@/components/EDialog.vue';
import { createNamespacedHelpers } from 'vuex';
import { getTokenList } from '@/utils/data/tokenList'
import { connectWallet } from '@/service/loginService'

const { mapState: mapStateWallet } = createNamespacedHelpers('wallet');
const { mapState: mapStateNetwork } = createNamespacedHelpers('network');

const erc20Abi = require('../../abi/ERC20.json');
const bridgeAbi = require('../../abi/bridge.json');
const bridgeContractAddress = '0x35645227C22c47Fe26953F14C8210b8Eb347CCd2';
let bridge;

export default {
    data() {
        return {
            dialogVisible: false,
            pageLoading: false,
            tokenList: [],
            tokenListOrigin: [],
            tokenListTKM: [],
            tokenListBSC: [],
            selectIndex: '',
            holdItem: {
                name: 'THINKIUM',
                chainName: 'thk',
                coinData: {},
            },
            exchangeItem: {
                name: 'BSC',
                chainName: 'bsc',
                coinData: {},
            },
            changeItem: '',
            inputValue: '',
            rbalance: 1,
        }
    },
    computed: {
        ...mapStateWallet(['currentWalletAddress']),
        ...mapStateNetwork(['chainId']),
        walletConnected() {
            return this.$store.getters.walletConnected;
        },
        obtain() {
            return this.inputValue * 0.997;
        },
        currentWalletAddressAndChainId() {
            return this.currentWalletAddress && this.chainId
        },
    },
    asyncComputed: {
        balance: {
            get() {
                const { coinData } = this.holdItem;
                if (!this.walletConnected) {
                    return 0;
                }
                if (coinData.chainId != this.chainId) {
                    this.networkAlert();
                    return 0;
                }
                if (!this.rbalance) {

                }
                if (coinData.type == 'main') {
                    return this.getAccountBalance().then(res => res);
                } else if (coinData.type == 'erc20') {
                    return this.getTokenBalance({ contractAddress: coinData.contractAddress }).then(res => res);;
                }
            }
        }
    },
    components: {
        EDialog
    },
    methods: {
        async init() {
            this.tokenListOrigin = getTokenList(this.chainId);
            this.tokenListTKM = this.getTokensByChainName('thk') || [];
            this.tokenListBSC = this.getTokensByChainName('bsc') || [];

            let thk = {
                name: 'THINKIUM',
                chainName: 'thk',
                coinData: {},
            }
            let bsc = {
                name: 'BSC',
                chainName: 'bsc',
                coinData: {},
            }
            if (this.tokenListBSC.map(item => item.chainId).includes(this.chainId)) {
                this.holdItem = bsc;
                this.exchangeItem = thk;
            } else {
                this.holdItem = thk;
                this.exchangeItem = bsc;
            }
            this.changeItem = 'holdItem';
            let token = this.tokenListOrigin.find(item => item.chainId == this.chainId && item.chainName == this.holdItem.chainName);
            if (!token) {
                token = this.getTokensByChainName(this.holdItem.chainName)[0]
            }
            console.log('----123', token);
            this.changeSelect(0, token)


            if (!this.walletConnected) {
                return;
            }
            let overrides = {
                gasLimit: 300000,
                from: window.defaultAccount,
                // gasLimit: 1000000,
                value: '0x0'
            }
            bridge = new window.web3.eth.Contract(bridgeAbi, bridgeContractAddress, overrides);
        },
        refreshBalance() {
            this.rbalance++
        },
        formateChainName(chainId) {
            let tkmChainIds = this.tokenListTKM.map(item => item.chainId);
            let bscChainIds = this.tokenListBSC.map(item => item.chainId);

            if (tkmChainIds.includes(chainId - 0)) {
                return `Thinkium ${chainId}#${this.$t('chain')}`
            } else if (bscChainIds.includes(chainId - 0)) {
                return `BSC`
            } else {
                return chainId
            }
        },
        networkAlert() {
            let fromChainName = this.formateChainName(this.holdItem.coinData.chainId);
            let toChainName = this.formateChainName(this.exchangeItem.coinData.chainId);
            // let currentChainName = this.formateChainName(this.chainId);
            this.$dialog.alert({
                title: this.$t('title'),
                message: this.$t('placeholder4', { fromChainName, toChainName, fromChainName, fromChainName }),
                confirmButtonText: this.$t('confirm')
            }).then(() => {
                // on close
            });
            return 0;
        },
        async getAccountBalance() {
            return metaMask.getBalance(window.defaultAccount);
        },
        async getTokenBalance({ address = window.defaultAccount, contractAddress }) {
            let overrides = {
                gasLimit: 6000000,
                from: address,
                value: '0x0'
            }
            const erc20 = new window.web3.eth.Contract(erc20Abi, contractAddress, overrides);
            return await erc20.methods.balanceOf(address).call();
        },
        changeSelect(index, item) {
            this.selectIndex = index;
            this[this.changeItem].coinData = item;

            let chainName = this[this.changeItem].chainName;
            let tokenList, anotherToken;
            if (chainName == 'thk') {
                tokenList = this.tokenListBSC;
            } else if (chainName == 'bsc') {
                tokenList = this.tokenListTKM;
            }
            anotherToken = tokenList.find(token => token.index == item.index); // 寻找 index 相同的 token;
            if (this.changeItem == 'holdItem') {
                this['exchangeItem'].coinData = anotherToken;
            } else {
                this['holdItem'].coinData = anotherToken;
            }
            setTimeout(() => {
                this.dialogVisible = false
            }, 500)
        },
        getTokensByChainName(chainName) {
            return this.tokenListOrigin.filter(item => item.chainName == chainName);
        },
        exchange() {
            let temp = { ...this.exchangeItem }
            this.exchangeItem = this.holdItem
            this.holdItem = temp;
        },
        changeToken(type, chainName) {
            this.tokenList = this.getTokensByChainName(chainName);
            this.dialogVisible = true
            this.changeItem = type;
        },
        async transfer() {
            const { inputValue, holdItem, exchangeItem } = this;
            const value = (inputValue + '').trim() - 0;
            if (!this.walletConnected) {
                this.$dialog.alert({
                    title: this.$t('title'),
                    message: this.$t('pleaseLinkTheWallet'),
                    confirmButtonText: this.$t('OK')
                }).then(() => {
                     connectWallet()
                })
                return;
            }
            if (holdItem.coinData.chainId != this.chainId) {
                this.networkAlert();
                return;
            }
            if (!value) {
                this.$dialog.alert({
                    title: this.$t('title'),
                    message: this.$t('placeholder2'),
                    confirmButtonText: this.$t('confirm')
                }).then(() => {
                    // on close
                });
                return;
            }
            let holdName = this.holdItem.coinData.name
            let isTKM = holdName == 'TKM' || holdName == 'BTKM' || holdName == 'TKM3' || holdName == 'BTKM3'
            let minNum = 0
            if (isTKM && value < 1000) {
                minNum = 1000
                this.$dialog.alert({
                    title: this.$t('title'),
                    message: this.$t('placeholder3', { minNum }),
                    confirmButtonText: this.$t('confirm')
                }).then(() => {
                    // on close
                });
                return;
            } else if (!isTKM && value < 200) {
                minNum = 200
                this.$dialog.alert({
                    title: this.$t('title'),
                    message: this.$t('placeholder3', { minNum }),
                    confirmButtonText: this.$t('confirm')
                }).then(() => {
                    // on close
                });
                return;
            }
            this.pageLoading = true;
            try {
                if (holdItem.coinData.type == 'main') {
                    await this.depositNative({
                        chain: exchangeItem.coinData.chainId + '',
                        value: this.$toBig(value)
                    });
                } else {
                    await this.depositToken({
                        chain: exchangeItem.coinData.chainId + '',
                        value: this.$toBig(value),
                        tokenAddress: holdItem.coinData.contractAddress,
                    });
                }
                this.$notify({ type: 'success', message: this.$t('successfulTransfer') });
                this.refreshBalance();

            } catch (err) {
                this.$notify({ type: 'warning', message: this.$t('failedTransfer') });

            }
            this.pageLoading = false;
        },
        async depositNative({ address = window.defaultAccount, chain, value }) {
            let params = [
                address,
                chain,
            ]
            let overrides = {
                value,
            }
            await bridge.methods.depositNative(...params).send(overrides)
        },
        async depositToken({ value, tokenAddress, address = window.defaultAccount, chain }) {
            let token = '';
            await this.approve({
                value,
                contractAddress: tokenAddress,
                spender: bridgeContractAddress,
            })
            let params = [
                tokenAddress,
                value,
                address,
                chain
            ]
            await bridge.methods.depositToken(...params).send();
        },
        async approve({ value, contractAddress, owner = window.defaultAccount, spender }) {
            console.log({ value, contractAddress, owner, spender });
            let overrides = {
                gasLimit: 6000000,
                from: owner,
                value: '0x0'
            }
            let erc20 = new window.web3.eth.Contract(erc20Abi, contractAddress, overrides);
            // let allowance = await erc20.methods.allowance(owner, spender).call()
            let approveResult = await erc20.methods.approve(spender, value).send({
                value: '0x0',
            });

        },
        toCannectWallet() {
            connectWallet()
        }
    },
    directives: {
        positiveInt: {
            bind: function(el, binding, vnode) {
                el.handler = function() {
                    let that = vnode.context
                    el.value = Number(el.value.replace(/\D+/, '')) || ''
                    that.inputValue = el.value - 0 || '';
                }
                el.addEventListener('input', el.handler)
            },
            unbind: function(el) {
                el.removeEventListener('input', el.handler)
            }
        }
    },
    created() {
        this.init();
    },
    watch: {
        currentWalletAddressAndChainId() {
            this.init();
        },
    },

}
</script>

<style scoped lang="scss">
.container {
    width: 100%;
    height: 100%;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    background: #FFF;
    .banner-top {
        height: 3.0rem;
        img {
            width: 7.5rem;
            height: 3.0rem;
        }
    }
    .cannect-wallet {
        margin: 0.47rem 0 0.18rem auto;
        width: 2.00rem;
        height: 0.60rem;
        background: rgba(252, 191, 25, 0.2);
        border-radius: 0.30rem 0rem 0rem 0.30rem;
        font-size: 0.26rem;
        line-height: 0.60rem;
        color: #FCBF19;
        text-align: center;
    }
    .redemption-wrap {
        position: relative; // flex: 1;
        .redemption-window {
            height: 2.2rem;
            background: #F7F7F7;
            margin-bottom: 0.3rem;
            .redemption-tit {
                display: flex;
                justify-content: space-between;
                height: 0.58rem;
                line-height: 0.58rem;
                border-bottom: 0.01rem solid #DDDDDD;
                .redemption-name {
                    font-size: 0.3rem;
                    color: #333333;
                    font-weight: bold;
                }
                .redemption-over {
                    font-size: 0.3rem;
                    color: #555555;
                }
            }
            .redemption-money {
                display: flex;
                justify-content: space-between;
                margin-top: 0.27rem;
                height: 0.46rem;
                line-height: 0.46rem;
                .token-name {
                    height: 0.46rem;
                    font-size: 0.3rem;
                    color: #666666;
                    display: flex;
                    img {
                        width: 0.46rem;
                        height: 0.46rem;
                        margin-right: 0.1rem;
                    }
                    span {
                        display: inline-block;
                        line-height: 0.46rem;
                    }
                }
                input {
                    background-color: #F7F7F7;
                    min-width: 3.72rem;
                    height: 0.46rem;
                    color: #333;
                    font-size: 0.3rem;
                    text-align: right;
                } // input[placeholder] {
                //     color: #CCCCCC;
                //     font-size: 0.3rem;
                //     text-align: right;
                // }
                .number {
                    color: #333333;
                    font-size: 0.3rem;
                }
            }
        }
        .hold {
            padding: 0.34rem 0.59rem 0 0.48rem;
        }
        .exchange {
            padding: 0.53rem 0.59rem 0 0.48rem;
        }
        .change-img {
            border-radius: 50%;
            position: absolute;
            left: 50%;
            right: 50%;
            top: 1.83rem;
            margin-left: -0.6rem;
            width: 1.2rem;
            height: 1.2rem;
            img {
                width: 1.2rem;
                height: 1.2rem;
            }
            div {
                position: absolute;
                left: 0.23rem;
                top: 0.17rem;
                width: 0.73rem;
                height: 0.73rem;
                z-index: 11;
                border-radius: 50%;
            }
        }
        .handling-fee {
            padding-left: 0.48rem;
            height: 0.4rem;
            line-height: 0.4rem;
            font-size: 0.26rem;
            color: #555555;
        }
    }
    .convert-btn {
        margin-left: 0.75rem;
        margin-top: 2.3rem;
        width: 6rem;
        height: 0.8rem;
        background-color: #FCBF19;
        border-radius: 0.1rem;
        font-size: 0.32rem;
        line-height: 0.8rem;
        text-align: center;
    }
    .select-list {
        overflow: auto;
        .select-item {
            height: 1rem;
            border-top: 0.01rem solid #E8E8E8;
            display: flex;
            justify-content: space-between;
            align-items: center;
            .item-left {
                display: flex;
                align-items: center;
                margin-left: 0.66rem;
                .item-name {
                    margin-left: 0.12rem;
                    font-size: 0.3rem;
                    color: #333333;
                }
                img {
                    width: 0.5rem;
                    height: 0.5rem;
                }
            }
            &>img {
                width: 0.36rem;
                height: 0.36rem;
                margin-right: 0.31rem;
            }
        }
        .active {
            background-color: rgba($color: #FCBF19, $alpha: 0.1);
        }
    }
    .loading-bg {
        position: fixed;
        width: 100%;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
        background: rgba(0, 0, 0, 0.3);
    }
    .cannect-wallet2 {
        text-align: center;
        margin: 1rem auto;
        color: red;
        font-size: .36rem;
    }
}
</style>
