<template>
<!-- <q-toolbar class="bg-grey-3" flat dense round icon="menu" aria-label="Menu" @click.stop>
  <q-toolbar-title>条件エディタ</q-toolbar-title>
  <q-space></q-space>
  <q-btn  flat round dense icon="info" color="blue" @click="showingCondition=!showingCondition"></q-btn>
</q-toolbar> -->
<div class="q-pa-md">
    <q-tree  :nodes="[tree.root]" node-key="index" children-key="children"
          tick-strategy="strict" v-model:ticked="ticked" :expanded="expanded" default-expand-all dense color="primary" >
      <template v-slot:header-root="prop">
        <!-- root -->
        <div class="row items-center" @click.stop>
          <q-select v-model="prop.node.logicalOperator" :options="logicalOperators" filled outlined dense></q-select>
          <q-btn flat round dense icon="more_horiz" size="sm" >
            <q-menu  auto-close anchor="top right">
                <q-list>
                  <q-item clickable @click="addGroup(prop.node, LogicalOperator.AND)">
                    <q-item-section avatar><q-icon name="playlist_add" ></q-icon></q-item-section>
                    <q-item-section>グループの追加</q-item-section>
                  </q-item>
                  <q-item clickable @click="addCondition(prop.node)">
                    <q-item-section avatar><q-icon name="add_circle_outline" ></q-icon></q-item-section>
                    <q-item-section >条件式の追加</q-item-section>
                  </q-item>
                </q-list>
              </q-menu>
          </q-btn>
        </div>
      </template>
      <template v-slot:header-generic="prop">
          <!-- logic group -->
          <div v-if="prop.node.type !== NodeType.Condition" class="row items-center" @click.stop>
            <q-select v-model="prop.node.logicalOperator" :options="logicalOperators" :outlined="true" :filled="true" :dense="true"></q-select>
            <q-btn flat round dense icon="more_horiz" size="sm" >
              <q-menu  auto-close anchor="top right">
                  <q-list>
                    <q-item clickable @click="moveUp(prop.node)">
                      <q-item-section avatar><q-icon name="arrow_upward" ></q-icon></q-item-section>
                      <q-item-section >一つ上に移動</q-item-section>
                    </q-item>
                    <q-item clickable @click="moveDown(prop.node)">
                      <q-item-section avatar><q-icon name="arrow_downward" ></q-icon></q-item-section>
                      <q-item-section >一つ下に移動</q-item-section>
                    </q-item>
                    <q-separator inset/>
                    <q-item clickable @click="addGroup(prop.node, LogicalOperator.AND)">
                      <q-item-section avatar><q-icon name="playlist_add" ></q-icon></q-item-section>
                      <q-item-section >グループ追加</q-item-section>
                    </q-item>
                    <q-item clickable @click="addCondition(prop.node)">
                      <q-item-section avatar><q-icon name="add_circle_outline" ></q-icon></q-item-section>
                      <q-item-section >条件式追加</q-item-section>
                    </q-item>
                    <q-separator inset/>
                    <q-item clickable  @click="splitGroup(prop.node)">
                      <q-item-section avatar><q-icon name="playlist_remove" color="negative"></q-icon></q-item-section>
                      <q-item-section >グループ化解除</q-item-section>
                    </q-item>
                    <q-item clickable  @click="removeNode(prop.node)">
                      <q-item-section avatar><q-icon name="delete" color="negative"></q-icon></q-item-section>
                      <q-item-section >削除</q-item-section>
                    </q-item>
                  </q-list>
                </q-menu>
             </q-btn>
          </div>
          <!-- condition -->
          <div @click.stop @keypress.stop v-else >
            <div class="row no-wrap items-center q-my-xs">
              <ConditionObject v-bind="prop.node" v-model="prop.node.object" :config="leftDynamicItemConfig" class="col-4"/>
              <q-select  v-model="prop.node.operator" :options="operators"  class="operator" :outlined="true" :dense="true"></q-select>
              <ConditionObject v-bind="prop.node" v-model="prop.node.value" :config="rightDynamicItemConfig" class="col-4"
              :options="objectValueOptions(prop.node?.object?.options)"
              />
              <!-- <ConditionObject v-bind="prop.node" v-model="prop.node.object" class="col-4"/> -->
              <!-- <q-input v-if="!prop.node.object || !('options' in prop.node.object)"
                        v-model="prop.node.value"
                        class="condition-value" :outlined="true" :dense="true" ></q-input> -->
              <!-- <q-select v-if="prop.node.object && ('options' in prop.node.object)"
                        v-model="prop.node.value"
                        :options="objectValueOptions(prop.node.object.options)"
                        clearable
                        value-key="index"
                        class="condition-value" :outlined="true" :dense="true" ></q-select> -->
              <q-btn flat round dense icon="more_horiz" size="sm" >
              <q-menu  auto-close anchor="top right">
                  <q-list>
                    <q-item clickable @click="moveUp(prop.node)">
                      <q-item-section avatar><q-icon name="arrow_upward" ></q-icon></q-item-section>
                      <q-item-section >一つ上に移動</q-item-section>
                    </q-item>
                    <q-item clickable @click="moveDown(prop.node)">
                      <q-item-section avatar><q-icon name="arrow_downward" ></q-icon></q-item-section>
                      <q-item-section >一つ下に移動</q-item-section>
                    </q-item>
                    <q-separator inset/>
                    <q-item clickable  @click="groupMerge(prop.node)" v-if="canMerge(prop.node)">
                      <q-item-section avatar><q-icon name="playlist_add"></q-icon></q-item-section>
                      <q-item-section >グループ化</q-item-section>
                    </q-item>
                    <q-separator inset/>
                    <q-item clickable  @click="removeNode(prop.node)">
                      <q-item-section avatar><q-icon name="delete" color="negative"></q-icon></q-item-section>
                      <q-item-section>削除</q-item-section>
                    </q-item>
                  </q-list>
                </q-menu>
             </q-btn>
            </div>
          </div>
      </template>
    </q-tree>
   <q-tooltip anchor="center middle" v-model="showingCondition" no-parent-event>
