<template>
  <div class="script-manager">
    <!-- 应用版本选择 -->
    <!-- <div class="item-box">
      <div class="title">应用版本</div>
      <el-select v-model="appVersion" placeholder="请选择" class="select-version">
        <el-option
          v-for="version in versions"
          :key="version.value"
          :label="version.label"
          :value="version.value"
        />
      </el-select>
    </div> -->
    <div class="item-box">
      <div class="title">
        <span> 节点信息 </span>
      </div>
      <span @click="showAppInfoFun" class="node-detail-btn">查看详情</span>
    </div>
    <!-- <div class="item-box">
      <div class="title">
        <span>
          前置条件
          <el-tooltip
            class="box-item"
            effect="dark"
            content="前置节点是否全部完成才能开展当前节点工作"
            placement="top-start"
          >
            <el-icon color="#606266"><QuestionFilled /></el-icon>
          </el-tooltip>
        </span>
      </div>
      <el-radio-group :disabled="readonly" v-model="nodeCondition">
        <el-radio value="and">与</el-radio>
        <el-radio value="or">或</el-radio>
      </el-radio-group>
    </div> -->
    <!-- <div class="item-box">
      <div class="title">
        <span>
          执行方式
          <el-tooltip
            class="box-item"
            effect="dark"
            content="节点的执行方式，是后台自动执行或者手动执行"
            placement="top-start"
          >
            <el-icon color="#606266"><QuestionFilled /></el-icon>
          </el-tooltip>
        </span>
      </div>
      <el-radio-group :disabled="readonly" v-model="exeMethod">
        <el-radio value="serviceTask">自动</el-radio>
        <el-radio value="userTask">手动</el-radio>
      </el-radio-group>
    </div> -->
    <div class="item-box">
      <div class="title">
        <span>节点前脚本</span>
        <el-upload
          v-if="!readonly"
          class="upload-btn"
          :multiple="true"
          :auto-upload="false"
          :show-file-list="false"
          @change="(val: any) => changeFileFun('pre', val)"
        >
          <img src="@/assets/imgs/dragFlow/add-script.svg" alt="" />
        </el-upload>
      </div>
      <div class="script-box" v-for="(item, index) in nodeAttribute.preScripts" :key="item.id">
        <div class="s-name">脚本名称</div>
        <div class="operation">
          <el-input v-model="item.name" class="el-input"></el-input>
          <span class="code-view-btn">
            <img
              src="@/assets/imgs/dragFlow/open-code.svg"
              v-if="!item.isPreview"
              @click="changeReviewFun('pre', Number(index))"
              alt=""
            />
            <img
              class="select-ing"
              src="@/assets/imgs/dragFlow/close-code.png"
              v-else
              @click="changeReviewFun('pre', Number(index))"
              alt=""
            />
          </span>
          <el-popconfirm title="确认删除？" @confirm="removeFileFun('pre', Number(index))">
            <template #reference>
              <img src="@/assets/imgs/dragFlow/lessen.svg" alt="" />
            </template>
          </el-popconfirm>
        </div>
        <div class="code-box" v-if="item.isPreview">
          <div class="code-header">
            <span class="s-name">脚本代码</span>
            <div class="edit-code" @click="openCodeDialogFun(item.fileId)">
              在IDE中{{ readonly ? '查看' : '编辑' }}
            </div>
          </div>
          <div class="code-text">
            <MonacoEditor
              :idIndex="item.fileId + item.name"
              readonly
              :file-id="item.fileId"
            ></MonacoEditor>
            <!-- <img src="@/assets/imgs/dragFlow/code.png" alt=""> -->
          </div>
        </div>
      </div>
    </div>
    <div class="item-box">
      <div class="title">
        <span>节点后脚本</span>
        <el-upload
          v-if="!readonly"
          class="upload-btn"
          :multiple="true"
          :auto-upload="false"
          :show-file-list="false"
          @change="(val: any) => changeFileFun('post', val)"
        >
          <img src="@/assets/imgs/dragFlow/add-script.svg" alt="" />
        </el-upload>
      </div>
      <div class="script-box" v-for="(item, index) in nodeAttribute.postScripts" :key="item.id">
        <div class="s-name">脚本名称</div>
        <div class="operation">
          <el-input v-model="item.name" class="el-input"></el-input>
          <span class="code-view-btn" v-if="!readonly">
            <img
              src="@/assets/imgs/dragFlow/open-code.svg"
              v-if="!item.isPreview"
              @click="changeReviewFun('post', Number(index))"
              alt=""
            />
            <img
              class="select-ing"
              src="@/assets/imgs/dragFlow/close-code.png"
              v-else
              @click="changeReviewFun('post', Number(index))"
              alt=""
            />
          </span>
          <el-popconfirm title="确认删除？" @confirm="removeFileFun('post', Number(index))">
            <template #reference>
              <img src="@/assets/imgs/dragFlow/lessen.svg" alt="" />
            </template>
          </el-popconfirm>
        </div>
        <div class="code-box" v-if="item.isPreview">
          <div class="code-header">
            <span class="s-name">脚本代码</span>
            <div class="edit-code" @click="openCodeDialogFun(item.fileId)">
              在IDE中{{ readonly ? '查看' : '编辑' }}
            </div>
          </div>
          <div class="code-text">
            <MonacoEditor
              :idIndex="item.fileId + item.name"
              readonly
              :file-id="item.fileId"
            ></MonacoEditor>
            <!-- <img src="@/assets/imgs/dragFlow/code.png" alt=""> -->
          </div>
        </div>
      </div>
    </div>
    <div class="item-box">
      <div class="title">前脚本执行命令</div>
      <el-input
        :disabled="readonly"
        v-model="preExeCommand"
        placeholder="请输入执行命令"
        class="select-version"
      >
      </el-input>
    </div>
    <div class="item-box">
      <div class="title">节点执行命令</div>
      <el-input
        :disabled="readonly"
        v-model="nodeExeCommand"
        placeholder="请输入执行命令"
        class="select-version"
      >
      </el-input>
    </div>
    <div class="item-box">
      <div class="title">后脚本执行命令</div>
      <el-input
        :disabled="readonly"
        v-model="postExeCommand"
        placeholder="请输入执行命令"
        class="select-version"
      >
      </el-input>
    </div>
    <div class="item-box">
      <div class="title">输入主文件格式</div>
      <el-input
        :disabled="readonly"
        v-model="inputFormat"
        placeholder="请输入正则表达式"
        class="select-version"
      >
      </el-input>
    </div>
    <div class="item-box">
      <div class="title">输入附文件格式</div>
      <el-input
        :disabled="readonly"
        v-model="slaveFormat"
        placeholder="请输入正则表达式"
        class="select-version"
      >
      </el-input>
    </div>
    <div class="item-box">
      <div class="title">输出文件格式</div>
      <el-input
        :disabled="readonly"
        v-model="outputFormat"
        placeholder="请输入正则表达式"
        class="select-version"
      >
      </el-input>
    </div>
    <div class="item-box">
      <div class="title">输入节点</div>
      <el-select :disabled="readonly" v-model="beforeNodeId" placeholder="请选择输入节点">
        <el-option
          v-for="item in nodeListOptions"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
    </div>

    <div class="item-box">
      <div class="title">默认配置</div>
      <el-select :disabled="readonly" v-model="nodeParamConfigName" placeholder="请选节点配置">
        <el-option
          v-for="item in nodeParamOptions"
          :key="item.id"
          :label="item.configName"
          :value="item.configName"
        />
      </el-select>
    </div>
  </div>
  <FleEdit
    :readonly="readonly"
    v-model:showDialog="showCodeEdit"
    :file-id="editFileId"
    :idIndex="editFileId + 'dialog'"
  ></FleEdit>
  <AppInfoDialog
    v-model:showDialog="showAppInfoVisible"
    :nodeAttribute="nodeAttribute"
  ></AppInfoDialog>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue';
