<template>
  <div class="rt-filters">
    <q-card bordered>
      <q-table
        selection="single"
        :hide-bottom="true"
        :hide-selected-banner="true"
        :data="filters"
        :selected.sync="selected"
        :columns="columns"
        :visible-columns="visibleColumns"
        :rows-per-page-options="[0]"
        row-key="filterId"
      >
        <template v-slot:body="props">
          <q-tr :key="props.rowIndex" :props="props">
            <td></td>
            <q-td key="globalOperator" :props="props">
              <div v-if="!props.selected">{{ props.row.globalOperator }}</div>
              <q-select
                v-else
                :props="props"
                class="q-mr-sm"
                v-model="props.row.globalOperator"
                :options="globalOperatorOptions"
                label="Тип выражения"
              />
            </q-td>
            <q-td key="guidFilter" :props="props">
              <div v-if="!props.selected">
                {{ getFilterTypeLabel(props.row.guidFilter) }}
              </div>
              <q-select
                v-else
                class="q-mr-sm"
                label="Критерий"
                v-model="selectedFilterType"
                :options="filterTypeOptions"
                @input="handleFilterType"
              />
            </q-td>
            <q-td key="operator" :props="props">
              <div v-if="!props.selected">
                {{ getFilterOperatorLabel(props.row.operator) }}
              </div>
              <q-select
                v-else
                class="q-mr-sm"
                label="Оператор"
                v-model="selectedOperator"
                :options="operatorOptions"
              />
            </q-td>
            <q-td key="value" :props="props">
              <div v-if="!props.selected">{{ props.row.value }}</div>
              <div v-else>
                <q-input
                  v-if="isValueTypeA('TEXT')"
                  v-model="selectedParam"
                  type="text"
                  filled
                  label="Значение"
                />
                <q-input
                  v-if="isValueTypeA('NUMBER')"
                  v-model="selectedParam"
                  :type="'number'"
                  min="0"
                  filled
                  label="Значение"
                />
                <q-btn-toggle
                  v-if="isValueTypeA('BOOLEAN')"
                  v-model="selectedParam"
                  label="Значение"
                  toggle-color="primary"
                  :options="booleanOptions"
                />
                <q-select
                  v-if="isValueTypeA('LIST')"
                  class="q-mr-sm"
                  label="Значение"
                  v-model="selectedParam"
                  :options="searchParamOptions"
                />
              </div>
            </q-td>
            <q-td v-if="!viewMode" key="actions" :props="props">
              <div v-if="!props.selected">
                <q-btn
                  flat
                  dense
                  text-color="primary"
                  icon="edit"
                  size="16"
                  :disabled="!!selected.length"
                  @click="edit(props)"
                />
                <q-btn
                  flat
                  dense
                  text-color="negative"
                  icon="delete"
                  size="16"
                  :disabled="!!selected.length"
                  @click="deleteFilter(props.rowIndex)"
                />
              </div>
              <div v-else>
                <q-btn
                  flat
                  dense
                  text-color="primary"
                  icon="save"
                  size="16"
                  :disabled="
                    !(selectedFilterType.value && selectedParam !== '')
                  "
                  @click="save(props)"
                />
                <q-btn
                  flat
                  dense
                  text-color="negative"
                  icon="delete"
                  size="16"
                  @click="deleteFilter(props.rowIndex)"
                />
              </div>
            </q-td>
          </q-tr>
        </template>
        <template v-slot:bottom-row>
          <q-tr>
            <q-td colspan="6" class="text-right">
              <q-btn
                v-if="!viewMode"
                flat
                dense
                :disable="editMode"
                icon="add"
                size="16"
                @click="add"
              />
            </q-td>
          </q-tr>
        </template>
      </q-table>
    </q-card>
  </div>
</template>

<script lang="js">
import {
  CriteriaFilterGlobalOperatorEnum,
} from '@/openapi/personal-accounts';
import { notifyError, notifySuccess } from '@/utils/notify';
import { cloneDeep } from 'lodash';
import axios from 'axios';