import { finished } from 'stream';
      {{ conditionString }}
    </q-tooltip>
  </div>
</template>
<script lang="ts">
import { defineComponent,ref,reactive, computed, inject } from 'vue';
import { INode,ConditionTree,GroupNode,ConditionNode, LogicalOperator,Operator,NodeType } from '../../types/Conditions';
import ConditionObject from './ConditionObject.vue';
import { IDynamicInputConfig } from 'src/types/ComponentTypes';
export default defineComponent( {
  name: 'NodeCondition',
  components: {
    ConditionObject
  },
  props:{
    conditionTree: {
      type: ConditionTree,
      default: null
    },
    show:{
      type:Boolean,
      default:false
    }
  },
  setup(props) {
    const ticked= ref([]);
    const showingCondition=ref(false);

    const logicalOperators = computed(()=>{
      const opts=[];
      for(const op in LogicalOperator){
         opts.push(LogicalOperator[op as keyof typeof LogicalOperator]);
      }
      return opts;
    });

    const operatorSet = inject<Array<any>>('Operator')
    const operators = ref(operatorSet ? operatorSet : Object.values(Operator));
    const tree = reactive(props.conditionTree);

    const conditionString = computed(()=>{
        return tree.buildConditionString(tree.root);
    });

    const objectValueOptions=(options:any):any[]|null=>{
      if(!options){
        return null;
      }
      const opts:any[] =[];
      Object.keys(options).forEach((key) =>
      {
        const opt=options[key];
         opts.push(opt);
      });
      return opts;
    };

    const addGroup = (parent:GroupNode, logicOp:LogicalOperator) => {
      if(!parent){
        parent=tree.root;
      }
      tree.addNode(parent,new GroupNode(logicOp,parent));
    };

    const addCondition = (parent:GroupNode) => {
      const newNode = new ConditionNode({},Operator.Equal,'',parent);
      tree.addNode(parent,newNode);
    };

    const removeNode = (node:INode) => {
      tree.removeNode(node);
    };

    const moveUp =(node:INode)=>{
      tree.moveNode(node,'up');
    }

    const moveDown =(node:INode)=>{
      tree.moveNode(node,'down');
    }

    const getConditionJson=()=>{
      return tree.toJson();
    }
    //JsonからConditionTreeのインスタンスを作成
    const LoadCondition=()=>{
      tree.fromJson(conditionString.value);
    }
    //グループ化
    const groupMerge=(node:INode)=>{
       const checkedNodes:INode[]=[];
       const checkedIndexs:number[] = ticked.value;
       checkedIndexs.forEach(index => {
          const node = tree.findByIndex(index);
          if(node){
            checkedNodes.push(node);
          }
       });
       tree.createGroupNode(node,checkedNodes,LogicalOperator.AND);
       ticked.value=[];
    }
    //グループ化可能かをチェックする
    const canMerge =(node:INode)=>{
      const checkedIndexs:number[] = ticked.value;
      const findNode = checkedIndexs.find(index=>node.index===index);
      console.log('findNode=>',findNode!==undefined,findNode);
      return findNode!==undefined;
    }
    //グループ化解散
    const splitGroup=(node:INode)=>{
      tree.dissolveGroupNode(node as GroupNode);
      ticked.value=[];
    }

    const expanded=computed(()=>tree.getGroups(tree.root));
    // addCondition(tree.root);
    const leftDynamicItemConfig = inject<IDynamicInputConfig>('leftDynamicItemConfig');
    const rightDynamicItemConfig = inject<IDynamicInputConfig>('rightDynamicItemConfig');

    return {
      leftDynamicItemConfig,
      rightDynamicItemConfig,
      showingCondition,
      conditionString,
      tree,
      ticked,
      logicalOperators,
      operators,
      addGroup,
      addCondition,
      removeNode,
      moveUp,
      moveDown,
      LogicalOperator,
      Operator,
      NodeType,
      getConditionJson,
      LoadCondition,
      objectValueOptions,
      expanded,
      canMerge,
      groupMerge,
      splitGroup
    };
  },
});
</script>
<style lang="scss">
.condition-value{
  min-width: 200px;
  max-height: 40px;
  margin: 0 2px;
}

.operator{
  min-width: 150px;
  max-height: 40px;
  margin: 0 2px;

  text-align: center;
  font-size: 12pt;
}
</style>