import FleEdit from '@/components/common/fileEdit/fileEditDialog/fileEdit.vue';
import { ElMessage } from 'element-plus';
import { upload } from '@/api/request';
import { updateNodeAttribute } from './nodeEvents';
import MonacoEditor from '@/components/common/fileEdit/monacoEditor/index.vue';
import { FLOW_NODE_TYPE_ENUM } from '@/utils/enum/flow';
import AppInfoDialog from './appInfoDialog.vue';
import { queryApplicationConfigApi } from '@/api/system/application';

const props = defineProps({
  nodeAttribute: {
    type: Object,
    default: () => ({}),
  },
  readonly: {
    type: Boolean,
    default: false,
  },
  graph: {
    type: Object,
    default: () => ({}),
  },
});

const env = import.meta.env;
const PREFIX = env.VITE_API_PREFIX_DATA;

// const appVersion = computed({
//   get() {
//     return props.nodeAttribute.appVersion;
//   },
//   set(val) {
//     updateNodeAttribute({ appVersion: val });
//   },
// });

const inputFormat = computed({
  get() {
    return props.nodeAttribute.inputFormat || '';
  },
  set(val) {
    updateNodeAttribute({ inputFormat: base64ToStrFun(val) });
  },
});

const slaveFormat = computed({
  get() {
    return props.nodeAttribute.slaveFormat || '';
  },
  set(val) {
    updateNodeAttribute({ slaveFormat: val });
  },
});

