<template>
  <div>
    <v-data-table :headers="datatableHeaders" :items="orders" item-value="index"
                  item-selectable="selectable" :show-select="false" :show-expand="true">
      <template v-slot:item.start="{ value }">{{ dateString(value) }}</template>
      <template v-slot:item.input="{ item }">
        <suspense v-if="item.order.amountIsInput">
          <span>
            <token-amount :addr="item.order.tokenIn" :amount="item.filled" :raw="true"/>
            /
            <token-amount :addr="item.order.tokenIn" :amount="item.order.amount"/>
          </span>
        </suspense>
        <suspense v-if="!item.order.amountIsInput">
          <token-symbol :addr="item.order.tokenIn"/>
        </suspense>
      </template>
      <template v-slot:item.output="{ item }">
        <suspense v-if="!item.order.amountIsInput">
          <span>
            <token-amount :addr="item.order.tokenOut" :amount="item.filled" :raw="true"/>
            /
            <token-amount :addr="item.order.tokenOut" :amount="item.order.amount"/>
          </span>
        </suspense>
        <suspense v-if="item.order.amountIsInput">
          <token-symbol :addr="item.order.tokenOut"/>
        </suspense>
      </template>
<!--
      <template v-slot:item.remaining="{ item }">
        <suspense>
          <token-amount :addr="item.amountToken" :amount="item.remaining"/>
        </suspense>
      </template>
      <template v-slot:item.filled="{ item }">
        <suspense>
          <token-amount :addr="item.amountToken" :amount="item.filled"/>
        </suspense>
      </template>
-->
      <template v-slot:item.avg="{ item }">
        <pair-price :base-addr="item.order.tokenIn" :quote-addr="item.order.tokenOut" :value="item.avg" :show-btn="true"/>
      </template>
      <template v-slot:item.status="{ item }">
        <v-chip v-if="item.state===PendingOrderState.Submitted || item.state===PendingOrderState.Signing"
                prepend-icon="mdi-signature">Wallet Signing</v-chip>
        <v-chip v-if="item.state===PendingOrderState.Rejected" prepend-icon="mdi-cancel">Rejected</v-chip>
        <v-chip v-if="item.state===PendingOrderState.Sent" prepend-icon="mdi-send">Sent</v-chip>
        <v-chip v-if="item.state===OrderState.Open" class="d-none d-lg-inline-flex" prepend-icon="mdi-dots-horizontal"
                color="green">Open
        </v-chip>
        <btn v-if="isOpen(item.state)" class="d-none d-sm-inline-flex" icon="mdi-cancel" color="red"
             @click="cancelOrder(vaultAddr,item.index)">Cancel
        </btn>
        <btn v-if="isOpen(item.state)" class="d-sm-none" variant="plain" icon="mdi-cancel" color="red"
             @click="cancelOrder(vaultAddr,item.index)"/>
        <v-chip v-if="item.state===OrderState.Canceled" prepend-icon="mdi-cancel" color="red">Canceled</v-chip>
        <v-chip v-if="item.state===OrderState.Filled" prepend-icon="mdi-check-circle-outline" color="green">Completed
        </v-chip>
        <v-chip v-if="item.state===OrderState.Expired" prepend-icon="mdi-progress-check" color="grey-darken-1">Expired
        </v-chip>
        <v-chip v-if="item.state===OrderState.Underfunded" prepend-icon="mdi-alert" color="warning">Underfunded</v-chip>
      </template>
