<template>
  <div v-bind="$attrs">
    <q-field v-model="tree" :label="displayName" labelColor="primary" stack-label>
      <template v-slot:control>
        <q-card flat class="full-width">
          <q-card-actions vertical>
            <q-btn color="grey-3" text-color="black" :disable="btnDisable" @click="showDg()">クリックで設定：{{ isSetted ?
              '設定済み' : '未設定' }}</q-btn>
          </q-card-actions>
          <q-card-section class="text-caption">
            <div v-if="!isSetted">{{ placeholder }}</div>
            <div v-else>{{ conditionString }}</div>
          </q-card-section>
        </q-card>
      </template>
    </q-field>
    <condition-editor v-model:show="show" v-model:conditionTree="tree" @closed="onClosed"></condition-editor>
  </div>
</template>

<script lang="ts">
import { ConditionNode, ConditionTree, Operator, OperatorListItem } from 'app/src/types/Conditions';
import { computed, defineComponent, provide, reactive, ref, watchEffect } from 'vue';
import ConditionEditor from '../ConditionEditor/ConditionEditor.vue';
import { IActionProperty } from 'src/types/ActionTypes';

export default defineComponent({
  name: 'FieldInput',
  inheritAttrs: false,
  components: {
    ConditionEditor
  },
  props: {
    context: {
      type: Array<IActionProperty>,
      default: '',
    },
    displayName: {
      type: String,
      default: '',
    },
    name: {
      type: String,
      default: '',
    },
    placeholder: {
      type: String,
      default: '',
    },
    hint: {
      type: String,
      default: '',
    },
    modelValue: {
      type: String,
      default: null
    },
    sourceType: {
      type: String,
      default: 'field'
    },
    connectProps:{
      type:Object,
      default:()=>({})
    },
    onlySourceSelect: {
      type: Boolean,
      default: false
    },
    operatorList: {
      type: Array,
    },
    inputConfig: {
      type: Object,
      default: () => ({
        left: {
          canInput: false,
          buttonsConfig: [
            { label: 'フィールド', color: 'primary', type: 'FieldAdd' },
            { label: '変数', color: 'green', type: 'VariableAdd' },
          ]
        },
        right: {
          canInput: true,
          buttonsConfig: [
            { label: '変数', color: 'green', type: 'VariableAdd' },
          ]
        },
      })
    }
  },

  setup(props, { emit }) {
    let source = reactive(props.connectProps['source']);
    if(!source){
      source = props.context.find(element => element.props.name === 'sources');
    }

    if (source) {
      if (props.sourceType === 'field') {
        provide('sourceFields', computed(() => source.props?.modelValue?.fields ?? []));
      } else if (props.sourceType === 'app') {
        provide('sourceApp', computed(() => source.props?.modelValue?.app?.id));
      }
    }

    provide('leftDynamicItemConfig', props.inputConfig.left);
    provide('rightDynamicItemConfig', props.inputConfig.right);
    provide('Operator', props.operatorList);

    const btnDisable = computed(() => {
      const onlySourceSelect = props.onlySourceSelect;

      if (!onlySourceSelect) {
        return false;
      }

      if (props.sourceType === 'field') {
        return source?.props?.modelValue?.fields?.length ?? 0 > 0;
      } else if (props.sourceType === 'app') {
        return source?.props?.modelValue?.app?.id ? false : true
      }
      return true;
    })

    const appDg = ref();
    const show = ref(false);
    const tree = reactive(new ConditionTree());
    if (props.modelValue && props.modelValue !== '') {
      tree.fromJson(props.modelValue);
    } else {
      const newNode = new ConditionNode({}, (props.operatorList && props.operatorList.length > 0) ? props.operatorList[0] as OperatorListItem : Operator.Equal, '', tree.root);
      tree.addNode(tree.root, newNode);
    }

    const isSetted = ref(props.modelValue && props.modelValue !== '');

    const conditionString = computed(() => {
      const condiStr= tree.buildConditionString(tree.root);
      return condiStr==='()'?'(条件なし)':condiStr;
    });

    const showDg = () => {
      show.value = true;
    };

    const onClosed = (val: string) => {
      if (val == 'OK') {
        isSetted.value = true;
        tree.setQuery(tree.buildConditionQueryString(tree.root));
        const conditionJson = tree.toJson();
        emit('update:modelValue', conditionJson);
      }
    };

    watchEffect(() => {
      tree.setQuery(tree.buildConditionQueryString(tree.root));
      const conditionJson = tree.toJson();
      emit('update:modelValue', conditionJson);
    });

    return {
      appDg,
      isSetted,
      show,
      showDg,
      onClosed,
      tree,
      conditionString,
      btnDisable
    };
  }
});
</script>