const outputFormat = computed({
  get() {
    return props.nodeAttribute.outputFormat || '';
  },
  set(val) {
    updateNodeAttribute({ outputFormat: val });
  },
});

const preExeCommand = computed({
  get() {
    return props.nodeAttribute.preExeCommand || '';
  },
  set(val) {
    updateNodeAttribute({ preExeCommand: val });
  },
});

const postExeCommand = computed({
  get() {
    return props.nodeAttribute.postExeCommand || '';
  },
  set(val) {
    updateNodeAttribute({ postExeCommand: val });
  },
});

// const nodeCondition = computed({
//   get() {
//     return props.nodeAttribute.nodeCondition || 'and';
//   },
//   set(val) {
//     updateNodeAttribute({ nodeCondition: val });
//   },
// });

// const exeMethod = computed({
//   get() {
//     return props.nodeAttribute.exeMethod || 'serviceTask';
//   },
//   set(val) {
//     updateNodeAttribute({ exeMethod: val });
//   },
// });

const beforeNodeId = computed({
  get() {
    return props.nodeAttribute.beforeNodeId || '';
  },
  set(val) {
    updateNodeAttribute({ beforeNodeId: val });
  },
});

const nodeExeCommand = computed({
  get() {
    return props.nodeAttribute.nodeExeCommand;
  },
  set(val) {
    updateNodeAttribute({ nodeExeCommand: val });
  },
});
const nodeParamConfigName = computed({
  get() {
    return props.nodeAttribute.nodeParamConfigName;
  },
  set(val) {
    updateNodeAttribute({ nodeParamConfigName: val });
  },
});

const showCodeEdit = ref(false);

// 应用版本数据
// const versions = ref<any[]>([]);

const changeFileFun = async (type: string, file: any) => {
  const isRepeat = props.nodeAttribute[type === 'pre' ? 'preScripts' : 'postScripts'].some(
    (item: any) => item.name === file.name
  );
  if (isRepeat) {
    ElMessage.warning('文件名重复！');
  }
  const form = new FormData();
  // form.append('fileType', String(FILE_TYPE.FLOW_PYTHON));
  // form.append('fileName ', file.name);
  form.append('script ', file.raw);
  const res = await upload(`${PREFIX}data/uploadScriptFile`, form);

  const preScripts = props.nodeAttribute.preScripts;
  const postScripts = props.nodeAttribute.postScripts;
  if (type === 'pre') {
    preScripts.push({
      name: file.name,
      isPreview: false,
      fileId: res.data,
    });
  } else if (type === 'post') {
    postScripts.push({
      name: file.name,
      isPreview: false,
      fileId: res.data,
    });
  }

  if (preScripts.length === 1) {
    preScripts[0].isPreview = true;
  }
  if (postScripts.length === 1) {
    postScripts[0].isPreview = true;
  }
  updateNodeAttribute({ preScripts, postScripts });
};

const changeReviewFun = (type: string, index: any) => {
  const preScripts = props.nodeAttribute.preScripts;
  const postScripts = props.nodeAttribute.postScripts;
  if (type === 'pre') {
    preScripts[index].isPreview = !preScripts[index].isPreview;
  }
  if (type === 'post') {
    postScripts[index].isPreview = !postScripts[index].isPreview;
  }
  updateNodeAttribute({ preScripts, postScripts });
};