<!--      <template v-slot:item.action="{item}">-->
<!--        <btn v-if="item.state===OrderState.Open" icon="mdi-cancel" color="red"-->
<!--             @click="cancelOrder(vaultAddr,item.index)">Cancel-->
<!--        </btn>-->
<!--      </template>-->
      <template v-slot:expanded-row="{item}">
        <tr>
          <td>&nbsp;</td>
          <td colspan="100">
            <v-table>
              <!--
                          <thead>
                          <tr>
                            <th></th>
                            <th>Filled</th>
                            <th></th>
                          </tr>
                          </thead>
              -->
              <tbody>
              <tr v-for="(t, i) in item.order.tranches">
                <td class="text-right">Tranche {{ i + 1 }}</td>
                <td class="text-center w-33">
                  <suspense v-if="item.state > OrderState.Signing">
                    <span>
                      <token-amount :addr="item.amountToken" :amount="item.trancheFilled[i]" :raw="true"/>
                      /
                    </span>
                  </suspense>
                  <suspense>
                    <span>
                      <token-amount :addr="item.amountToken" :amount="item.order.amount*BigInt(t.fraction)/65535n"/>
                    </span>
                  </suspense>
                </td>
                <td class="text-left">
                  <span class="mx-3">{{ describeTrancheTime(item, true, t) }}</span>
                  <span class="mx-3">{{ describeTrancheTime(item, false, t) }}</span>
                  <span class="mx-3">{{ describeTrancheLine(item, true, t.minIntercept, t.minSlope) }}</span>
                  <span class="mx-3">{{ describeTrancheLine(item, false, t.maxIntercept, t.maxSlope) }}</span>
                </td>
              </tr>
              </tbody>
            </v-table>
          </td>
        </tr>
      </template>
    </v-data-table>
    <btn icon="mdi-delete-alert" color="red" class="mx-3 mb-3" @click="cancelAll(vaultAddr)">Cancel All Orders</btn>
  </div>
</template>

<script setup>
import {FixedNumber} from "ethers";
import {useStore} from "@/store/store";
import {computed, defineAsyncComponent, ref} from "vue";
import Btn from "@/components/Btn.vue"
import {cancelAll, cancelOrder, PendingOrderState, useWalletStore} from "@/blockchain/wallet.js";
import {dateString, pairPriceAddr} from "@/misc.js";
import {isOpen, OrderState} from "@/blockchain/orderlib.js";
import NewOrder from "@/components/NewOrder.vue";
import PairPrice from "@/components/PairPrice.vue";

const TokenAmount = defineAsyncComponent(()=>import('./TokenAmount.vue'))
const TokenSymbol = defineAsyncComponent(()=>import('./TokenSymbol.vue'))

const s = useStore()
const ws = useWalletStore()
const props = defineProps(['vault'])
const vaultAddr = computed(()=>props.vault?props.vault:s.vault)
const inverted = ref({})


// <thead>
// <tr>
//   <th className="num d-none d-md-table-cell">Date</th>
//   <th className="token d-none d-sm-table-cell">Input</th>
//   <th className="token d-none d-sm-table-cell">Output</th>
//   <th className="amount">Remaining</th>
//   <th className="amount">Filled</th>
//   <th className="amount d-none d-md-table-cell">Avg&nbsp;Price</th>
//   <th className="status">Status</th>
//   <th className="cancel d-none d-lg-table-cell">&nbsp;</th>
// </tr>
// </thead>
const datatableHeaders = [
  {title: 'Date', align: 'start', key: 'start'},
  {title: 'Input', align: 'end', key: 'input'},
  {title: 'Output', align: 'end', key: 'output'},
  // {title: 'Remaining', align: 'end', key: 'remaining'},
  // {title: 'Filled', align: 'end', key: 'filled'},
  {title: 'Avg Price', align: 'end', key: 'avg'},
  {title: 'Status', align: 'end', key: 'status'},
  // {title: '', align: 'end', key: 'action'},
];

