<template>
  <div class="modal-card box box-modal">
    <header class="box-modal-header">
      <div class="box-modal-title">{{ $t('settings') }}</div>
      <button type="button" class="delete" @click="$parent.cancel('escape')" />
    </header>
    <div class="field">
      <b-field :label="$t('rpc')" class="has-custom-field" data-test="rpc_endpoint_dropdown">
        <b-dropdown v-model="selectedRpc" expanded aria-role="list">
          <div slot="trigger" class="control" :class="{ 'is-loading': checkingRpc && !isCustomRpc }">
            <div class="input">
              <span>{{ isCustomRpc ? $t('customRpc') : selectedRpc }}</span>
            </div>
          </div>
          <b-dropdown-item
            v-for="{ name, url } in Object.values(networkConfig.rpcUrls)"
            :key="name"
            :value="name"
            aria-role="listitem"
            :data-test="`rpc_endpoint_${name}`"
            @click="checkRpc({ name, url })"
          >
            {{ name }}
          </b-dropdown-item>
          <b-dropdown-item
            value="custom"
            aria-role="listitem"
            data-test="rpc_endpoint_custom"
            @click="checkRpc({ name: 'custom' })"
          >
            {{ $t('customRpc') }}
          </b-dropdown-item>
        </b-dropdown>
      </b-field>
      <div v-if="isCustomRpc" class="field has-custom-field">
        <b-input
          ref="customInput"
          v-model="customRpcUrl"
          type="url"
          :placeholder="$t('customRpcPlaceholder')"
          :custom-class="hasErrorRpc.type"
          :use-html5-validation="false"
          @input="checkCustomRpc"
        ></b-input>
      </div>
      <p v-if="hasErrorRpc.msg" class="help" :class="hasErrorRpc.type">
        {{ hasErrorRpc.msg }}
      </p>
    </div>
    <template v-if="!isEthereumNetwork">
      <div class="field">
        <b-field label="Ethereum RPC provider" class="has-custom-field" data-test="rpc_endpoint_eth_dropdown">
          <b-dropdown v-model="selectedEthRpc" expanded aria-role="list">
            <div slot="trigger" class="control" :class="{ 'is-loading': checkingRpc && !isCustomEthRpc }">
              <div class="input">
                <span>{{ isCustomEthRpc ? $t('customRpc') : selectedEthRpc }}</span>
              </div>
            </div>
            <b-dropdown-item
              v-for="{ name, url } in Object.values(ethNetworkConfig.rpcUrls)"
              :key="name"
              :value="name"
              aria-role="listitem"
              :data-test="`rpc_endpoint_eth_${name}`"
              @click="checkEthRpc({ name, url })"
            >
              {{ name }}
            </b-dropdown-item>
            <b-dropdown-item
              value="custom"
              aria-role="listitem"
              data-test="rpc_endpoint_eth_custom"
              @click="checkEthRpc({ name: 'custom' })"
            >
              {{ $t('customRpc') }}
            </b-dropdown-item>
          </b-dropdown>
        </b-field>
        <div v-if="isCustomEthRpc" class="field has-custom-field">
          <b-input
            ref="customInputTwo"
            v-model="customEthRpcUrl"
            type="url"
            :placeholder="$t('customRpcPlaceholder')"
            :custom-class="hasErrorEthRpc.type"
            :use-html5-validation="false"
            @input="checkCustomEthRpc"
          ></b-input>
        </div>
        <p v-if="hasErrorEthRpc.msg" class="help" :class="hasErrorEthRpc.type">
          {{ hasErrorEthRpc.msg }}
        </p>
      </div>
    </template>
    <div class="buttons buttons__halfwidth">
      <b-button type="is-primary" outlined data-test="button_reset_rpc" @mousedown.prevent @click="onReset">
        {{ $t('reset') }}
      </b-button>
      <b-button type="is-primary" :disabled="isDisabledSave" data-test="save_rpc_button" @click="onSave">
        {{ $t('save') }}
      </b-button>
    </div>
  </div>
</template>
<script>
/* eslint-disable no-console */
import { mapGetters, mapMutations } from 'vuex'

import { debounce } from '@/utils'
import networkConfig from '@/networkConfig'

