<template>
  <div
    class="filters__condition-item"
    :class="{ 'filters__condition-item--loading': filter._?.loading }"
  >
    <div class="filters__field">
      <Dropdown
        :value="filter.field"
        :disabled="disableFilter"
        :fixed-items="true"
        small
        @input="$emit('updateFilter', { field: $event })"
      >
        <DropdownItem
          v-for="field in fields"
          :key="'field-' + field.id"
          :name="field.name"
          :value="field.id"
          :disabled="!hasCompatibleFilterTypes(field, filterTypes)"
        ></DropdownItem>
      </Dropdown>
    </div>
    <div class="filters__type">
      <Dropdown
        :disabled="disableFilter"
        :value="filter.type"
        :fixed-items="true"
        small
        @input="$emit('updateFilter', { type: $event })"
      >
        <DropdownItem
          v-for="fType in allowedFilters(filterTypes, fields, filter.field)"
          :key="fType.type"
          :name="fType.getName()"
          :value="fType.type"
        ></DropdownItem>
      </Dropdown>
    </div>
    <div
      class="filters__value"
      :class="{
        'filters__value--with-after-input': hasAfterValueInputContent,
      }"
    >
      <slot
        name="filterInputComponent"
        :slot-props="{
          filter: filter,
          field: getField(filter.field),
          filterType: getFilterType(filter.type),
        }"
      >
        <component
          :is="getInputComponent(filter.type, filter.field)"
          v-if="fieldCanBeFiltered(fields, filter)"
          ref="filter-value"
          :filter="filter"
          :view="view"
          :is-public-view="isPublicView"
          :fields="fields"
          :disabled="disableFilter"
          :read-only="readOnly"
          @input="$emit('updateFilter', { value: $event })"
        />
      </slot>
      <slot
        name="afterValueInput"
        :slot-props="{
          filter: filter,
          filterType: getFilterType(filter.type),
          emitUpdate: emitUpdate,
        }"
      ></slot>
      <i
        v-if="!fieldIdExists(fields, filter.field)"
        v-tooltip="$t('viewFilterContext.relatedFieldNotFound')"
        class="fas fa-exclamation-triangle color-error"
      ></i>
      <i
        v-if="!fieldIsCompatible(filter.type, filter.field)"
        v-tooltip="$t('viewFilterContext.filterTypeNotFound')"
        class="fas fa-exclamation-triangle color-error"
      ></i>
    </div>
    <a
      class="filters__remove"
      :class="{ 'filters__remove--disabled': disableFilter }"
      @click="!disableFilter && $emit('deleteFilter', $event)"
    >
      <i class="iconoir-bin"></i>
    </a>
  </div>
</template>

<script>
import { hasCompatibleFilterTypes } from '@baserow/modules/database/utils/field'
import viewFilterTypes from '@baserow/modules/database/mixins/viewFilterTypes'

export default {
  name: 'ViewFieldConditionItem',
  mixins: [viewFilterTypes],
  props: {
    filter: {
      type: Object,
      required: true,
    },
    fields: {
      type: Array,
      required: true,
    },
    view: {
      type: Object,
      required: false,
      default: () => {},
    },
    isPublicView: {
      type: Boolean,
      required: false,
      default: false,
    },
    disableFilter: {
      type: Boolean,
      default: false,
    },
    readOnly: {
      type: Boolean,
      required: true,
    },
  },
  computed: {
    hasAfterValueInputContent() {
      return !!this.$scopedSlots.afterValueInput
    },
  },
  methods: {
    hasCompatibleFilterTypes,
    focusValue() {
      if (this.$refs['filter-value']?.focus !== undefined) {
        this.$refs['filter-value'].focus()
      }
    },
    getField(fieldId) {
      return this.fields.find(({ id }) => id === fieldId)
    },
    getFilterType(type) {
      return this.$registry.get('viewFilter', type)
    },
    allowedFilters(filterTypes, fields, fieldId) {
      const field = this.getField(fieldId)
      return Object.values(filterTypes).filter((filterType) => {
        return field !== undefined && filterType.fieldIsCompatible(field)
      })
    },
    getInputComponent(type, fieldId) {
      const field = this.getField(fieldId)
      return this.getFilterType(type).getInputComponent(field)
    },
    fieldCanBeFiltered(fields, filter) {
      return (
        this.fieldIdExists(fields, filter.field) &&
        this.fieldIsCompatible(filter.type, filter.field)
      )
    },
    fieldIdExists(fields, fieldId) {
      return fields.findIndex((field) => field.id === fieldId) !== -1
    },
    fieldIsCompatible(filterType, fieldId) {
      const field = this.getField(fieldId)
      if (!(filterType in this.filterTypes)) {
        return false
      }
      return this.filterTypes[filterType].fieldIsCompatible(field)
    },
    emitUpdate(changes) {
      this.$emit('updateFilter', changes)
    },
  },
}
</script>