export default {
  name: 'EventFilters',
  props: ['value', 'viewMode', 'visibleColumns'],
  data() {
    return {
      filters: this.value,
      selected: [],
      globalOperatorOptions: Object.values(
        CriteriaFilterGlobalOperatorEnum
      ),
      selectedFilterType: null,
      operatorOptions: [],
      selectedOperator: null,
      selectedParam: '',
      searchParamOptions: [],
      booleanOptions: [
        { label: 'Да', value: 'true' },
        { label: 'Нет', value: 'false' }
      ],
      editMode: false,
      operatorLabels: {
        EQUAL: '==',
        NOT_EQUAL: '!=',
        LIKE: 'LIKE',
        NOT_LIKE: 'NOT_LIKE',
        GREATER_THAN: '>',
        GREATER_THAN_OR_EQUAL: '>=',
        LESS_THAN: '<',
        LESS_THAN_OR_EQUAL: '<=',
      }
    }
  },

  computed: {
    filterTypeOptions() {
      return (this.$store.getters['registryService/additionalSettings/settingsForServiceCard'].settingsforservicecriteria || []).map((e) => {
        return {
          value: e.id,
          label: e.name,
          data: e,
        }
      });
    },
    columns() {
      return [
        {
          align: 'center',
          label: 'Тип выражения',
          name: 'globalOperator',
        },
        {
          align: 'center',
          label: 'Критерий',
          name: 'guidFilter',
        },
        {
          align: 'center',
          label: 'Оператор',
          name: 'operator',
        },
        {
          align: 'center',
          label: 'Значение',
          name: 'value',
        },
        {
          align: 'center',
          label: 'Опции',
          name: 'actions',
        },
      ];
    }
  },

  methods: {
    add() {
      this.editMode = true;
      const filters = this.filters || [];
      const newFilter = cloneDeep({
        guidFilter: '',
        value: '',
        operator: '',
        globalOperator: CriteriaFilterGlobalOperatorEnum.And,
        filterId: '',
      });
      this.selectedFilterType = {
        data: {},
        value: '',
        label: ''
      }
      filters.push(newFilter);
      this.filters = filters;
      this.selected = [newFilter];
      this.selected[0].filterId = this.filters.length.toString();
    },
    handleFilterType(filterType) {
      this.selectedOperator = '';
      this.selectedParam = '';
      if (!this.selected[0]) return;
      this.selected[0].guidFilter = filterType.data.name || '';
      this.getOperatorOptions()
      this.selectedOperator = this.operatorOptions[0];
    },
    save(filter) {
      filter.row.guidFilter = this.selectedFilterType?.data.id || '';
      filter.row.operator = this.selectedOperator?.value;
      filter.row.value = this.selectedParam || '';
      filter.selected = false;
      this.$emit('changeFilter', this.filters);
      this.selectedOperator = '';
      this.selectedParam = '';
      this.editMode = false;
    },
    edit(filter) {
      this.editMode = true;
      this.selected = [this.filters[filter.rowIndex]]
      this.selectedFilterType = this.filterTypeOptions.find(e => e.value === filter.row.guidFilter)
      this.getOperatorOptions();
      this.selectedOperator = this.operatorOptions.find(e => e.value === filter.row.operator);
      this.selectedParam = filter.row.value;
    },
    deleteFilter(index) {
      this.editMode = false;
      if (this.filters == null) return;
      if (index !== -1) {
        this.filters.splice(index, 1);
        this.filters = this.filters.map((e, index) => ({
          ...e,
          filterId: (index + 1).toString(),
        }))
      }
      this.$emit('changeFilter', this.filters);
      this.selected = []
    },

    getOperatorOptions(filterType) {
      this.operatorOptions = []
      switch (this.selectedFilterType.data.type) {
        case 'BOOLEAN':
          this.operatorOptions = [{EQUAL: '=='}, {NOT_EQUAL: '!='}];
          break
        case 'LIST':
          this.operatorOptions = [{EQUAL: '=='}, {NOT_EQUAL: '!='}];
          this.searchParamOptions = this.selectedFilterType.data.values;
          break
        case 'TEXT':
          this.operatorOptions = [{EQUAL: '=='}, {NOT_EQUAL: '!='}, {LIKE: 'LIKE'},{NOT_LIKE: 'NOT_LIKE'}];
          break
        case 'NUMBER':
          this.operatorOptions = [{EQUAL: '=='}, {NOT_EQUAL: '!='}, {GREATER_THAN: '>'},{GREATER_THAN_OR_EQUAL: '>='},{LESS_THAN: '<'},{LESS_THAN_OR_EQUAL: '<='}];
          break
        default:
          this.operatorOptions = [];
      }
      this.operatorOptions = this.operatorOptions.flatMap((op) => {
        return Object.entries(op).map(([value, label]) => {
          return {
            label,
            value,
          };
        }) || [];
      })

    },
    getFilterTypeLabel(type) {
      return this.filterTypeOptions.find(e => e.value === type)?.label || 'КРИТЕРИЙ НЕ НАЙДЕН';
    },
    getFilterOperatorLabel(operator) {
      return this.operatorLabels[operator] || operator;
    },
    isValueTypeA(...types) {
      if (!this.selectedFilterType?.data.type) return false;
      return types.includes(this.selectedFilterType?.data.type);
    },

    noEmptyValueRule(val) {
      if (typeof val === 'number') {
        return true;
      }
      return false
    },
    testNum(val) {
      return val.replace(/[^0-9]/g, '') || ''
    }
  }
}
</script>