const removeFileFun = (type: string, index: any) => {
  const preScripts = props.nodeAttribute.preScripts;
  const postScripts = props.nodeAttribute.postScripts;
  if (type === 'pre') {
    preScripts.splice(index, 1);
  }
  if (type === 'post') {
    postScripts.splice(index, 1);
  }
  updateNodeAttribute({ preScripts, postScripts });
};

const editFileId = ref('');
const openCodeDialogFun = (fileId: string) => {
  showCodeEdit.value = true;
  editFileId.value = fileId;
};

const nodeListOptions = ref<any[]>([]);

const base64ToStrFun = (str: any) => {
  const encoder = new TextEncoder();
  const utfBytes = encoder.encode(str);
  const binaryStr = String.fromCharCode(...utfBytes);
  const base64Str = btoa(binaryStr);
  return base64Str;
};

watch(
  () => props.graph,
  () => {
    nodeListOptions.value = [];
    props.graph.getNodes().forEach((node: any) => {
      if (
        node.data.nodeType !== FLOW_NODE_TYPE_ENUM.START &&
        node.data.nodeType !== FLOW_NODE_TYPE_ENUM.END &&
        node.data.currentId !== props.nodeAttribute.currentId
      ) {
        nodeListOptions.value.push({
          label: node.data.label,
          value: node.id,
        });
      }
    });
  },
  {
    immediate: true,
    deep: true,
  }
);

// const getAppVersion = async () => {
//   const res:any = await queryApplicationConfigApi({ appId: props.nodeAttribute.uuid });
//   if (res.code === 200) {
//     versions.value = res.data.map((item:any) => {
//       return {
//         label: item.configName,
//         value: item.id,
//       };
//     });
//   }
// };
const nodeParamOptions = ref<any[]>([]);

const getAppConfigListFun = async (uuid: any) => {
  try {
    const res: any = await queryApplicationConfigApi({
      appId: uuid,
    });
    if (res && res.code === 200) {
      nodeParamOptions.value = res.data;
    }
  } catch {}
};

const showAppInfoVisible = ref(false);

const showAppInfoFun = () => {
  showAppInfoVisible.value = true;
};

onMounted(async () => {
  if (props.nodeAttribute?.uuid) {
    await getAppConfigListFun(props.nodeAttribute?.uuid);
  } else {
    nodeParamOptions.value = [];
  }
  // downLoadScript();
});

// watch(
//   () => props.nodeAttribute.uuid,
//   (val) => {
//     if (props.nodeAttribute.uuid) {
//       getAppVersion();
//     }
//   },
//   {
//     immediate: true,
//     deep: true,
//   }
// );
</script>

<style lang="scss" scoped>
.script-manager {
  padding: 0 var(--padding-medium);
  padding-top: var(--padding-medium);
  height: 100%;
  overflow-y: auto;
}
.item-box {
  padding-bottom: var(--padding-medium);
  margin-bottom: var(--margin-medium);
  border-bottom: 1px solid var(--el-disabled-border-color);
  .title {
    font-size: var(--font-size-text-normal);
    // color: ;
    font-weight: bold;
    margin-bottom: var(--margin-medium);
    display: flex;
    justify-content: space-between;
    img {
      width: 20px;
    }
  }
  .select-version {
    width: 100%;
  }
  .script-box {
    .s-name {
      font-size: var(--font-size-text-small);
      color: #999999;
      margin-bottom: var(--margin-small);
    }
    .operation {
      display: flex;
      align-items: center;
      justify-content: space-between;
      .code-view-btn {
        img {
          width: 14px;
        }
        .select-ing {
          width: 20px;
          // background-color: red;
        }
      }
      img {
        width: 20px;
        margin-left: var(--margin-small);
        cursor: pointer;
      }
    }
    .code-box {
      margin-bottom: var(--margin-small);
      .code-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-top: var(--margin-small);

        .edit-code {
          font-size: var(--font-size-text-small);
          color: #0366ff;
          margin-bottom: var(--margin-small);
          background-color: #edf4ff;
          padding: var(--padding-tiny);
          border-radius: var(--border-radius-small);
          cursor: pointer;
        }
      }
      .code-text {
        width: 100%;
        height: 200px;
        overflow: hidden;
        border-radius: var(--border-radius-normal);
      }
    }
  }
  .node-detail-btn {
    font-size: var(--font-size-text-normal);
    color: var(--el-color-primary);
    cursor: pointer;
  }
}
</style>
