{% extends "public.html" %} {% block page %}
<div class="row q-col-gutter-md flex">
  <div class="col-12 col-md-7 col-lg-6 q-gutter-y-md">
    <q-card>
      <div class="chat-container q-pa-md">
        <div class="chat-box">
          <!-- <p v-if="Object.keys(messages).length === 0">No messages yet</p> -->
          <div class="chat-messages">
            <q-chat-message
              :key="index"
              v-for="(message, index) in messages"
              :name="message.pubkey == user.keys.publickey ? 'me' : 'merchant'"
              :text="[message.msg]"
              :sent="message.pubkey == user.keys.publickey ? true : false"
              :bg-color="message.pubkey == user.keys.publickey ? 'white' : 'light-green-2'"
            />
          </div>
        </div>
        <q-form @submit="sendMessage" class="full-width chat-input">
          <q-input
            ref="newMessage"
            v-model="newMessage"
            placeholder="Message"
            class="full-width"
            dense
            outlined
            @click="checkWebSocket"
          >
            <template>
              <q-btn
                round
                dense
                flat
                type="submit"
                icon="send"
                color="primary"
              />
            </template>
          </q-input>
        </q-form>
      </div>
    </q-card>
  </div>
  <div class="col-12 col-md-5 col-lg-6 q-gutter-y-md">
    <q-card>
      <q-card-section>
        {% raw %}
        <h6 class="text-subtitle1 q-my-none">{{ stall.name }}</h6>
        <p @click="copyText(stall.publickey)" style="width: max-content">
          Public Key: {{ sliceKey(stall.publickey) }}
          <q-tooltip>Click to copy</q-tooltip>
        </p>
        {% endraw %}
      </q-card-section>
      <q-card-section v-if="user">
        <q-form @submit="" class="q-gutter-md">
          <!-- <q-select
            filled
            dense
            emit-value
            v-model="model"
            :options="mockMerch"
            label="Merchant"
            hint="Select a merchant you've opened an order to"
          ></q-select>
          <br /> -->
          <q-select
            filled
            dense
            emit-value
            v-model="selectedOrder"
            :options="Object.keys(user.orders).map(o => ({label: `${o.slice(0, 25)}...`, value: o}))"
            label="Order"
            hint="Select an order from this merchant"
            @input="val => { changeOrder() }"
            emit-value
          ></q-select>
        </q-form>
      </q-card-section>
      <q-card-section>
        <q-list>
          {% raw %}
          <q-item clickable :key="p.id" v-for="p in products">
            <q-item-section side>
              <span>{{p.quantity}} x </span>
            </q-item-section>
            <q-item-section avatar>
              <q-avatar color="primary">
                <img size="sm" :src="p.image" />
              </q-avatar>
            </q-item-section>
            <q-item-section>
              <q-item-label>{{ p.name }}</q-item-label>
            </q-item-section>

            <q-item-section side>
              <span v-if="stall.currency != 'sat'"
                >{{ getAmountFormated(p.price) }}</span
              >
              <span v-else> {{p.price}} sats</span>
            </q-item-section>
          </q-item>
          {% endraw %}
        </q-list>
      </q-card-section>
      <q-card-section>
        <q-separator></q-separator>
        <q-list>
          <q-expansion-item group="extras" icon="vpn_key" label="Keys"
            ><p>
              Bellow are the keys needed to contact the merchant. They are
              stored in the browser!
            </p>
            <div v-if="user?.keys" class="row q-col-gutter-md">
              <div
                class="col-12 col-sm-6"
                v-for="type in ['publickey', 'privatekey']"
                v-bind:key="type"
              >
                <div class="text-center q-mb-lg">
                  {% raw %}
                  <q-responsive
                    :ratio="1"
                    class="q-mx-auto"
                    style="max-width: 250px"
                  >
                    <qrcode
                      :value="user.keys[type]"
                      :options="{width: 500}"
                      class="rounded-borders"
                    ></qrcode>
                    <q-tooltip>{{ user.keys[type] }}</q-tooltip>
                  </q-responsive>
                  <p>
                    {{ type == 'publickey' ? 'Public Key' : 'Private Key' }}
                  </p>
                  {% endraw %}
                </div>
              </div>
            </div>
            <q-separator></q-separator>
            <div class="row q-mt-lg">
              <q-btn outline color="grey" @click="downloadKeys"
                >Backup keys
                <q-tooltip>Download your keys</q-tooltip>
              </q-btn>
              <q-btn
                outline
                color="grey"
                class="q-mx-sm"
                @click="keysDialog.show = true"
                :disabled="this.user.keys"
                >Restore keys
                <q-tooltip>Restore keys</q-tooltip>
              </q-btn>
              <q-btn
                @click="deleteData"
                v-close-popup
                flat
                color="grey"
                class="q-ml-auto"
                >Delete data
                <q-tooltip>Delete all data from browser</q-tooltip>
              </q-btn>
            </div>
          </q-expansion-item>
        </q-list>
        <q-expansion-item icon="qr_code" label="Export page">
          <p>Export, or send, this page to another device</p>
          <div class="text-center q-mb-lg">
            <q-responsive
              :ratio="1"
              class="q-my-xl q-mx-auto"
              style="max-width: 250px"
              @click="copyText(exportURL)"
            >
              <qrcode
                :value="exportURL"
                :options="{width: 500}"
                class="rounded-borders"
              ></qrcode>
              <q-tooltip>Click to copy</q-tooltip>
            </q-responsive>
          </div>
          <div class="row q-mt-lg">
            <q-btn
              @click="copyText(exportURL)"
              v-close-popup
              flat
              color="grey"
              class="q-ml-auto"
              >Copy URL
              <q-tooltip
                >Export, or send, this page to another device</q-tooltip
              >
            </q-btn>
          </div>
        </q-expansion-item>
      </q-card-section>
    </q-card>
  </div>
  <!-- RESTORE KEYS DIALOG -->
  <q-dialog
    v-if="diagonalley"
    v-model="keysDialog.show"
    position="top"
    @hide="clearRestoreKeyDialog"
  >
    <q-card class="q-pa-lg q-pt-xl lnbits__dialog-card"> </q-card>
    <q-card class="q-pa-lg lnbits__dialog-card">
      <q-form @submit="restoreKeys" class="q-gutter-md">
        <q-input
          filled
          dense
          v-model.trim="keysDialog.data.publickey"
          label="Public Key"
        ></q-input>
        <q-input
          filled
          dense
          v-model.trim="keysDialog.data.privatekey"
          label="Private Key *optional"
        ></q-input>
        <div class="row q-mt-lg">
          <q-btn
            unelevated
            color="primary"
            :disable="keysDialog.data.publickey == null"
            type="submit"
            label="Submit"
          ></q-btn>
          <q-btn
            v-close-popup
            flat
            @click="clearRestoreKeyDialog"
            color="grey"
            class="q-ml-auto"
            label="Cancel"
          ></q-btn>
        </div>
      </q-form>
    </q-card>
  </q-dialog>
  <!-- ONBOARDING DIALOG -->
  <q-dialog v-model="lnbitsBookmark.show">
    <q-card class="q-pa-lg">
      <h6 class="q-my-md text-primary">Bookmark this page</h6>
      <p>
        Don't forget to bookmark this page to be able to check on your order!
      </p>
      <p>
        You can backup your keys, and export the page to another device also.
      </p>
      <div class="row q-mt-lg">
        <q-btn
          v-close-popup
          flat
          @click="lnbitsBookmark.finish"
          color="grey"
          class="q-ml-auto"
          >Close</q-btn
        >
      </div>
    </q-card>
  </q-dialog>
