<template>
  <div class="lg:flex-nowrap flex-wrap justify-between relative">
    <slot
      name="stats"
      :node="node"
      :pubkey="pubkey"
      :target="target"
      :startDate="startDate"
      :endDate="endDate"
      :unit="unit"
      :dividend="dividend"
      :total="total"
      :issuers="issuers"
      :graph="graph"
    >
      <div class="leading-5 px-2 lg:px-0">
        <div v-if="unit === 'DU'">
          <span v-if="total && dividend" class="text-xl font-bold">
            {{
              !dividend ? 0 : (total / dividend).toFixed(2).replace('.', ',')
            }}
          </span>
          {{ ' DU' }}<sub>Ğ1</sub>
        </div>
        <div v-else>
          <span class="text-xl font-bold">
            {{ total.toFixed(2).replace('.', ',') }}
          </span>
          {{ ' Ğ1' }}
        </div>
        <div class="text-xl font-extralight">
          {{ `Montant collecté en ${months} mois` }}
        </div>
      </div>

      <div class="leading-5 px-2 lg:px-0">
        <div class="text-xl font-bold">{{ issuers.length }}</div>
        <div class="text-xl font-extralight">{{ 'Donneurs' }}</div>
      </div>
    </slot>

    <div
      class="
        flex
        items-center
        w-full
        lg:w-max
        justify-center
        px-2
        lg:px-0
        pt-2
        lg:pt-0
      "
    >
      <slot
        v-if="!isKeyCopied"
        name="button"
        class="w-full lg:w-max"
        :on-click="onClick"
      >
        <t-button class="w-full lg:w-max" @click="onClick">
          {{ buttonText }}
        </t-button>
      </slot>
      <t-button
        v-else
        variant="success"
        class="w-full lg:w-max"
        @click="onClick"
      >
        <fa icon="check" />
        Clé copiée
      </t-button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'G1Crowdfunding',
  props: {
    /**
     * Duniter node where to fetch data.
     */
    node: {
      type: String,
      default: 'https://g1.duniter.org',
    },
    /**
     * Pubkey of the crowdfunded wallet.
     */
    pubkey: {
      type: String,
      required: true,
    },
    /**
     * Amount target to reach.
     */
    target: {
      type: Number,
      default: null,
    },
    /**
     * Date of the begining of the crowdfunding
     * Default 3 months before today
     */
    startDate: {
      type: [Date, String],
      default() {
        const d = new Date()
        d.setHours(0, 0, 0, 0)
        return new Date(d.setMonth(d.getMonth() - 3))
      },
    },
    /**
     * Date of the begining of the crowdfunding
     * Default 3 months before today
     */
    endDate: {
      type: [Date, String],
      default() {
        return new Date()
      },
    },
    /**
     * Display amount in Ğ1 or DU
     * Default: DU
     */
    unit: {
      type: String,
      default: 'DU',
    },
    buttonText: {
      type: String,
      default: 'Donner',
    },
  },
  data() {
    return {
      now: Math.round(Date.now() / 1000),
      total: 0,
      graph: [],
      mapDelta: [],
      issuers: [],
      percentage: 0,
      dividend: null,
      isKeyCopied: false,
    }
  },
  computed: {
    endpoint() {
      // Build url from props. Prevent missing protocol.
      return (
        /^https:\/\//.test(this.node) ? this.node : `https://${this.node}`
      ).replace(/\/$/, '')
    },
    startDateTimestamp() {
      // TODO Check format starDate prop
      return Math.round(new Date(this.startDate).getTime() / 1000)
    },
    months() {
      return (
        this.endDate.getMonth() -
        this.startDate.getMonth() +
        12 * (this.endDate.getFullYear() - this.startDate.getFullYear())
      )
    },
  },
  mounted() {
    this.fetchDividend()
    this.fetchHistory()
  },
  methods: {
    async fetchDividend() {
      const dividend = JSON.parse(sessionStorage.getItem('current_dividend'))
      if (dividend) {
        this.dividend = dividend
      } else {
        const dividend = await fetch(`${this.endpoint}/blockchain/with/ud`)
          .then((resp) => resp.json())
          .then(
            async (data) =>
              await fetch(
                `${this.endpoint}/blockchain/block/${[
                  ...data.result.blocks,
                ].pop()}`
              )
                .then((resp) => resp.json())
                .then((data) => data.dividend / 100)
          )
        this.dividend = dividend
        sessionStorage.setItem('current_dividend', JSON.stringify(dividend))
      }
    },
    async fetchHistory() {
      // Caches to avoid fetching each time the dropdown is opened
      const history = JSON.parse(
        sessionStorage.getItem(`crowdfunding_${this.pubkey}`)
      )
      if (history) {
        this.total = history.total
        this.issuers = history.issuers
        this.graph = history.graph
      } else {
        await fetch(
          `${this.endpoint}/tx/history/${this.pubkey}/times/${this.startDateTimestamp}/${this.now}`
        )
          .then((response) => response.json())
          .then((response) => {
            const data = response.history.received
            this.buildData(data)
          })
          // eslint-disable-next-line no-console
          .catch((error) => console.log('Erreur : ' + error))

        // this.percentage = Math.round((this.total / this.target) * 100)
      }
    },
    buildData(data) {
      let tmpTimestamp = this.startDateTimestamp

      for (const tx of data) {
        const issuer = tx.issuers[0]

        // Why ? To check if issuer is not the account ? aka sent transaction to himself ?
        if (issuer !== this.pubkey) {
          // store issuer
          if (!this.issuers.includes(issuer)) this.issuers.push(issuer)

          for (const output of tx.outputs) {
            // One tx can have many output. Keep only our pubkey output.
            if (output.includes(this.pubkey)) {
              const timestamp = tx.time
              const amountTx = Number(output.match(/^(\d+):/)[1]) / 100

              if (timestamp !== tmpTimestamp)
                this.graph.push({
                  t: tmpTimestamp,
                  y: this.total.toFixed(2),
                })

              // const tday = 43200 + timestamp - (timestamp % 86400)
              // if (this.mapDelta[tday]) {
              //   this.mapDelta[tday] += Math.round(amountTx)
              // } else {
              //   this.mapDelta[tday] = Math.round(amountTx)
              // }

              // add tx amount to total
              this.total += amountTx

              tmpTimestamp = timestamp

              // // store for graph
              // this.arrayFinal.push(
              //   { t: tmpTimestamp, y: this.total.toFixed(2) },
              //   { t: this.now, y: this.total.toFixed(2) }
              // )
            }
          }
        }
      }
      sessionStorage.setItem(
        `crowdfunding_${this.pubkey}`,
        JSON.stringify({
          total: this.total,
          issuers: this.issuers,
          graph: this.graph,
        })
      )
    },
    onClick() {
      this.$copyText(this.pubkey)
      this.isKeyCopied = true
    },
  },
}
</script>

<style lang="scss" scoped></style>