
<template>
  <row-bar :color="color">
    <color-band :color="color"/>
    <div :style="faintColorStyle" style="width: 100%" class="justify-start align-content-start">
      <v-text-field type="number" inputmode="numeric" pattern="[0-9]*\.?[0-9]*" v-model="order.amount" variant="outlined"
                    density="compact"
                    :hint="available" :persistent-hint="true"
                    min="0"
                    class="amount py-2" :color="color"
                    :label="order.amountIsTokenA ? 'Amount':('Value in '+co.selectedSymbol.quote.s)"
      >
        <template #prepend>
          <v-btn variant="outlined" :color="color" class="ml-3"
              :text="(order.buy ? 'Buy ' : 'Sell ') + co.selectedSymbol.base.s"
              @click="order.buy=!order.buy"/>
        </template>
        <template #prepend-inner>
          <v-btn variant="text" text="max" class="px-0" size="small"
                 :disabled="!maxAmount || order.amountIsTokenA===order.buy && !co.price" @click="setMax"/>
        </template>
        <template #append-inner>
          <v-btn :text="order.amountIsTokenA?co.baseToken.s:co.quoteToken.s+' worth'"
                 :color="color" variant="text" @click="toggleAmountToken"/>
        </template>
      </v-text-field>
      <template v-for="b in builders">
        <builder-factory :order="order" :builder="b"/>
      </template>
      <div class="my-3">
        <div v-if="order.builders.length===0">  <!--todo remove gralpha limitation of one builder-->
          <span :style="colorStyle" class="ma-3">Add condition:</span>
          <v-btn :color="color" variant="text" prepend-icon="mdi-clock-outline" @click="build(order,'DCABuilder')">DCA</v-btn>
          <v-btn :color="color" variant="text" prepend-icon="mdi-ray-vertex" @click="build(order,'LimitBuilder')">Limit</v-btn>
          <v-btn :color="color" variant="text" prepend-icon="mdi-vector-line" @click="build(order,'DiagonalBuilder')">Diagonal</v-btn>
<!--
          <v-tooltip text="Coming Soon!" location="top">
            <template v-slot:activator="{ props }">
              <span v-bind="props">
                <v-btn :color="color" variant="text" prepend-icon="mdi-information-outline">New Thing!</v-btn>
              </span>
            </template>
          </v-tooltip>
-->
          <!-- mdi-ray-start-end mdi-vector-polyline -->
        </div>
      </div>
    </div>
  </row-bar>
</template>

<script setup>

import BuilderFactory from "@/components/chart/BuilderFactory.vue";
import {builderFuncs, newBuilder, orderFuncs, useChartOrderStore} from "@/orderbuild.js";
import {useOrderStore, useStore} from "@/store/store.js";
import {computed, onUnmounted, onUpdated, ref, watchEffect} from "vue";
import {lightenColor, lightenColor2} from "@/misc.js";
import {useTheme} from "vuetify";
import RowBar from "@/components/chart/RowBar.vue";
import ColorBand from "@/components/chart/ColorBand.vue";
import Color from "color";
import {Exchange, newOrder} from "@/blockchain/orderlib.js";

const props = defineProps(['order'])
const s = useStore()
const co = useChartOrderStore()
const os = useOrderStore()

const marketBuilder = newBuilder('MarketBuilder')

const builders = computed(()=>props.order.builders.length > 0 ? props.order.builders : [marketBuilder])
const tokenIn = computed(()=>props.order.buy ? co.quoteToken : co.baseToken)
const tokenOut = computed(()=>props.order.buy ? co.baseToken : co.quoteToken)


console.log('order', props.order)
function build(order, component, options={}) {
  order.builders.push(newBuilder(component, options))
}


// check order validity
watchEffect(()=>{
  let valid = props.order.amount > 0
  if (valid) {
    for (const builder of builders.value) {
      if (!builder.valid) {
          valid = false
          break
      }
    }
  }
  props.order.valid = valid
})


function buildOrder() {
  const order = props.order
  console.log('buildOrder', order)

  if (!order.amount) return null

  // struct SwapOrder {
  //     address tokenIn;
  //     address tokenOut;
  //     Route route;
  //     uint256 amount;
  //     uint256 minFillAmount;  // if a tranche has less than this amount available to fill, it is considered completed
  //     bool amountIsInput;
  //     bool outputDirectlyToOwner;
  //     uint64 chainOrder; // use NO_CHAIN for no chaining. chainOrder index must be < than this order's index for safety (written first) and chainOrder state must be Template
  //     Tranche[] tranches;
  // }
  const symbol = co.selectedSymbol
  const fee = co.selectedPool[1]
  const amountDec = order.amountIsTokenA ? symbol.base.d : symbol.quote.d
  const amount = BigInt(Math.trunc(order.amount * 10 ** amountDec))
  const amountIsInput = !!(order.amountIsTokenA ^ order.buy)

  let tranches = []
  for (const builder of builders.value) {
    console.log('builder', builder)
    const ts = builderFuncs[builder.id]()
    console.log('tranches', ts)
    tranches = [...tranches, ...ts]
  }

  return newOrder(tokenIn.value.a, tokenOut.value.a, Exchange.UniswapV3, fee, amount, amountIsInput, tranches)
}


let lastId = props.order.id
orderFuncs[lastId] = buildOrder
onUpdated(()=>{
  console.log('onUpdated', lastId, ...arguments)
  delete orderFuncs[lastId]
  orderFuncs[props.order.id] = buildOrder
  lastId = props.order.id
})
onUnmounted(() => delete orderFuncs[lastId])


const theme = useTheme().current
const color = computed(()=>new Color(props.order.buy?theme.value.colors.success:theme.value.colors.error).darken(0.2).string())
const lightColor = computed(() => lightenColor(color.value))
const faintColor = computed(() => lightenColor2(color.value))
const colorStyle = computed(() => { return {'color': color.value} })
const bgColorStyle = computed(() => { return {'background-color': color.value} })
const lightColorStyle = computed(() => { return {'background-color': lightColor.value} })
const faintColorStyle = computed(() => { return {'background-color': faintColor.value} })

const inToken = computed( ()=>props.order.buy ? co.quoteToken : co.baseToken )
const maxAmount = computed(()=>{
  const token = inToken.value;
  if (!token)
    return null
  const balance = s.balances[token.a]
  if( !balance )
    return 0
  const divisor = os.amountIsTotal ? 1 : os.tranches
  return balance / 10**token.d / divisor
})
const available = computed(()=>{
  const max = maxAmount.value
  return max === null ? '' : `Available: ${maxAmount.value} ${tokenIn.value.s}`
})

const lastMaxValue = ref(null)

function setMax() {
  let amount = maxAmount.value
  if (amount) {
    const order = props.order
    const price = co.price
    if (order.amountIsTokenA===order.buy) {
      if (order.buy)
        amount /= price
      else
        amount *= price
    }
    amount = Number(amount.toPrecision(7))
    lastMaxValue.value = amount
    order.amount = amount
  }
}

function toggleAmountToken() {
  const order = props.order
  order.amountIsTokenA=!order.amountIsTokenA
  if (order.amount === lastMaxValue.value)
    setMax()
}

</script>

<style scoped lang="scss">
.amount {
  max-width: 30em;
  div.v-field {
    padding-left: 0;
  }
}
</style>
