import Vue from 'vue'
import './SntPayment.scss'
import { mapActions, mapGetters } from 'vuex'
import { VProgressCircular, VForm, VMenu, VDatePicker } from 'vuetify/lib'
import banks from '../../resources/json/banks.json'
import {
  CREATE_ORDER,
  CREATE_PAYORDER,
  GET_BANK_ACCOUNTS,
  GET_SALEPAGE_BANKACCOUNTS,
  GET_SALEPAGE_ORDER
} from '../../resources/graphql'

export default Vue.extend({
  name: 'SntPayment',
  components: { VProgressCircular, VForm, VMenu, VDatePicker },
  apollo: {
    order: () => ({
      fetchPolicy: 'network-only',
      query: GET_SALEPAGE_ORDER,
      pollInterval: 5000,
      skip () {
        return !this.orderId || !this.isAuth || this.isDemo
      },
      variables () {
        return {
          domain: this.subdomain,
          customerId: this.customerId,
          orderId: this.orderId
        }
      },
      update ({ salePage }) {
        return this.$_.head(salePage.findCustomer?.orderList.nodes || [])
      },
      result () {
        const order = this.order
        this.verifyOrder(order)
        this.balance = order.price
      }
    }),
    bankAccounts: () => ({
      query () {
        return this.subdomain ? GET_SALEPAGE_BANKACCOUNTS : GET_BANK_ACCOUNTS
      },
      variables () {
        return this.subdomain
          ? {
              domain: this.subdomain
            }
          : {
              page: 1,
              perPage: 100
            }
      },
      update (data) {
        const bankAccountList = this.subdomain ? data.salePage.bankAccountList : data.bankAccounts.nodes
        return bankAccountList.map((item) => ({
          ...item,
          color: this.banks[item.bank]?.color || null
        }))
      },
      result ({ data }) {
        if (this.isQRCode && !data.salePage.stock.scbPayment) {
          this.$router.push({ name: 'SalePage' })
        }
      }
    })
  },
  data () {
    return {
      orderId: null,
      isOldOrder: false,
      order: null,
      banks,
      bankAccount: null,
      imageFile: null,
      balance: 0,
      date: '',
      hour: null,
      minute: null,
      submitting: false,
      completeOrderId: null,
      hours: [
        '00', '01', '02', '03', '04', '05', '06', '07',
        '08', '09', '10', '11', '12', '13', '14', '15',
        '16', '17', '18', '19', '20', '21', '22', '23'
      ],
      minutes: [
        '00', '01', '02', '03', '04', '05', '06', '07',
        '08', '09', '10', '11', '12', '13', '14', '15',
        '16', '17', '18', '19', '20', '21', '22', '23',
        '24', '25', '26', '27', '28', '29', '30', '31',
        '32', '33', '34', '35', '36', '37', '38', '39',
        '40', '41', '42', '43', '44', '45', '46', '47',
        '48', '49', '50', '51', '52', '53', '54', '55',
        '56', '57', '58', '59'
      ]
    }
  },
  computed: {
    ...mapGetters({
      subdomain: 'salePage/subdomain',
      newOrder: 'salePage/order',
      customer: 'salePage/customer'
    }),
    isDemo () {
      return !this.subdomain
    },
    customerId () {
      return this.customer?.id
    },
    isAuth () {
      return !!this.customerId
    },
    isQRCode () {
      return this.$route.query?.method === 'qr' || null
    },
    loading () {
      return this.$apollo.queries.order.loading || this.$apollo.queries.bankAccounts.loading
    },
    imgQRCode () {
      return this.order?.scbQrCode?.data?.qrImage
        ? `data:image/png;base64, ${this.order.scbQrCode.data.qrImage}`
        : null
    },
    linkQRCode () {
      return this.order?.scbQrCode?.data?.qrRawData
        ? `https://info.scb.co.th/scbeasy/easy_app_link.html?URI=scbeasy://scan/${this.order.scbQrCode.data.qrRawData}`
        : null
    },
    displayDate () {
      if (!this.date) {
        return ''
      }
      return new Date(this.date)
        .toLocaleDateString('th-TH', {
          year: 'numeric',
          month: 'short',
          day: 'numeric'
        })
    },
    transferredAt () {
      if (this.hour && this.minute) {
        return this.$dayjs(this.date)
          .hour(this.hour)
          .minute(this.minute)
      }
      return null
    },
    netPrice () {
      return this.order?.price || this.newOrder?.price || 0
    },
    valid () {
      return this.isQRCode || (this.bankAccount && this.imageFile && this.balance && this.date && this.hour && this.minute)
    },
    slotProps () {
      return {
        order: this.order,
        bankAccounts: this.bankAccounts,
        isQRCode: this.isQRCode,
        imgQRCode: this.imgQRCode,
        linkQRCode: this.linkQRCode,
        netPrice: this.netPrice,
        value: {
          bankAccount: this.bankAccount,
          file: this.imageFile,
          balance: this.balance,
          date: this.date,
          hour: this.hour,
          minute: this.minute
        },
        changeValues: this.changeValues,
        valid: this.valid,
        submitting: this.submitting,
        submit: this.submit
      }
    }
  },
  created () {
    this.orderId = this.$route.params.orderId
    if (this.orderId) {
      // เช็คกรณีเป็นออเดอร์เก่า
      if (!this.isAuth) {
        this.$router.push({ name: 'SalePage' })
      }
    } else if (!this.isDemo) {
      if (!this.newOrder.price) {
        this.$router.push({ name: 'SalePage' })
      }
    }
    this.date = this.$dayjs().format('YYYY-MM-DD')
  },
  methods: {
    ...mapActions({
      setCustomer: 'salePage/setCustomer',
      clearOrder: 'salePage/clearOrder',
      clearCart: 'cart/clearCart'
    }),
    changeValues (value) {
      this.bankAccount = value.bankAccount || this.bankAccount
      this.imageFile = value.imageFile || this.imageFile
      this.balance = Math.abs(value.balance) || this.balance
      this.date = value.date || this.date
      this.hour = value.hour || this.hour
      this.minute = value.minute || this.minute
    },
    verifyOrder (order) {
      if (!order) { return false }
      const isUnconfirmed = order.salePageStatus === 'UNCONFIRMED'
      if (!order.price) {
        this.$router.push({ name: 'SalePage' })
        return false
      } if (!isUnconfirmed && order.id) {
        this.$router.push({
          name: 'SalePageOrder',
          params: {
            orderId: order.id
          }
        })
      }
      return true
    },
    async submit () {
      if (this.isDemo) {
        return
      }
      this.submitting = true
      let orderId = this.orderId
      if (this.order) {
        const { data: { salePage } } = await this.$apollo.query({
          query: GET_SALEPAGE_ORDER,
          variables: {
            domain: this.subdomain,
            customerId: this.customerId,
            orderId: this.orderId
          }
        })
        const order = this.$_.head(salePage.findCustomer?.orderList.nodes || [])
        if (this.orderId === order.id && this.verifyOrder(order)) {
          const { data: { payOrder } } = await this.$apollo.mutate({
            mutation: CREATE_PAYORDER,
            variables: {
              input: {
                id: orderId,
                salePageDomain: this.subdomain,
                bankAccountId: this.bankAccount,
                paidAmount: this.balance,
                transferredAt: this.transferredAt,
                paymentSlip: this.imageFile
              }
            }
          })
          if (payOrder) {
            this.$fb.track('Purchase', {
              value: payOrder.order.price,
              currency: 'THB'
            })
          }
        }
      } else {
        const { data: { createOrder } } = await this.$apollo.mutate({
          mutation: CREATE_ORDER,
          variables: {
            input: {
              customerId: this.customerId,
              salePageDomain: this.subdomain,
              shippingType: this.newOrder.shippingType,
              address: this.newOrder.address,
              email: this.newOrder.email,
              name: this.newOrder.name,
              promotionCode: this.newOrder.promotionCode,
              shippop: this.newOrder.shippop,
              taxable: this.newOrder.taxable,
              taxId: this.newOrder.taxId,
              tel: this.newOrder.tel,
              purchases: this.newOrder.purchases,
              setPurchases: this.newOrder.setPurchases,
              bankAccountId: this.bankAccount,
              paidAmount: this.balance,
              transferredAt: this.transferredAt,
              paymentSlip: this.imageFile
            }
          }
        })
        if (createOrder) {
          orderId = createOrder.order.id
          const customer = createOrder.order.customer
          this.setCustomer({
            id: customer.id,
            tel: customer.tel,
            addressList: customer.addressList,
            name: customer.name,
            address: customer.address,
            email: customer.email
          })
          this.clearCart()
          this.$fb.track('Purchase', {
            value: createOrder.order.price,
            currency: 'THB'
          })
        }
      }
      this.submitting = false
      this.clearOrder()
      this.$router.push({ name: 'SalePageThankYou', params: { orderId } })
    }
  },
  template: `
    <div class="snt-payment">
      <slot v-bind="slotProps">
        <div
          v-if="loading"
          class="text-center">
          <v-progress-circular
            :size="14"
            :width="1"
            color="secondary"
            indeterminate
          />
        </div>
        <template v-else>
          <snt-container>
            <div class="snt-payment__title">
              <slot
                v-bind="slotProps"
                name="header">
                <div class="snt-payment-title">
                  แจ้งชำระเงิน
                </div>
              </slot>
            </div>
            <div
              v-if="isQRCode"
              class="snt-payment-card">
              <slot
                v-bind="slotProps"
                name="qrcode">
                <div class="snt-payment-card__title">
                  SCB QR Code
                </div>
                <div
                  v-if="order"
                  class="snt-payment-card__text">
                  <div
                    v-if="imgQRCode"
                    class="snt-payment-qrcode">
                    <img
                      :src="imgQRCode"
                      class="snt-payment-qrcode__image"
                      width="260" />
                  </div>
                  <a
                    v-if="linkQRCode && $shipnity.isMobileDevice"
                    :href="linkQRCode"
                    class="snt-payment-qrcode__link"
                    target="_blank">
                    ลิงก์
                  </a>
                </div>
              </slot>
            </div>
            <template v-else>
              <div class="snt-payment-card">
                <slot
                  v-bind="slotProps"
                  name="banks">
                  <div class="snt-payment-card__title">
                    เลือกบัญชีที่ต้องการโอน
                  </div>
                  <div class="snt-payment-card__text">
                    <snt-payment-banks
                      :value="bankAccount"
                      :items="bankAccounts"
                      @input="changeValues({ bankAccount: $event })" />
                  </div>
                </slot>
              </div>
              <div class="snt-payment-card">
                <slot
                  v-bind="slotProps"
                  name="proof">
                  <div class="snt-payment-card__title">
                    หลักฐานการโอนเงิน
                  </div>
                  <div class="snt-payment-card__text">
                    <div class="snt-payment-proof">
                      <div class="snt-payment-proof-upload">
                        <snt-payment-upload @input="changeValues({ imageFile: $event })" />
                      </div>
                      <v-form class="snt-payment-proof-form">
                        <div class="snt-payment-proof-form__label">
                          ยอดเงิน
                        </div>
                        <div class="mb-3">
                          <snt-text-field
                            :value="balance"
                            class="snt-payment-proof-form__input"
                            onkeypress="return event.charCode >= 48 && event.charCode <= 57"
                            type="number"
                            min="0"
                            autocomplete="off"
                            single-line
                            hide-details
                            dense
                            outlined
                            @input="changeValues({ balance: $event })" />
                        </div>
                        <div class="snt-payment-proof-form__label">
                          วันที่โอนเงิน
                        </div>
                        <div class="mb-3">
                          <v-menu
                            :close-on-content-click="false"
                            offset-y>
                            <template #activator="{ on, attrs }">
                              <snt-text-field
                                :value="displayDate"
                                v-bind="attrs"
                                class="snt-payment-proof-form__input"
                                outlined
                                readonly
                                dense
                                hide-details
                                v-on="on" />
                            </template>
                            <v-date-picker
                              v-model="date"
                              locale="th-TH"
                              width="300"
                              @input="changeValues({ date: $event })" />
                          </v-menu>
                        </div>
                        <div class="snt-payment-proof-form__label">
                          เวลาที่โอนเงิน
                        </div>
                        <div class="snt-payment-proof-form__input-group">
                          <snt-select
                            :value="hour"
                            :items="hours"
                            label="ชั่วโมง"
                            placeholder="ชั่วโมง"
                            class="snt-payment-proof-form__input snt-payment-proof-form__input--half"
                            hide-details
                            dense
                            outlined
                            @input="changeValues({ hour: $event })"
                          />
                          <snt-select
                            :value="minute"
                            :items="minutes"
                            label="นาที"
                            placeholder="นาที"
                            class="snt-payment-proof-form__input snt-payment-proof-form__input--half"
                            hide-details
                            dense
                            outlined
                            @input="changeValues({ minute: $event })"
                          />
                        </div>
                      </v-form>
                    </div>
                  </div>
                </slot>
              </div>
            </template>
            <div class="snt-payment-footer">
              <slot
                v-bind="slotProps"
                name="action">
                <div class="snt-payment-footer__net-price">
                  <div class="snt-payment-footer__net-price-title">
                    ราคาสุทธิ
                  </div>
                  <div class="snt-payment-footer__net-price-text">
                    {{ netPrice | toLocaleString }} บาท
                  </div>
                </div>
                <snt-button
                  :loading="submitting"
                  :disabled="!valid"
                  class="snt-payment-footer__submit"
                  color="primary"
                  depressed
                  large
                  @click="submit()">
                  ยืนยันการชำระเงิน
                </snt-button>
              </slot>
            </div>
          </snt-container>
        </template>
      </slot>
    </div>
  `
})
