<template>
  <div class="root">
    <div class="filters">
      <div v-translate class="title">Filter according to your preferences</div>

      <form @change="onFormChange()">
        <div class="group">
          <label for="profile" v-translate>Your profile</label>

          <b-form-radio-group id="profile" buttons name="profile" v-model="profile">
            <b-form-radio value="viewer">
              <translate>Viewer</translate>
            </b-form-radio>

            <b-form-radio value="video-maker">
              <translate>Video maker</translate>
            </b-form-radio>
          </b-form-radio-group>
        </div>

        <div class="group">
          <label for="profile" v-translate>You want to</label>

          <b-form-radio-group id="wantTo" buttons name="wantTo" v-model="wantTo">
            <b-form-radio value="create-account">
              <translate>Create an account</translate>
            </b-form-radio>

            <b-form-radio value="discover-instances">
              <translate>Discover instances</translate>
            </b-form-radio>
          </b-form-radio-group>
        </div>

        <div class="group">
          <label for="themes" class="label-checkbox" v-translate>Themes</label>

          <b-form-checkbox-group
            v-model="themes"
            :options="availableThemes"
            name="themes"
            id="themes"
            size="lg"
          ></b-form-checkbox-group>
        </div>

        <div class="group">
          <label for="profile" v-translate>Sensitive videos</label>

          <b-form-radio-group id="nsfw" buttons name="nsfw" v-model="nsfw">
            <b-form-radio value="do_not_list">
              <translate>Hide</translate>
            </b-form-radio>

            <b-form-radio value="blur">
              <translate>Blur</translate>
            </b-form-radio>

            <b-form-radio value="display">
              <translate>Display</translate>
            </b-form-radio>

            <b-form-radio value="no-opinion">
              <translate>No opinion</translate>
            </b-form-radio>
          </b-form-radio-group>
        </div>

        <div class="group">
          <label for="instance-languages" class="label-checkbox" v-translate>Instance languages</label>

          <b-form-checkbox-group
            v-model="languages"
            :options="availableLanguages"
            name="instance-languages"
            id="instance-languages"
            size="lg"
          ></b-form-checkbox-group>
        </div>

        <div class="group" v-if="isQuotaEnabled()">
          <label for="quota" v-translate>Allowed video space</label>

          <b-form-select v-model="quota" id="quota" name="quota">
            <option value="1">
              <translate>At least 1GB</translate>
            </option>

            <option value="5">
              <translate>At least 5GB</translate>
            </option>

            <option value="20">
              <translate>At least 20GB</translate>
            </option>

            <option value="50">
              <translate>At least 50GB</translate>
            </option>
          </b-form-select>
        </div>
      </form>
    </div>

    <div class="instances-list">
      <div v-translate class="title">Instances list</div>

      <div class="list">
        <div v-for="instance of instances" class="instance" :key="instance.host">
          <instance-card
            :instance="instance" :isVideoMaker="isVideoMaker()"
            :translatedLanguages="translatedLanguages" :translatedThemes="translatedThemes"
          >
          </instance-card>
        </div>
      </div>

      <div v-if="error" class="alert alert-danger">
        Sorry, but we cannot fetch the instances list. Please retry later.
      </div>

      <div v-if="noResults" class="alert alert-info">
        Sorry, but we did not find any instance matching your filters.
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
  @import '../scss/_variables.scss';

  .title {
    font-size: 24px;
  }

  .filters {
    margin-bottom: 100px;

    .title {
      margin-bottom: 25px;
    }

    form {
      border-left: 6px solid $orange;
      padding-left: 24px;

      .group {
        margin-bottom: 30px;
        display: flex;
        align-items: center;

        & > label {
          min-width: 140px;
          margin: 0 10px 0 0;

          &.label-checkbox {
            align-self: flex-start;
          }
        }
      }

      select {
        width: 280px;
        height: 35px;
        line-height: 21px;
        border-radius: 0;
      }

      .btn-group-toggle {
        .btn {
          display: flex;
          align-items: center;
          color: #000;
          background-color: #fff;
          border-color: $orange;
          height: 30px;
          padding: 0 15px;
          cursor: pointer;

          &.active {
            color: #fff;
            font-weight: $font-semibold;
            background-color: $orange;
          }
        }
      }
    }
  }

  .instances-list {
    margin-bottom: 50px;
  }
</style>

<style lang="scss">
  @import '../scss/_variables.scss';

  .custom-checkbox {
    .custom-control-label > span {
      font-size: 16px;
    }

    .custom-control-input:checked + label {
      font-weight: $font-semibold;
    }
  }

  #themes {
    .custom-control {
      &:nth-child(4n) {
        width: 100px;
        margin-right: 0;
      }

      &:nth-child(4n-1) {
        width: 190px;
      }

      &:nth-child(4n-2) {
        width: 130px;
      }

      &:nth-child(4n-3) {
        width: 100px;
      }
    }
  }

  .instances-list {
    .title {
      margin-bottom: 50px;
    }

    .instance {
      margin-bottom: 40px;
    }
  }