export default {
  props: {
    netId: {
      type: Number,
      required: true
    }
  },
  data() {
    return {
      checkingRpc: false,
      hasErrorRpc: { type: '', msg: '' },
      hasErrorEthRpc: { type: '', msg: '' },
      customRpcUrl: '',
      customEthUrl: '',
      selectedRpc: 'custom',
      selectedEthRpc: 'custom',
      rpc: { name: 'custom', url: '' },
      ethRpc: { name: 'custom', url: '' }
    }
  },
  computed: {
    ...mapGetters('settings', ['getRpc']),
    networkConfig() {
      return networkConfig[`netId${this.netId}`]
    },
    ethNetworkConfig() {
      return networkConfig.netId1
    },
    isEthereumNetwork() {
      return this.netId === 1
    },
    isCustomRpc() {
      return this.selectedRpc === 'custom'
    },
    isCustomEthRpc() {
      return this.selectedEthRpc === 'custom'
    },
    isDisabledSave() {
      return (
        this.hasErrorRpc.type === 'is-warning' || this.checkingRpc || (this.isCustomRpc && !this.customRpcUrl)
      )
    }
  },
  created() {
    this.ethRpc = this.getRpc(1)
    this.rpc = this.getRpc(this.netId)
    this.selectedRpc = this.rpc.name
    this.selectedEthRpc = this.ethRpc.name

    if (this.selectedRpc === 'custom') {
      this.$nextTick(() => {
        this.customRpcUrl = this.rpc.url
      })
    }
    if (this.selectedEthRpc === 'custom') {
      this.$nextTick(() => {
        this.customEthRpcUrl = this.ethRpc.url
      })
    }

    this.checkRpc(this.rpc)
    this.checkEthRpc(this.ethRpc)
  },
  methods: {
    ...mapMutations('settings', ['SAVE_RPC']),
    onReset() {
      this.checkingRpc = false
      this.hasErrorRpc = { type: '', msg: '' }

      this.rpc = Object.entries(this.networkConfig.rpcUrls)[0][1]
      this.ethRpc = Object.entries(this.ethNetworkConfig.rpcUrls)[0][1]
      this.selectedRpc = this.rpc.name
      this.selectedEthRpc = this.ethRpc.name
      this.checkEthRpc(this.ethRpc)
      this.checkRpc(this.rpc)
    },
    onSave() {
      this.SAVE_RPC({ ...this.rpc, netId: this.netId })
      if (this.netId !== 1) {
        this.SAVE_RPC({ ...this.ethRpc, netId: 1 })
      }
      this.$emit('close')
    },
    onCancel() {
      this.$emit('cancel')
    },
    checkRpc({ name, url = '' }) {
      this.checkingRpc = true

      if (name === 'custom') {
        this.customRpcUrl = ''
        this.hasErrorRpc = { type: '', msg: '' }
      }
      this._checkRpc({ name, url })
    },
    checkEthRpc({ name, url = '' }) {
      this.checkingRpc = true

      if (name === 'custom') {
        this.customEthRpcUrl = ''
        this.hasErrorEthRpc = { type: '', msg: '' }
        return
      }
      this._checkEthRpc({ name, url })
    },
    checkCustomRpc(url) {
      const trimmedUrl = url.trim()
      if (!trimmedUrl) {
        this.hasErrorRpc = { type: '', msg: '' }
        return
      }
      debounce(this._checkRpc, { name: 'custom', url: trimmedUrl })
    },
    checkCustomEthRpc(url) {
      const trimmedUrl = url.trim()
      if (!trimmedUrl) {
        this.hasErrorEthRpc = { type: '', msg: '' }
        return
      }
      debounce(this._checkEthRpc, { name: 'custom', url: trimmedUrl })
    },
    async _checkRpc({ name, url }) {
      this.checkingRpc = true
      this.hasErrorRpc = { type: '', msg: '' }

      const { isValid, error } = await this.$store.dispatch('settings/checkRpc', {
        url,
        netId: this.netId
      })

      if (isValid) {
        this.hasErrorRpc.type = 'is-primary'
        this.hasErrorRpc.msg = this.$t('rpcStatusOk')
        this.rpc = { name, url }
      } else {
        this.hasErrorRpc.type = 'is-warning'
        this.hasErrorRpc.msg = error
      }

      this.checkingRpc = false
    },
    async _checkEthRpc({ name, url }) {
      this.checkingRpc = true
      this.hasErrorEthRpc = { type: '', msg: '' }

      const { isValid, error } = await this.$store.dispatch('settings/checkRpc', {
        url,
        netId: 1,
        isEthRpc: true
      })

      if (isValid) {
        this.hasErrorEthRpc.type = 'is-primary'
        this.hasErrorEthRpc.msg = this.$t('rpcStatusOk')
        this.ethRpc = { name, url }
      } else {
        this.hasErrorEthRpc.type = 'is-warning'
        this.hasErrorEthRpc.msg = error
      }

      this.checkingRpc = false
    }
  }
}
</script>