<template>
  <div class="RMultiSelect">
    <span class="RMultiSelect-Label">{{ label }}</span>
    <q-select
      v-model="selected"
      :emit-value="false"
      :label="placeholder"
      :options="options"
      borderless
      class="multi-select"
      dense
      dropdown-icon="pgs-shevron-down-off"
      menu-anchor="bottom start"
      multiple
      options-dense
      virtual-scroll-slice-size="10"
      @popup-hide="handleSelectedSearch"
    >
      <template #option="scope">
        <q-item v-bind="scope.itemProps" v-on="scope.itemEvents">
          <q-item-section side>
            <q-checkbox
              :value="scope.selected"
              @input="scope.itemEvents.click"
            />
          </q-item-section>
          <q-item-section>
            <q-item-label v-html="scope.opt.label" />
          </q-item-section>
        </q-item>
      </template>
      <template #before-options>
        <div class="multi-select__custom-header">
          <q-item>
            <q-item-section>
              <q-checkbox
                v-model="isSelectedChange"
                label="Выбрать всё"
                @input="handleAllSelected"
              />
            </q-item-section>
          </q-item>
        </div>
      </template>
    </q-select>
  </div>
</template>

<script lang="ts">
import { Component, Model, Prop, Vue, Watch } from 'vue-property-decorator';

interface Option {
  label: string;
  value: string;
}

@Component
export default class RMultiSelect extends Vue {
  @Prop() label?: string;
  @Prop() placeholder?: string;
  @Prop({ default: [] }) private options: [];
  @Model('input', { default: () => [] }) private status!: [];
  private selected: Option[] = [];
  private hasActiveSelected = false;
  private isSelectedChange: boolean | null = false;

  @Watch('selected')
  checkSelectedLength(val: string): void {
    this.isSelectedChange =
      val.length === 0
        ? false
        : val.length === this.options.length
        ? true
        : null;
  }

  @Watch('status')
  resetStatus(val: []): void {
    if (val.length === 0) {
      this.selected = [];
      this.hasActiveSelected = false;
    } else {
      this.selected = val;
      this.hasActiveSelected = true;
    }
  }

  handleSelectedSearch(): void {
    const result = this.selected.length ? this.selected : undefined;
    if (result !== undefined) {
      this.isSelectedChange = false;
      this.$emit('input', result);
      this.hasActiveSelected = true;
    } else {
      this.selected = [];
      this.hasActiveSelected = false;
      this.isSelectedChange = false;
      this.$emit('input', []);
    }
  }

  handleAllSelected(): void {
    if (this.selected.length === this.options.length) {
      this.selected = [];
    } else {
      this.selected = [...this.options];
    }
  }
}
</script>

<style lang="sass">
.RMultiSelect
  &-Label
    font-family: 'Golos Text', sans-serif
    font-style: normal
    font-weight: 600
    font-size: 12px
    line-height: 16px
    color: rgba(2, 12, 18, 0.58)
    margin-bottom: 4px
.q-field--auto-height.q-field--dense .q-field__control
  height: 39px
  min-height: 39px
  padding: 0 8px !important
.multi-select__custom-header
  :hover
    background-color: #e4e4e4
    cursor: pointer
.multi-select .q-field__native
  white-space: nowrap
  max-width: 900px
  overflow: hidden
  text-overflow: ellipsis
  max-height: 27px
  span
    max-width: 50vw // иначе, по неизвестной причине, ломался grid layout при выборе больше чем 3 статуса (на примере со статусом)
.q-select--with-chips .hide-chip-overflow .q-chip__content
    overflow: hidden
</style>
