<template>
  <q-page>
    <q-layout container class="absolute-full shadow-2 rounded-borders">
      <div class="q-pa-sm q-gutter-sm  ">
        <q-drawer side="left" :overlay="true" bordered v-model="drawerLeft" :show-if-above="false" elevated>
          <div class="flex-center fixed-top app-selector">
            <AppSelector />
          </div>

          <div class="flex-center absolute-full" style="padding-top:65px;padding-left:15px;padding-right:15px;">
            <q-scroll-area class="fit" :horizontal-thumb-style="{ opacity: '0' }">
              <EventTree />
            </q-scroll-area>
          </div>

          <div class="flex-center fixed-bottom bg-grey-3 q-pa-md row ">
            <q-btn color="secondary" glossy label="デプロイ" @click="onDeploy" icon="sync" :loading="deployLoading" />
            <q-space></q-space>
            <q-btn color="primary" label="保存" @click="onSaveFlow" icon="save" :loading="saveLoading" />
          </div>
        </q-drawer>
      </div>
      <q-btn flat dense round
              :icon="drawerLeft?'keyboard_double_arrow_left':'keyboard_double_arrow_right'"
              :style="[drawerLeft?{'left':'300px'}:{'left':'0px'}]"
              @click="drawerLeft=!drawerLeft" class="expand" />
      <div class="q-pa-md q-gutter-sm" :style="{minWidth: minPanelWidth}">
        <div class="flowchart" v-if="store.currentFlow" :style="[drawerLeft?{paddingLeft:'300px'}:{}]">
          <node-item v-if="rootNode!==undefined" :key="rootNode.id" :isSelected="rootNode === store.activeNode"
            :actionNode="rootNode" @addNode="addNode" @nodeSelected="onNodeSelected" @nodeEdit="onNodeEdit"
            @deleteNode="onDeleteNode" @deleteAllNextNodes="onDeleteAllNextNodes" @copyFlow="onCopyFlow"></node-item>
        </div>
      </div>
      <PropertyPanel :actionNode="store.activeNode" v-model:drawerRight="drawerRight"></PropertyPanel>
    </q-layout>
    <ShowDialog v-model:visible="showAddAction" name="アクション" @close="closeDg" min-width="500px" min-height="500px">
      <template v-slot:toolbar>
        <q-input  dense debounce="200" v-model="filter" placeholder="検索" clearable>
          <template v-slot:before>
            <q-icon name="search" />
          </template>
        </q-input>
      </template>
      <action-select ref="appDg" name="model" :filter="filter"  type="single"></action-select>
    </ShowDialog>

  </q-page>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue';
import { IActionNode, ActionNode, IActionFlow, ActionFlow, RootAction, IActionProperty } from 'src/types/ActionTypes';
import { storeToRefs } from 'pinia';
import { useFlowEditorStore } from 'stores/flowEditor';
import { useAuthStore } from 'stores/useAuthStore';

import NodeItem from 'src/components/main/NodeItem.vue';
import ShowDialog from 'components/ShowDialog.vue';
import ActionSelect from 'components/ActionSelect.vue';
import PropertyPanel from 'components/right/PropertyPanel.vue';
import AppSelector from 'components/left/AppSelector.vue';
import EventTree from 'components/left/EventTree.vue';
import { FlowCtrl } from '../control/flowctrl';
import { useQuasar } from 'quasar';
const deployLoading = ref(false);
const saveLoading = ref(false);
const drawerLeft = ref(false);
const $q = useQuasar();
const store = useFlowEditorStore();
const authStore = useAuthStore();

const appDg = ref();
const prevNodeIfo = ref({
  prevNode: {} as IActionNode,
  inputPoint: ""
});
// const refFlow = ref<ActionFlow|null>(null);
const showAddAction = ref(false);
const drawerRight = ref(false);
const filter=ref("");
const model = ref("");
const addActionNode = (action: IActionNode) => {
  // refFlow.value?.actionNodes.push(action);
  store.currentFlow?.actionNodes.push(action);
}
const rootNode = computed(()=>{
  return store.currentFlow?.getRoot();
});
const minPanelWidth=computed(()=>{
  const root = store.currentFlow?.getRoot();
  if(store.currentFlow && root){
    return store.currentFlow?.getColumns(root) * 300 + 'px';
  }else{
    return "300px";
  }
});

const addNode = (node: IActionNode, inputPoint: string) => {
  if (drawerRight.value) {
    drawerRight.value = false;
  }
  showAddAction.value = true;
  prevNodeIfo.value.prevNode = node;
  prevNodeIfo.value.inputPoint = inputPoint;
}

