<i18n>
{
  "ru": {
    "EmployeesSelect": {
      "cancel": "Отмена",
      "save": "Сохранить",
      "select": "Выбрать сотрудника",
      "selectAnother": "Выбрать другого сотрудника",
      "impossibleToChange": "Невозможно поменять сотрудника в сохраненном расписании",
      "columns": {
        "FIO": "ФИО",
        "email": "Email"
      },
      "selected": "Сотрудник не выбран | Выбран сотрудник | Выбрано {n} сотрудника | Выбрано {n} сотрудников",
      "impossibleToSelect": "Нельзя добавить сотрудника в два расписания одновременно"
    }
  },
  "en": {
    "EmployeesSelect": {
      "cancel": "Cancel",
      "save": "Save",
      "select": "Select employee",
      "selectAnother": "Select another employee",
      "impossibleToChange": "Impossible to change employee in saved schedule",
      "columns": {
        "FIO": "Full name",
        "email": "Email"
      },
      "selected": "No employee selected | Employee is selected | {n} employees are selected",
      "impossibleToSelect": "It's impossible to add one person into two schedules"
    }
  }
}
</i18n>
<template>
  <div class="employees-select">
    <template v-if="selected.length">
      <q-card
        bordered
        flat
        v-for="employee in selected"
        :key="employee.id"
        @click="!isScheduleSaved && openPopup()"
        :class="[
          'employees-select__card',
          {
            'cursor-pointer': !isScheduleSaved,
          },
        ]"
        :title="
          isScheduleSaved
            ? $t('EmployeesSelect.impossibleToChange')
            : $t('EmployeesSelect.selectAnother')
        "
      >
        <q-card-section class="q-pa-sm">
          <div class="employees-select__name">
            {{ employee.person.firstname }} {{ employee.person.surname }}
          </div>
          <div style="font-size: 0.8em">{{ employee.person.email }}</div>
        </q-card-section>
      </q-card>
    </template>
    <q-btn
      outline
      color="grey-6"
      text-color="black"
      v-else
      class="full-width"
      @click="openPopup()"
    >
      {{ $t('EmployeesSelect.select') }}
    </q-btn>
    <q-dialog v-model="popup" persistent>
      <q-card
        :style="{
          maxWidth: '80vw',
          width: '700px',
        }"
      >
        <q-card-section>
          <div class="select-table">
            <q-tabs align="right" dense active-color="green" v-model="tab">
              <q-tab name="all" icon="add_circle_outline" />
              <q-tab name="selected" icon="task_alt" />
            </q-tabs>
            <q-separator />
            <q-tab-panels :value="tab">
              <q-tab-panel name="all">
                <q-table
                  dense
                  class="no-shadow text-grey-9"
                  row-key="id"
                  :selected-rows-label="
                    (number) => $tc('EmployeesSelect.selected', number)
                  "
                  :rows-per-page-options="[5, 10, 15]"
                  :columns="columns"
                  :pagination.sync="pagination"
                  :grid="$q.screen.xs"
                  :loading="loading"
                  saveQuery
                  :data="model"
                  :selection="selection"
                  :selected.sync="selected"
                  @request="init"
                  @update="init"
                  @selection="touch"
                >
                  <template v-slot:body-selection="scope">
                    <q-checkbox v-model="scope.selected" />
                  </template>
                </q-table>
              </q-tab-panel>
              <q-tab-panel name="selected">
                <q-table
                  dense
                  class="no-shadow text-grey-9"
                  row-key="id"
                  :selected-rows-label="
                    (number) => $tc('EmployeesSelect.selected', number)
                  "
                  :rows-per-page-options="[5, 10, 15]"
                  :columns="columns"
                  :grid="$q.screen.xs"
                  :loading="loading"
                  :data="selected"
                  :selection="selection"
                  :selected.sync="selected"
                  @selection="touch"
                >
                  <template v-slot:body-selection="scope">
                    <q-checkbox v-model="scope.selected" />
                  </template>
                </q-table>
              </q-tab-panel>
            </q-tab-panels>
          </div>
        </q-card-section>
        <q-card-actions align="right">
          <q-btn
            dense
            text-color="primary"
            color="white"
            :label="$t('EmployeesSelect.cancel')"
            @click="clear"
            v-close-popup
          />
          <q-btn
            dense
            text-color="primary"
            color="white"
            :disable="!dirty"
            @click="save"
          >
            {{ $t('EmployeesSelect.save') }}
          </q-btn>
        </q-card-actions>
      </q-card>
    </q-dialog>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import WeekSchedule from '@components/tickets/components/WeekSchedule.vue';
import { EmployeeDTO } from '@openapi/preorder-pgs';
import { AccountApi, Account } from '@openapi/idm';
import get from 'lodash/get';
const accountApi = new AccountApi();

