<template>
  <main
    v-title="labels.title"
    class="main pusher"
  >
    <section class="ui vertical stripe segment">
      <div class="ui small text container">
        <h2>
          <i class="lock open icon" /><translate translate-context="Content/Auth/Title/Verb">
            Authorize third-party app
          </translate>
        </h2>
        <div
          v-if="errors.length > 0"
          role="alert"
          class="ui negative message"
        >
          <h4
            v-if="application"
            class="header"
          >
            <translate translate-context="Popup/Moderation/Error message">
              Error while authorizing application
            </translate>
          </h4>
          <h4
            v-else
            class="header"
          >
            <translate translate-context="Popup/Moderation/Error message">
              Error while fetching application data
            </translate>
          </h4>
          <ul class="list">
            <li
              v-for="(error, key) in errors"
              :key="key"
            >
              {{ error }}
            </li>
          </ul>
        </div>
        <div
          v-if="isLoading"
          class="ui inverted active dimmer"
        >
          <div class="ui loader" />
        </div>
        <form
          v-else-if="application && !code"
          :class="['ui', {loading: isLoading}, 'form']"
          @submit.prevent="submit"
        >
          <h3>
            <translate
              translate-context="Content/Auth/Title"
              :translate-params="{app: application.name}"
            >
              %{ app } wants to access your Funkwhale account
            </translate>
          </h3>

          <h4
            v-for="(topic, key) in topicScopes"
            :key="key"
            class="ui header vertical-align"
          >
            <span
              v-if="topic.write && !topic.read"
              :class="['ui', 'basic', 'right floated', 'tiny', 'vertically-spaced component-label label']"
            >
              <i class="pencil icon" />
              <translate translate-context="Content/Auth/Label/Noun">Write-only</translate>
            </span>
            <span
              v-else-if="!topic.write && topic.read"
              :class="['ui', 'basic', 'right floated', 'tiny', 'vertically-spaced component-label label']"
            >
              <translate translate-context="Content/Auth/Label/Noun">Read-only</translate>
            </span>
            <span
              v-else-if="topic.write && topic.read"
              :class="['ui', 'basic', 'right floated', 'tiny', 'vertically-spaced component-label label']"
            >
              <i class="pencil icon" />
              <translate translate-context="Content/Auth/Label/Noun">Full access</translate>
            </span>
            <i :class="[topic.icon, 'icon']" />
            <div class="content">
              {{ topic.label }}
              <div class="sub header">
                {{ topic.description }}
              </div>
            </div>
          </h4>
          <div v-if="unknownRequestedScopes.length > 0">
            <p><strong><translate translate-context="Content/Auth/Paragraph">The application is also requesting the following unknown permissions:</translate></strong></p>
            <ul
              v-for="(unknownscope, key) in unknownRequestedScopes"
              :key="key"
            >
              <li>{{ unknownscope }}</li>
            </ul>
          </div>
          <button
            class="ui success labeled icon button"
            type="submit"
          >
            <i class="lock open icon" />
            <translate
              translate-context="Content/Signup/Button.Label/Verb"
              :translate-params="{app: application.name}"
            >
              Authorize %{ app }
            </translate>
          </button>
          <p
            v-if="redirectUri === 'urn:ietf:wg:oauth:2.0:oob'"
            key="1"
            v-translate
            translate-context="Content/Auth/Paragraph"
          >
            You will be shown a code to copy-paste in the application.
          </p>
          <p
            v-else
            key="2"
            v-translate="{url: redirectUri}"
            translate-context="Content/Auth/Paragraph"
            :translate-params="{url: redirectUri}"
          >
            You will be redirected to <strong>%{ url }</strong>
          </p>
        </form>
        <div v-else-if="code">
          <p><strong><translate translate-context="Content/Auth/Paragraph">Copy-paste the following code in the application:</translate></strong></p>
          <copy-input :value="code" />
        </div>
      </div>
    </section>
  </main>
</template>

<script>
import axios from 'axios'

import { checkRedirectToLogin } from '~/utils'
import useSharedLabels from '~/composables/locale/useSharedLabels'
export default {
  props: {
    clientId: { type: String, required: true },
    redirectUri: { type: String, required: true },
    scope: { type: String, required: true },
    responseType: { type: String, required: true },
    nonce: { type: String, required: true },
    state: { type: String, required: true }
  },
  setup () {
    const sharedLabels = useSharedLabels()
    return { sharedLabels }
  },
  data () {
    return {
      application: null,
      isLoading: false,
      errors: [],
      code: null,
      knownScopes: [
        { id: 'profile', icon: 'user' },
        { id: 'libraries', icon: 'book' },
        { id: 'favorites', icon: 'heart' },
        { id: 'listenings', icon: 'music' },
        { id: 'follows', icon: 'users' },
        { id: 'playlists', icon: 'list' },
        { id: 'radios', icon: 'rss' },
        { id: 'filters', icon: 'eye slash' },
        { id: 'notifications', icon: 'bell' },
        { id: 'edits', icon: 'pencil alternate' },
        { id: 'security', icon: 'lock' },
        { id: 'reports', icon: 'warning sign' }
      ]
    }
  },
  computed: {
    labels () {
      return {
        title: this.$pgettext('Head/Authorize/Title', 'Allow application')
      }
    },
    requestedScopes () {
      return (this.scope || '').split(' ')
    },
    supportedScopes () {
      const supported = ['read', 'write']
      this.knownScopes.forEach(s => {
        supported.push(`read:${s.id}`)
        supported.push(`write:${s.id}`)
      })
      return supported
    },
    unknownRequestedScopes () {
      const self = this
      return this.requestedScopes.filter(s => {
        return self.supportedScopes.indexOf(s) < 0
      })
    },
    topicScopes () {
      const self = this
      const requested = this.requestedScopes
      let write = false
      let read = false
      if (requested.indexOf('read') > -1) {
        read = true
      }
      if (requested.indexOf('write') > -1) {
        write = true
      }

      return this.knownScopes.map(s => {
        const id = s.id
        return {
          id: id,
          icon: s.icon,
          label: self.sharedLabels.scopes[s.id].label,
          description: self.sharedLabels.scopes[s.id].description,
          read: read || requested.indexOf(`read:${id}`) > -1,
          write: write || requested.indexOf(`write:${id}`) > -1
        }
      }).filter(c => {
        return c.read || c.write
      })
    }
  },
  async created () {
    await checkRedirectToLogin(this.$store, this.$router)
    if (this.clientId) {
      this.fetchApplication()
    }
  },
  methods: {
    fetchApplication () {
      this.isLoading = true
      const self = this
      axios.get(`oauth/apps/${this.clientId}/`).then((response) => {
        self.isLoading = false
        self.application = response.data
      }, error => {
        self.isLoading = false
        self.errors = error.backendErrors
      })
    },
    submit () {
      this.isLoading = true
      const self = this
      const data = new FormData()
      data.set('redirect_uri', this.redirectUri)
      data.set('scope', this.scope)
      data.set('allow', true)
      data.set('client_id', this.clientId)
      data.set('response_type', this.responseType)
      data.set('state', this.state)
      data.set('nonce', this.nonce)
      axios.post('oauth/authorize/', data, { headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest' } }).then((response) => {
        if (self.redirectUri === 'urn:ietf:wg:oauth:2.0:oob') {
          self.isLoading = false
          self.code = response.data.code
        } else {
          window.location.href = response.data.redirect_uri
        }
      }, error => {
        self.isLoading = false
        self.errors = error.backendErrors
      })
    }
  }
}
</script>