const onNodeSelected = (node: IActionNode) => {
  //右パネルが開いている場合、自動閉じる
  if (drawerRight.value && store.activeNode?.id !== node.id) {
    drawerRight.value = false;
  }
  store.setActiveNode(node);
}

const onNodeEdit = (node: IActionNode) => {
  store.setActiveNode(node);
  drawerRight.value = true;
}

const onDeleteNode = (node: IActionNode) => {
  if (!store.currentFlow) return;
  //右パネルが開いている場合、自動閉じる
  if (drawerRight.value && store.activeNode?.id === node.id) {
    drawerRight.value = false;
  }
  store.currentFlow?.removeNode(node);
}

const onDeleteAllNextNodes = (node: IActionNode) => {
  if (!store.currentFlow) return;
  //右パネルが開いている場合、自動閉じる
  if (drawerRight.value) {
    drawerRight.value = false;
  }
  store.currentFlow?.removeAllNext(node.id);
}
const closeDg = (val: any) => {
  console.log("Dialog closed->", val);
  if (val == 'OK') {
    const data = appDg.value.selected[0];
    const actionProps = JSON.parse(data.property);
    const outputPoint = JSON.parse(data.outputPoints);
    const action = new ActionNode(data.name, data.desc, "", outputPoint, actionProps);
    store.currentFlow?.addNode(action, prevNodeIfo.value.prevNode, prevNodeIfo.value.inputPoint);
  }
}
/*
 *フローのデータをコピーする
 */
const onCopyFlow = () => {
  if (navigator.clipboard) {
    const jsonData =JSON.stringify(store.currentFlow) ;
    navigator.clipboard.writeText(jsonData).then(() => {
      console.log('Text successfully copied to clipboard');
    },
      (err) => {
        console.error('Error in copying text: ', err);
      });
  } else {
    console.log('Clipboard API not available');
  }
};
/**
 * デプロイ
 */
const onDeploy = async () => {
  if (store.appInfo === undefined || store.flows?.length === 0) {
    $q.notify({
      type: 'negative',
      caption: "エラー",
      message: `設定されたフローがありません。`
    });
    return;
  }
  try {
    deployLoading.value = true;
    await store.deploy();
    deployLoading.value = false;
    $q.notify({
      type: 'positive',
      caption: "通知",
      message: `デプロイを成功しました。`
    });
  } catch (error) {
    console.error(error);
    deployLoading.value = false;
    $q.notify({
      type: 'negative',
      caption: "エラー",
      message: `デプロイが失敗しました。`
    })
  }
  return;
}

const onSaveFlow = async () => {
  const targetFlow = store.selectedFlow;
  if (targetFlow === undefined) {
    $q.notify({
      type: 'negative',
      caption: "エラー",
      message: `編集中のフローがありません。`
    });
    return;
  }
  try {
    saveLoading.value = true;
    await store.saveFlow(targetFlow);
    saveLoading.value = false;
    $q.notify({
      type: 'positive',
      caption: "通知",
      message: `${targetFlow.getRoot()?.subTitle}のフロー設定を保存しました。`
    });
  } catch (error) {
    console.error(error);
    saveLoading.value = false;
    $q.notify({
      type: 'negative',
      caption: "エラー",
      message: `${targetFlow.getRoot()?.subTitle}のフローの設定の保存が失敗しました。`
    })
  }

}

const fetchData = async () => {
  drawerLeft.value = true;
  if (store.appInfo === undefined) return;
  const flowCtrl = new FlowCtrl();
  const actionFlows = await flowCtrl.getFlows(store.appInfo?.appId);
  if (actionFlows && actionFlows.length > 0) {
    store.setFlows(actionFlows);
  }
  if (actionFlows && actionFlows.length == 1) {
    store.selectFlow(actionFlows[0]);
  }
  const root = actionFlows[0].getRoot();
  if (root) {
    store.setActiveNode(root);
  }
}

onMounted(() => {
  authStore.toggleLeftMenu();
  fetchData();
});
</script>

<style lang="scss">
.app-selector {
  padding: 15px;
  z-index: 999;
}

.flowchart {
  padding-top: 10px;
}

.flow-toolbar {
  opacity: 50%;
}

.event-tree .q-drawer {
  top: 50px;
  z-index: 999;
}
.expand{
  position: fixed;
  left: 0px;
  top: 50%;
  z-index: 9999;
}
</style>
