<script setup lang="ts">
import { ref, watch } from 'vue';
import { $t } from '@/locales';
import NodeWrap from './modules/nodes/node-wrap.vue';
import StartNode from './modules/nodes/start-node.vue';

defineOptions({
  name: 'SnailWorkflow'
});

interface Props {
  modelValue?: Workflow.NodeDataType;
  spinning?: boolean;
  disabled?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  disabled: false,
  spinning: false,
  modelValue: () => ({})
});

interface Emits {
  (e: 'update:modelValue', modelValue: Workflow.NodeDataType): void;
  (e: 'save'): void;
  (e: 'cancel'): void;
}

const emit = defineEmits<Emits>();

const zoom = ref<number>(100);
const nodeData = ref<Workflow.NodeDataType>({});

const save = async () => {
  emit('save');
};

const cancel = () => {
  emit('cancel');
};

watch(
  () => props.modelValue,
  val => {
    nodeData.value = val;
  },
  { immediate: true, deep: true }
);

watch(
  () => nodeData.value,
  val => {
    emit('update:modelValue', val);
  }
);

const onZoom = (n: number) => {
  zoom.value += 10 * n;

  if (zoom.value <= 10) {
    zoom.value = 10;
  } else if (zoom.value >= 300) {
    zoom.value = 300;
  }
};
</script>

<template>
  <div class="workflow">
    <div class="workflow-affix">
      <NAffix :trigger-top="0">
        <div class="header">
          <div>
            <NTooltip>
              <template #trigger>
                <NButton type="info" size="small" strong @click="onZoom(-1)">
                  <icon-ant-design:minus-outlined />
                </NButton>
              </template>
              缩小
            </NTooltip>
            <span class="ml-8px mr-8px text-18px text-#333639 dark:text-#d6d6d6">{{ zoom }}%</span>
            <NTooltip>
              <template #trigger>
                <NButton type="info" size="small" strong @click="onZoom(1)">
                  <icon-ant-design:plus-outlined />
                </NButton>
              </template>
              放大
            </NTooltip>
          </div>
          <div v-if="!disabled" class="buttons">
            <NButton type="info" @click="save">保存</NButton>
            <NButton class="ml-16px" @click="cancel">取消</NButton>
          </div>
        </div>
      </NAffix>
      <div class="workflow-body">
        <NSpin :show="spinning">
          <div class="workflow-design" :style="`transform: scale(${zoom / 100})`">
            <div class="box-scale">
              <StartNode v-model="nodeData" :disabled="disabled" />
              <NodeWrap v-if="nodeData.nodeConfig" v-model="nodeData.nodeConfig" :disabled="disabled" />
              <div class="end-node">
                <div class="end-node-circle"></div>
                <div class="end-node-text">{{ $t('workflow.node.endNode') }}</div>
              </div>
            </div>
          </div>
        </NSpin>
      </div>
    </div>
  </div>
</template>

<style lang="scss">
@import './styles/index';

.workflow {
  padding: 0 !important;

  &-affix {
    .header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
      background-color: #fff;
      box-sizing: border-box;
      padding: 8px 16px;
    }
  }

  &-body {
    overflow: auto;
    height: calc(100vh - 198px);
  }

  &-design {
    margin-top: 16px;
    transform-origin: 0 0 !important;
  }
}

.dark {
  .workflow {
    &-affix {
      .header {
        box-shadow: 0 1px 4px rgba(255, 255, 255, 0.08);
        background-color: #121212;
      }
    }
  }
}
</style>