interface Pagination {
  page?: number;
  rowsPerPage?: number;
  descending?: boolean;
  sortBy?: string;
  rowsNumber?: number;
}
interface TableContext {
  pagination: Pagination;
}
type Employee = Omit<EmployeeDTO, 'filter'>;

@Component({
  components: {
    WeekSchedule,
  },
  methods: {
    get,
  },
})
export default class EmployeesSelect extends Vue {
  @Prop({ default: false }) private isScheduleSaved: boolean;
  @Prop({ default: () => [] }) private unavelible: string[];
  @Prop({ default: () => [] }) private value: Employee[];
  @Prop({ default: '' }) private valueIdKey: keyof Employee;
  @Prop({ default: 'single' }) private selection: 'multiple' | 'single';

  loading = false;
  private dirty = false;

  touch(): void {
    this.dirty = true;
  }

  clear(): void {
    this.fetchSelected(this.value);
    this.dirty = false;
  }

  private popup = false;
  private tab = 'all';

  public openPopup(): void {
    this.popup = true;
  }

  public closePopup(): void {
    this.popup = false;
    this.tab = 'all';
  }

  private model: Account[] = [];
  private selected: Account[] = [];
  sortByDefault: 'name';
  pagination: Pagination = {
    page: 1,
    rowsPerPage: 5,
    descending: false,
    sortBy: 'name',
    rowsNumber: 0,
  };

  queryString = '';
  fulltextString = '';

  get columns(): any[] {
    return [
      {
        align: 'left',
        field: (val: any) => get(val, 'person', ''),
        label: this.$t('EmployeesSelect.columns.FIO'),
        name: 'person.surname',
        sortable: true,
        style: 'width:450px',
        format: (val: any) => {
          if (val && typeof val === 'object') {
            return `${get(val, 'surname', '')} ${get(
              val,
              'firstname',
              ''
            )} ${get(val, 'middlename', '')} `;
          }
          return '';
        },
        handlerField: 'id',
        icon: 'people_outline',
      },
      {
        align: 'left',
        field: (val: any) => val.person.email,
        label: this.$t('EmployeesSelect.columns.email'),
        name: 'person.email',
        sortable: true,
        style: 'width:450px',
      },
    ];
  }

  private isEmployeeUnavelible(id: string): boolean {
    return this.unavelible.includes(id);
  }

  get userDomainId(): string {
    return get(this.$store.getters['oidcClient/currentUser'], 'domain_id', '');
  }

  @Watch('value', { immediate: true })
  private onValueChange(value: Employee[]): void {
    this.fetchSelected(value);
  }

  save(): void {
    const values = this.selected.map((itm) => {
      return {
        [this.valueIdKey]: itm.id,
      };
    });
    this.$emit('input', values);
    this.closePopup();
  }

  created(): void {
    this.fetch();
  }

  init<T extends TableContext>(context: T): void {
    if (context?.pagination) {
      this.pagination.page = context.pagination.page;
      this.pagination.rowsPerPage = context.pagination.rowsPerPage;
      this.pagination.descending = context.pagination.descending;
      this.pagination.sortBy =
        context.pagination.sortBy == null
          ? this.sortByDefault
          : context.pagination.sortBy;
    }
    this.fetch();
  }

  async fetch(): Promise<void> {
    this.loading = true;
    const response = await accountApi.findAccountsDepartmentsByOrganizationId(
      this.userDomainId,
      this.pagination.page,
      this.pagination.rowsPerPage,
      `${this.pagination.descending ? '-' : '+'}${this.pagination.sortBy}`,
      'user-domain,roles,person',
      this.queryString,
      this.fulltextString
    );

    this.model = get(response, 'data.records') as Account[];
    this.pagination.rowsNumber = get(response, 'data.totalRows') as number;
    this.onValueChange(this.value);
    this.loading = false;
  }

  async fetchSelected(value: EmployeeDTO[]): Promise<void> {
    const listOfIds = value.map(({ employeeId }) => `'${employeeId}'`);
    if (!listOfIds.length) {
      this.selected = [];
      return;
    }
    this.loading = true;
    try {
      const response = await accountApi.searchAccounts(
        'my',
        `id =in= (${listOfIds.join()})`,
        this.fulltextString,
        `${this.pagination.descending ? '-' : '+'}${this.pagination.sortBy}`,
        'person'
      );
      this.selected = get(response, 'data') as unknown as Account[];
    } catch (error) {
      this.selected = [];
    }
    this.$emit('select', this.selected);
    this.loading = false;
  }
}
</script>

<style lang="scss" scoped>
.employees-select {
  &__name {
    text-transform: uppercase;
  }
}
.select-table {
  &__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-left: 1rem;
    padding-right: 1rem;
  }
  &__title {
    font-size: 1.25rem;
  }
}
</style>
