<template>
  <div>
    <div v-if="!hasVault">
      <v-card-title>
        Creating Your Dexorder Vault
        <v-icon icon="mdi-safe-square" size="small" color="grey-darken-1" style="vertical-align: baseline"/>
      </v-card-title>
      <v-card-text v-if="num!==0"><!--todo-->Multiple vaults are not yet supported</v-card-text>
      <v-card-text v-if="num===0">
        Please wait while your vault is being created. This should only take a few seconds...
      </v-card-text>
    </div>
    <div v-if="hasVault">
      <v-card-subtitle class="overflow-x-hidden">
        <copy-button :text="addr">Deposit {{addr}}</copy-button>
      </v-card-subtitle>

      <v-card-text v-if="empty">
        <!--
                <p>
                  Your vault is a smart contract that securely holds your funds plus any orders you place. When your order
                  conditions are met, Dexorder creates a blockchain transaction asking your vault to execute the order. Your
                  vault then checks that order against the current blockchain time and pool price, and only trades if
                  everything looks good.
                </p>
        -->
        <p v-if="!s.mockenv">
          There are no funds currently in your vault. Send tokens to the address above to fund your trading vault.
        </p>
        <p v-if="s.mockenv">
          There are no funds currently in your vault. Use the faucet below to mint some testnet coins.
        </p>
      </v-card-text>
      <v-card-item v-if="!empty">
        <v-table>
          <tbody>
          <native-row v-if="nativeBalance && BigInt(nativeBalance)>0n" :chain-id="s.chainId" :addr="s.vault" :amount="nativeBalance"
                      :on-withdraw="onWithdrawNative" :on-wrap="()=>wrapShow=true"/>
          <suspense v-for="(amount,addr) of balances">
            <token-row v-if="amount && BigInt(amount)>0n" :chain-id="s.chainId" :addr="addr" :amount="amount" :onWithdraw="onWithdraw"/>
          </suspense>
          </tbody>
        </v-table>
      </v-card-item>
    </div>
    <withdraw :vault="addr" :token="withdrawToken" v-model="withdrawShow"/>
    <withdraw-native :vault="addr" v-model="withdrawNativeShow" :balance="nativeBalance"/>
    <native-wrap :vault="addr" v-model="wrapShow" :max-amount="nativeBalance"/>
  </div>
<!--
    <div>
      addr {{ addr }}<br/>
      empty {{ empty }}<br/>
      exists {{ exists }}<br/>
    </div>
-->
</template>

<script setup>
import {useStore} from "@/store/store.js";
import {computed, defineAsyncComponent, onUnmounted, ref, watchEffect} from "vue";
import {vaultAddress} from "@/blockchain/contract.js";
import {ensureVault} from "@/blockchain/wallet.js";
import CopyButton from "@/components/CopyButton.vue";
import Withdraw from "@/components/Withdraw.vue";
import NativeRow from "@/components/NativeRow.vue";
import NativeWrap from "@/components/NativeWrap.vue";
import WithdrawNative from "@/components/WithdrawNative.vue";
import {provider} from "@/blockchain/provider.js";

const TokenRow = defineAsyncComponent(()=>import('./TokenRow.vue'))
const s = useStore()

const props = defineProps(['owner', 'num'])
const addr = computed(()=>vaultAddress(s.factory, s.vaultInitCodeHash, props.owner, props.num))
const balances = computed(()=>{
  const bs = s.vaultBalances[addr.value]
  console.log('balances', addr.value, s.vaultBalances, bs)
  return bs || {}
})
const empty = computed(()=>{
  if(nativeBalance.value!==0n) return false
  for( const v of Object.values(balances.value) )
    if(BigInt(v)!==0n)
      return false
  return true
})
const hasVault = computed(()=>s.vault!==null)

const withdrawToken = ref(null)
const withdrawShow = ref(false)
async function onWithdraw(token) {
  console.log('withdraw', addr.value, token)
  withdrawToken.value = token
  withdrawShow.value = true
}

const withdrawNativeShow = ref(false)
async function onWithdrawNative() {
  withdrawNativeShow.value = true
}

const wrapShow = ref(false)

const nativeBalance = ref(null)

async function updateNativeBalance() {
  // unfortunately there is no better way than polling, unless we start tracking in the backend. i assume the wallets
  // cache this data anyway and are not actually polling their backends
  if (provider) {
    const s = useStore();
    const vault = s.vault;
    if (vault) {
      const balance = await provider.getBalance(vault)
      console.log('native balance', vault, balance)
      if (s.vault===vault) // could have changed during async
        nativeBalance.value = balance
      else
        console.warn('vault changed during balance update', vault, s.vault)
    }
  }
}

updateNativeBalance()
const timeout = setInterval(updateNativeBalance, 5000)
onUnmounted(()=>clearInterval(timeout))


function checkVault() {
  console.log('checkVault', props.num, s.account, s.vault)
  if(props.num===0 && s.account && !s.vault)
    ensureVault()
}

watchEffect(checkVault)
checkVault()



</script>

<style scoped lang="scss">
@use "../styles/vars" as *;
p {
  margin-top: 1.5em;
}
</style>