const orders = computed(()=>{
  // example twap
  // status = [
  //   [ order
  //     "0x52412507302F6bAB17f56370b6a8F304CbB30Ce1", in token
  //     "0x63e187162a4c33A4D14465eA3859fFe423647710", out token
  //     [1, 500], route
  //     "100000000", amount
  //     "1000000", min amount
  //     false, amount is input
  //     false, output to owner
  //     18446744073709552000,  chain order
  //     [ tranches
  //       [21845,    fraction
  //       true,      start time relative
  //       true,      end time relative
  //       false,     min is barrier
  //       false,     max is barrier
  //       false,     market order
  //       false,     reserved
  //       false,     reserved
  //       false,     reserved
  //       0,         reserved
  //       0,         reserved
  //       0,         start time
  //       20,        end time
  //       730643660, min intercept
  //       0,         min slope
  //       0,         max intercept
  //       0          max slope
  //       ],
  //       [...],
  //       [...],
  //     ]
  //   ],
  //   4,                state
  //   1701809053,       started at
  //   null,             oco group
  //   "0",              filled in
  //   "0",              filled out
  //   ["0", "0", "0"],  tranche filled in
  //   ["0", "0", "0"]   tranche filled out
  // ]
  const result = []

  // in-flight orders
  for (const pend of ws.pendingOrders) {
    console.log('pended order', pend)
    result.push({
      start: pend.placementTime,
      order: pend.order,
      filled: 0,
      state: pend.state,
      amountToken: pend.order.amountIsInput ? pend.order.tokenIn : pend.order.tokenOut
    })
  }

  // historical orders
  if( vaultAddr.value in s.orders ) {
    for (const [index, status] of Object.entries(s.orders[vaultAddr.value]).reverse()) {
      const st = {...status}
      const o = {...st.order}
      st.order = o
      console.log('order status', st)
      result.push(st)
      st.index = parseInt(index)
      o.tranches = o.tranches.map((tranche)=>{
        const t = {...tranche}
        // t.startTime = t.startTimeIsRelative ? intervalString(t.startTime) : dateString(t.startTime)
        // t.endTime = t.endTimeIsRelative ? intervalString(t.endTime) : dateString(t.endTime)
        return t
      })
      const fmtX18 = {decimals: 18, width: 256, signed: false};
      st.filled = o.amountIsInput ? st.filledIn : st.filledOut
      if(BigInt(st.filled) === 0n)
        st.avg = null
      else {
        st.avg = FixedNumber.fromValue(status.filledOut, 0, fmtX18)
            .div(FixedNumber.fromValue(status.filledIn, 0, fmtX18)).toUnsafeFloat();
        if( o.tokenIn > o.tokenOut )
          st.avg = 1/st.avg
      }
      st.trancheFilled = o.amountIsInput ? st.trancheFilledIn : st.trancheFilledOut
      st.amountToken = o.amountIsInput ? o.tokenIn : o.tokenOut
      st.input = o.amountIsInput ? o.amount : 0
      st.output = !o.amountIsInput ? o.amount : 0
      st.remaining = o.amount - st.filled
      st.selectable = st.state===OrderState.Open
      st.status = st.state
    }
  }
  console.log('orders', result)
  return result
})

function describeTrancheTime(st, isStart, t) {
  let result = ''
  if( t.minIsBarrier || t.maxIsBarrier )
    return 'barrier'
  if( isStart && t.startTime > 0 ) {
    const started = t.startTimeIsRelative ? st.start + t.startTime : t.startTime
    result += started*1000 < Date.now() ? 'Activated ' : 'Activates '
    result += dateString(started) + ' '
  }
  if( !isStart && t.endTime < 4294967295 ) {
    const ended = t.endTimeIsRelative ? st.start + t.endTime : t.endTime
    result += ended*1000 < Date.now() ? 'Expired ' : 'Expires '
    result += dateString(ended)
  }
  return result
}

function describeTrancheLine(st, isMin, b, m) {
  // todo make this a PairPrice
  if( b===0 && m===0 ) return ''
  const chainId = useStore().chainId
  console.log('tranche line', isMin, b, m)
  const inverted = st.order.tokenIn > st.order.tokenOut
  const t0 = inverted ? st.order.tokenIn : st.order.tokenOut
  const t1 = !inverted ? st.order.tokenIn : st.order.tokenOut
  if( m !== 0 ) {
    const limit = b + m * s.clock
    const price = pairPriceAddr(chainId, t0, t1, limit);
    return 'diagonal ' + (price === null ? null : price.toPrecision(5))
  }
  const price = pairPriceAddr(chainId, t0, t1, b)
  return (isMin === st.order.amountIsInput ? 'dont-chase ' : 'limit ') + (price === null ? null : price.toPrecision(5))
}

</script>

<style scoped lang="scss">
@use "src/styles/vars" as *;

// columns
.num {
  min-width: 1em;
}
.token {
  min-width: 3em;
  max-width: 5em;
}
.pair {
  min-width: 5em;
}
.amount {
  min-width: 3em;
  max-width: 6em;
  overflow-x: hidden;
  text-overflow: ellipsis;
}
.status {
  max-width: 8em;
}
.cancel {
}

</style>
