<template>
  <div class="q-my-md" v-bind="$attrs">
    <q-field v-model="selectedField" :label="displayName" labelColor="primary" :clearable="isSelected" stack-label
      :rules="rulesExp" lazy-rules="ondemand" @clear="clear" ref="fieldRef">
      <template v-slot:control>
        {{ isSelected ? selectedField.app?.name : "(未選択)" }}
      </template>
      <template v-slot:hint v-if="!isSelected">
        {{ placeholder }}
      </template>
      <template v-slot:append>
        <q-icon name="search" class="cursor-pointer" color="primary" @click="showDg" />
      </template>
    </q-field>
    <div v-if="selectedField.fields && selectedField.fields.length > 0">
      <q-list bordered>
        <q-virtual-scroll style="max-height: 160px;" :items="selectedField.fields" separator v-slot="{ item, index }">
          <q-item :key="index" dense clickable>
            <q-item-section>
              <q-item-label>
                {{ item.label }}
              </q-item-label>
            </q-item-section>
            <q-item-section side>
              <q-btn round flat size="sm" icon="clear" @click="removeField(index)" />
            </q-item-section>
          </q-item>
        </q-virtual-scroll>
      </q-list>
    </div>
    <show-dialog v-model:visible="show" name="フィールド一覧" @close="closeAFBox">
      <AppFieldSelectBox v-model:selectedField="selectedField" :selectType="selectType" ref="afBox"
        :fieldTypes="fieldTypes" />
    </show-dialog>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, ref, watchEffect } from 'vue';
import AppFieldSelectBox from '../AppFieldSelectBox.vue';
import ShowDialog from '../ShowDialog.vue';
import { useFlowEditorStore } from 'stores/flowEditor';

export interface IApp {
  id: string,
  name: string
}
export interface IField {
  name: string,
  code: string,
  type: string,
  label?: string
}

export interface IAppFields {
  app?: IApp,
  fields: IField[]
}

export default defineComponent({
  inheritAttrs: false,
  name: 'AppFieldSelect2',
  components: {
    ShowDialog,
    AppFieldSelectBox
  },
  props: {
    displayName: {
      type: String,
      default: '',
    },
    name: {
      type: String,
      default: '',
    },
    placeholder: {
      type: String,
      default: '',
    },
    modelValue: {
      type: Object,
      default: null
    },
    selectType: {
      type: String,
      default: 'single'
    },
    fieldTypes: {
      type: Array,
      default: () => []
    },
    //例：[val=>!!val ||'入力してください']
    rules: {
      type: String,
      default: undefined
    },
    required: {
      type: Boolean,
      default: false
    },
    requiredMessage: {
      type: String,
      default: ''
    }
  },
  setup(props, { emit }) {
    const show = ref(false);
    const afBox = ref();
    const fieldRef = ref();
    const selectedField = ref<IAppFields>({
      app: undefined,
      fields: []
    });
    if (props.modelValue && 'app' in props.modelValue && 'fields' in props.modelValue) {
      selectedField.value = props.modelValue as IAppFields;
    }
    const store = useFlowEditorStore();

    const clear = () => {
      selectedField.value = {
        fields: []
      };
    }

    const removeField = (index: number) => {
      selectedField.value.fields.splice(index, 1);
    }

    const closeAFBox = (val: string) => {
      if (val == 'OK') {
        console.log(afBox.value);
        selectedField.value = afBox.value.selField;
        fieldRef.value.validate();
      }
    };

    const isSelected = computed(() => {
      return !!selectedField.value.app
    });

    const customExp = props.rules === undefined ? [] : eval(props.rules);
    const errmsg = props.requiredMessage?props.requiredMessage:`${props.displayName}が必須です。`;
    const requiredExp = props.required ? [((val: any) => (val && val.app && val.fields && val.fields.length > 0) || errmsg)] : [];
    const rulesExp = [...requiredExp, ...customExp];

    watchEffect(() => {
      emit('update:modelValue', selectedField.value);
    });

    return {
      store,
      afBox,
      show,
      showDg: () => { show.value = true },
      selectedField,
      clear,
      removeField,
      closeAFBox,
      isSelected,
      rulesExp,
      fieldRef
    };
  }
});
</script>
