<template class="d-flex align-content-center flex-column" style="height: 100%; width: 100%;">
  <rung-builder name='Dates' :order="order" :builder="builder" v-model="timeEndpoints"
                :shape="VLine"
                :mode="1" :flip="flipped" :orientation="0"
                :get-model-value="getModelValue" :set-model-value="setModelValue"
                :get-points-value="getPointsValue"
                :set-values="setValues" :set-weights="setWeights"
                :std-width="stdWidth" :build-tranches="buildTranches">

<!--
    <v-list style="background-color: inherit">
      <v-list-item v-for="t in absoluteTimes">{{t}}</v-list-item>
    </v-list>
-->

    <table>
      <tbody>
      <tr>
        <td>
          <absolute-time-entry v-model="absTimeA"/>
        </td>
        <td class="weight">{{ weights.length ? allocationTexts[0] : '' }}</td>
      </tr>
      <tr v-if="weights.length>2" v-for="i in weights.length-2" class="ml-5"> <!-- vue uses 1-based loops -->
        <td class="d-flex justify-end pr-3">{{ dateStrings[i] }}</td>
        <td class="weight">{{ allocationTexts[i] }}</td>
      </tr>
      <tr v-if="weights.length>1">
        <td>
          <absolute-time-entry v-model="absTimeB"/>
        </td>
        <td class="weight">{{ allocationTexts[weights.length-1] }}</td>
      </tr>
      </tbody>
    </table>


  </rung-builder>
</template>

<script setup>
import {builderDefaults, useChartOrderStore} from "@/orderbuild.js";
import {allocationText, VLine} from "@/charts/shape.js";
import {sideColor} from "@/misc.js";
import {useOrderStore, usePrefStore, useStore} from "@/store/store.js";
import {DEFAULT_SLIPPAGE, DISTANT_FUTURE, MAX_FRACTION, MIN_EXECUTION_TIME, newTranche} from "@/blockchain/orderlib.js";
import RungBuilder from "@/components/chart/RungBuilder.vue";
import {computed, ref, watchEffect} from "vue";
import {chart, dragging} from "@/charts/chart.js";
import AbsoluteTimeEntry from "@/components/AbsoluteTimeEntry.vue";
import {DateTime} from "luxon";

const s = useStore()
const os = useOrderStore()
const co = useChartOrderStore()
const prefs = usePrefStore()
const props = defineProps(['order', 'builder'])
const emit = defineEmits(['update:builder'])

const minWidth = computed(()=>co.intervalSecs)
const stdWidth = computed(()=>10 * minWidth.value)

function computeDefaultColor() {
  const index = props.order.builders.indexOf(props.builder)
  return sideColor(props.order.buy, index)
}

const defaultColor = computeDefaultColor()

builderDefaults(props.builder, {
  timeA: s.clock, // todo relative 0
  timeB: null,
  // relative: true, // todo
  relative: false,
  slippage: DEFAULT_SLIPPAGE,
  rungs: 1,
  balance: 0,
  color: defaultColor,
  buy: true,
})

const times = ref([])
const weights = ref([])

const amountSymbol = computed(()=>props.order.amountIsTokenA ? co.selectedSymbol.base.s : co.selectedSymbol.quote.s )
const allocationTexts = computed(()=>weights.value.map((w)=>allocationText(props.order.buy, w, w * props.order.amount, co.selectedSymbol.base.s, amountSymbol.value)))

const endTimes = computed(()=>{
  const ts = times.value
  const window = Math.max(MIN_EXECUTION_TIME, Math.floor((ts[ts.length-1]-ts[0])/props.builder.rungs))
  return ts.map((t)=>t+window)
})
const absoluteTimes = computed(()=>{
  // console.log('absoluteTimes', props.builder.relative, times.value)
  // if (!props.builder.relative)
    return times.value
  // const now = s.clock
  // return times.value.map((t)=>now+t)
})