</style>

<script>
  import { BFormCheckboxGroup, BFormRadio, BFormRadioGroup, BFormSelect } from 'bootstrap-vue'
  import axios from 'axios'
  import InstanceCard from './InstanceCard'

  export default {
    components: {
      'b-form-radio-group': BFormRadioGroup,
      'b-form-radio': BFormRadio,
      'b-form-checkbox-group': BFormCheckboxGroup,
      'b-form-select': BFormSelect,
      InstanceCard
    },

    data () {
      return {
        error: false,
        noResults: false,

        instances: [],
        translatedThemes: {
          '1': this.$gettext('Music'),
          '2': this.$gettext('Films'),
          '3': this.$gettext('Vehicles'),
          '4': this.$gettext('Art'),
          '5': this.$gettext('Sports'),
          '6': this.$gettext('Travels'),
          '7': this.$gettext('Gaming'),
          '8': this.$gettext('People'),
          '9': this.$gettext('Comedy'),
          '10': this.$gettext('Entertainment'),
          '11': this.$gettext('News & Politics'),
          '12': this.$gettext('How To'),
          '13': this.$gettext('Education'),
          '14': this.$gettext('Activism'),
          '15': this.$gettext('Science & Technology'),
          '16': this.$gettext('Animals'),
          '17': this.$gettext('Kids'),
          '18': this.$gettext('Food')
        },
        translatedLanguages: {
          'en': this.$gettext('English'),
          'fr': this.$gettext('Français'),
          'ja': this.$gettext('日本語'),
          'eu': this.$gettext('Euskara'),
          'ca': this.$gettext('Català'),
          'cs': this.$gettext('Čeština'),
          'eo': this.$gettext('Esperanto'),
          'el': this.$gettext('ελληνικά'),
          'de': this.$gettext('Deutsch'),
          'it': this.$gettext('Italiano'),
          'nl': this.$gettext('Nederlands'),
          'es': this.$gettext('Español'),
          'oc': this.$gettext('Occitan'),
          'gd': this.$gettext('Gàidhlig'),
          'zh': this.$gettext('简体中文（中国）'),
          'pt': this.$gettext('Português (Portugal)'),
          'sv': this.$gettext('svenska'),
          'pl': this.$gettext('Polski'),
          'fi': this.$gettext('suomi'),
          'ru': this.$gettext('русский')
        },

        profile: 'viewer',
        wantTo: 'create-account',
        themes: [],
        nsfw: 'no-opinion',
        languages: [],
        quota: '5'
      }
    },

    computed: {
      availableThemes: function () {
        const result = []

        for (const key of Object.keys(this.translatedThemes)) {
          result.push({
            value: key,
            text: this.translatedThemes[key]
          })
        }

        return result
      },

      availableLanguages: function () {
        const available = [
          {
            value: 'en',
            text: this.translatedLanguages['en']
          }
        ]

        const navigatorLanguage = window.navigator.userLanguage || window.navigator.language
        const smallLanguage = navigatorLanguage.split('-')[0]

        const found = this.translatedLanguages[smallLanguage]
        if (found && smallLanguage !== 'en') {
          available.push({
            value: smallLanguage,
            text: found
          })
        }

        return available
      }
    },

    methods: {
      isVideoMaker () {
        return this.profile === 'video-maker'
      },

      wantToRegister () {
        return this.wantTo === 'create-account'
      },

      // Thanks https://stackoverflow.com/a/6274381
      shuffle (a) {
        for (let i = a.length - 1; i > 0; i--) {
          const j = Math.floor(Math.random() * (i + 1));
          [a[i], a[j]] = [a[j], a[i]]
        }

        return a
      },

      onFormChange () {
        console.log('Updating instances list.')

        this.fetchInstances()
      },

      isQuotaEnabled () {
        return this.isVideoMaker() && this.wantToRegister()
      },

      fetchInstances () {
        this.noResults = false

        const params = {
          start: 0,
          count: 250,
          healthy: true,
          search: 'peertube2'
        }

        if (this.wantTo === 'create-account') params.signup = true
        if (this.themes.length !== 0) params.categoriesOr = this.themes
        if (this.nsfw !== 'no-opinion') params.nsfwPolicy = [ this.nsfw ]
        if (this.languages.length !== 0) params.languagesOr = this.languages
        if (this.isQuotaEnabled()) params.minUserQuota = this.quota

        const options = {
          method: 'GET',
          params
        }

        axios('https://instances.joinpeertube.org/api/v1/instances', options)
          .then(response => {
            this.instances = this.shuffle(response.data.data)

            if (this.instances.length === 0) this.noResults = true
          })
          .catch(err => {
            console.error(err)
            this.error = true
          })
      }
    },

    mounted () {
      this.fetchInstances()
    }
  }
</script>
