<template>
  <div class="add-field-wrapper">
    <button
      ref="addFieldBtnRef"
      class="add-field-btn btn btn-xs btn-icon"
      :title="tooltip"
      @click.stop="toggleFieldtypeOptions"
    >
      <slot>
        {{ t("Add field") }}
      </slot>
    </button>
    <Teleport to="body">
      <div 
        v-show="show" 
        ref="autocompleteRef" 
        class="autocomplete-dropdown"
        :style="dropdownStyle"
      >
        <Autocomplete
          v-model:show="show"
          :value="autocompleteValue"
          :options="fields"
          @change="addNewField"
          :placeholder="t('Search fieldtypes...')"
        />
      </div>
    </Teleport>
  </div>
</template>

<script setup>
import Autocomplete from "./Autocomplete.vue";
import { useFormBuilderStore, ALL_FIELDTYPES, LAYOUT_FIELDS } from "../store";
import { cloneField, inList } from "../utils";
import { computed, nextTick, ref, watch } from "vue";
import { onClickOutside } from "@vueuse/core";
import { t } from '@/shared/i18n';

const store = useFormBuilderStore();

const props = defineProps({
  column: {
    type: Object,
    default: null,
  },
  field: {
    type: Object,
    default: null,
  },
  tooltip: {
    type: String,
    default: "Add field",
  },
});

const emit = defineEmits(["update:modelValue"]);

const selected = computed(() => {
  let fieldname = props.field ? props.field.df.name : props.column.df.name;
  return store.selected(fieldname);
});

const show = ref(false);
const autocompleteValue = ref("");
const dropdownStyle = ref({});

const fields = computed(() => {
  let fieldList = ALL_FIELDTYPES
    .filter((df) => {
      if (inList(LAYOUT_FIELDS, df)) {
        return false;
      }
      return true;
    })
    .map((df) => {
      let out = { label: df, value: df };
      return out;
    });
  return [...fieldList];
});

const addFieldBtnRef = ref(null);
const autocompleteRef = ref(null);

onClickOutside(addFieldBtnRef, () => (show.value = false), { ignore: [autocompleteRef] });

function updatePosition() {
  if (!addFieldBtnRef.value || !show.value) return;
  
  const rect = addFieldBtnRef.value.getBoundingClientRect();
  dropdownStyle.value = {
    position: 'fixed',
    top: `${rect.bottom + 4}px`,
    left: `${rect.left}px`,
    minWidth: '200px',
    zIndex: 1000,
  };
}

function toggleFieldtypeOptions() {
  show.value = !show.value;
  autocompleteValue.value = "";
  nextTick(() => updatePosition());
}

function addNewField(field) {
  const fieldtype = field?.value;

  if (!fieldtype) return;

  let newField = {
    df: store.getDf(fieldtype),
    table_columns: [],
  };

  let clonedField = cloneField(newField);

  // insert new field after current field
  let index = 0;
  if (props.field) {
    index = props.column.fields.indexOf(props.field);
  }
  props.column.fields.splice(index + 1, 0, clonedField);
  store.form.selected_field = clonedField.df;
  show.value = false;
}

watch(selected, (val) => {
  if (!val) show.value = false;
});

defineExpose({ open: toggleFieldtypeOptions });
</script>

<style lang="scss" scoped>
.add-field-wrapper {
  display: inline-block;
}

.add-field-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px 8px;
  border: 1px solid #d1d5db;
  border-radius: 4px;
  background-color: #fff;
  cursor: pointer;
  font-size: 12px;
  
  &:hover {
    background-color: #f9fafb;
  }
}

.autocomplete-dropdown {
  z-index: 1000;
}
</style>