const dateStrings = computed(()=>absoluteTimes.value.map((t)=>{
  const n = DateTime.fromSeconds(t).setZone(prefs.timezone)
  const y = n.toLocaleString({year:'numeric'})
  const m = n.toLocaleString({month:'long'})
  const d = n.toLocaleString({day:'numeric'})
  const h = n.toLocaleString({hour:'numeric', minute:'numeric'})
  return `${y} ${m} ${d} ${h}`
}))

watchEffect(()=>{
  // auto scroll
  if (!dragging && absoluteTimes.value.length) {
    const endTime = absoluteTimes.value[absoluteTimes.value.length-1]
    const range = chart.getVisibleRange()
    const width = range.to - range.from
    const now = s.clock
    const extra = (Math.max(0,endTime - now) + stdWidth.value/2) / width
    // console.log('visrange', range, width, absV)
    if (range.to < endTime) {
      // console.log('scrolling')
      chart.setVisibleRange({from: now - width, to: now}, {
        percentRightMargin: Math.round(100 * extra),
        applyDefaultRightMargin: false
      })
    }
  }
})


const absTimeA = computed({
  get() { return _timeEndpoints.value[0] },
  set(v) {
    if (v!==null)
      v = Number(v)
    updateA(v)
  }
})
const absTimeB = computed({
  get() { return _timeEndpoints.value[1] },
  set(v) {
    if (v!==null)
      v = Number(v)
    updateB(v)
  }
})


const _timeEndpoints = ref([props.builder.timeA, props.builder.timeB])
const timeEndpoints = computed({
  get() { return _timeEndpoints.value},
  set(v) {
    const [a, b] = v
    update(a,b, true, true)
  }
})


function updateA(a) {
  update(a, _timeEndpoints.value[1], true, false)
}


function updateB(b) {
  update(_timeEndpoints.value[0], b, false, true)
}


function update(a, b, updateA, updateB) {
  if (updateA) {
    const minB = a + minWidth.value
    if (b < minB)
      b = minB
  }
  if (updateB) {
    const maxA = b - minWidth.value
    if (a > maxA)
      a = maxA
  }
  _timeEndpoints.value = [a, b]
  props.builder.timeA = a
  props.builder.timeB = b
}

const flipped = computed(()=>{
  const a = props.builder.timeA
  const b = props.builder.timeB
  return a !== null && b !== null && a > b
})

function buildTranches() {
  const order = props.order
  const builder = props.builder
  const tranches = []
  const warnings = []

  console.log('buildTranches', builder, order, tranches)
  const ts = times.value
  const ets = endTimes.value
  const ws = weights.value
  console.log('buildTranches times ends weights', ts, ets, ws)
  for(let i=0; i<ts.length; i++) {
    const endTime = Math.max(ets[i],ts[i]+60);
    console.log('time check', endTime, s.clock)
    if (endTime <= s.clock)
      warnings.push(`Tranche already expired at ${new Date(endTime*1000)}`)
    const t = newTranche({
      marketOrder: true,
      slippage: builder.slippage,
      fraction: ws[i] * MAX_FRACTION,
      startTime: ts[i],
      endTime, // always give at least 60 seconds of window to execute
    })
    tranches.push(t)
  }
  return {tranches, warnings}
}


function getModelValue(model) {
  if(!model) {
    console.log('getModelValue', model)
    return null
  }
  return model.time
}

function getPointsValue(points) {
  return points[0].price
}

function setModelValue(model, value) {
  // console.log('DCA set model value', model, value)
  // const v = value === null ? null : props.builder.relative ? s.clock + Math.round(value) : Math.round(value)
  const v = value === null ? null : Math.round(value)
  if (model.time !== v) {
    // console.log('DCA do set time', v)
    model.time = v
  }
}

function setValues(values) {
  times.value = values.map((t)=>Math.round(t))
}

function setWeights(ws) { weights.value = ws }

</script>

<style scoped lang="scss">
td.weight {
  padding-left: 1em;
  padding-right: 1em;
}
</style>