</div>
{% endblock %} {% block scripts %}
<script src="https://unpkg.com/nostr-tools/lib/nostr.bundle.js"></script>

<script>
  const mapChatMsg = msg => {
    let obj = {}
    obj.timestamp = {
      msg: msg,
      pubkey: pubkey
    }
    return obj
  }

  const mapProductsItems = obj => {
    obj.price = (obj.price / 100).toFixed(2)

    return obj
  }
  Vue.component(VueQrcode.name, VueQrcode)
  const nostr = window.NostrTools
  new Vue({
    el: '#vue',
    mixins: [windowMixin],
    data: function () {
      return {
        lnbitsBookmark: {
          show: true,
          finish: () => {
            this.$q.localStorage.set('lnbits.marketbookmark', false)
            this.lnbitsBookmark.show = false
          }
        },
        newMessage: '',
        showMessages: false,
        messages: {},
        stall: null,
        selectedOrder: null,
        diagonalley: false,
        products: [],
        orders: [],
        user: {
          keys: {},
          orders: {}
        },
        keysDialog: {
          show: false,
          data: {}
        }
      }
    },
    computed: {
      exportURL() {
        return (
          '{{request.url}}' +
          `&keys=${this.user.keys.publickey},${this.user.keys.privatekey}`
        )
      }
    },
    methods: {
      getAmountFormated(amount) {
        return LNbits.utils.formatCurrency(amount, this.stall.currency)
      },
      clearMessage() {
        this.newMessage = ''
        this.$refs.newMessage.focus()
      },
      clearRestoreKeyDialog() {
        this.keysDialog = {
          show: false,
          data: {}
        }
      },
      sendMessage() {
        let message = {
          msg: this.newMessage,
          pubkey: this.user.keys.publickey
        }
        this.ws.send(JSON.stringify(message))

        this.clearMessage()
      },
      sliceKey(key) {
        if (!key) return ''
        return `${key.slice(0, 4)}...${key.slice(-4)}`
      },
      downloadKeys() {
        const file = new File(
          [JSON.stringify(this.user.keys)],
          'backup_keys.json',
          {
            type: 'text/json'
          }
        )
        const link = document.createElement('a')
        const url = URL.createObjectURL(file)

        link.href = url
        link.download = file.name
        link.click()

        window.URL.revokeObjectURL(url)
      },
      restoreKeys() {
        this.user.keys = this.keysDialog.data
        let data = this.$q.localStorage.getItem(`lnbits.market.data`)
        this.$q.localStorage.set(`lnbits.market.data`, {
          ...data,
          keys: this.user.keys
        })

        this.clearRestoreKeyDialog()
      },
      deleteData() {
        LNbits.utils
          .confirmDialog('Are you sure you want to delete your stored data?')
          .onOk(() => {
            this.$q.localStorage.remove('lnbits.market.data')
            this.user = null
          })
      },
      generateKeys() {
        //check if the keys are set
        if ('publickey' in this.user.keys && 'privatekey' in this.user.keys)
          return

        const privkey = nostr.generatePrivateKey()
        const pubkey = nostr.getPublicKey(privkey)

        this.user.keys = {
          privatekey: privkey,
          publickey: pubkey
        }
      },
      async getMessages(room_name, all = false) {
        await LNbits.api
          .request(
            'GET',
            `/market/api/v1/chat/messages/${room_name}${
              all ? '?all_messages=true' : ''
            }`
          )
          .then(response => {
            if (response.data) {
              response.data.reverse().map(m => {
                this.$set(this.messages, m.timestamp * 1000, {
                  msg: m.msg,
                  pubkey: m.pubkey
                })
              })
            }
          })
          .catch(function (error) {
            LNbits.utils.notifyApiError(error)
          })
      },
      async changeOrder() {
        this.products = this.user.orders[this.selectedOrder]
        this.messages = {}
        await this.getMessages(this.selectedOrder)
        this.startChat(this.selectedOrder)
      },
      checkWebSocket() {
        if (!this.ws) return
        if (this.ws.readyState === WebSocket.CLOSED) {
          console.log('WebSocket CLOSED: Reopening')
          this.ws = new WebSocket(
            ws_scheme + location.host + '/market/ws/' + this.selectedOrder
          )
        }
      },
      startChat(room_name) {
        if (this.ws) {
          this.ws.close()
        }
        if (location.protocol == 'https:') {
          ws_scheme = 'wss://'
        } else {
          ws_scheme = 'ws://'
        }
        ws = new WebSocket(
          ws_scheme + location.host + '/market/ws/' + room_name
        )

        ws.onmessage = event => {
          let event_data = JSON.parse(event.data)

          this.$set(this.messages, Date.now(), event_data)
        }

        this.ws = ws
      }
    },
    async created() {
      let showBookmark = this.$q.localStorage.getItem('lnbits.marketbookmark')
      this.lnbitsBookmark.show = showBookmark === true || showBookmark == null

      let order_details = JSON.parse('{{ order | tojson }}')
      let products = JSON.parse('{{ products | tojson }}')
      let order_id = '{{ order_id }}'
      let hasKeys = Boolean(
        JSON.parse('{{ publickey | tojson }}') &&
          JSON.parse('{{ privatekey | tojson }}')
      )

      if (hasKeys) {
        this.user.keys = {
          privatekey: '{{ privatekey }}',
          publickey: '{{ publickey }}'
        }
      }

      this.stall = JSON.parse('{{ stall | tojson }}')
      this.products = order_details.map(o => {
        let product = products.find(p => p.id == o.product_id)
        return {
          quantity: o.quantity,
          name: product.product,
          image: product.image,
          price: product.price
        }
      })
      console.log(this.stall)
      if (this.stall.currency != 'sat') {
        this.products = this.products.map(mapProductsItems)
      }

      let data = this.$q.localStorage.getItem(`lnbits.market.data`) || false

      if (data) {
        this.user = data
        if (!this.user.orders[`${order_id}`]) {
          this.$set(this.user.orders, order_id, this.products)
        }
      } else {
        // generate keys
        this.generateKeys()
        try {
          await LNbits.api.request(
            'GET',
            `/market/api/v1/order/pubkey/${order_id}/${this.user.keys.publickey}`
          )
        } catch (error) {
          LNbits.utils.notifyApiError(error)
        }
        // populate user data
        this.user.orders = {
          [`${order_id}`]: this.products
        }
      }

      this.selectedOrder = order_id

      await this.getMessages(order_id)

      this.$q.localStorage.set(`lnbits.market.data`, this.user)
      this.startChat(order_id)
    }
  })
</script>
<style scoped>
  .q-field__native span {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .chat-container {
    position: relative;
    display: grid;
    grid-template-rows: 1fr auto;
    /*height: calc(100vh - 200px);*/
    height: 70vh;
  }

  .chat-box {
    display: flex;
    flex-direction: column-reverse;
    padding: 1rem;
    overflow-y: auto;
    margin-left: auto;
    width: 50%;
  }

  .chat-messages {
    width: auto;
  }

  .chat-other {
  }

  .chat-input {
    position: relative;
    display: flex;
    align-items: end;
    margin-top: 1rem;
  }
</style>
{% endblock %}
