<template>
  <div class="control-command-wrapper">
    <div class="control-command">
      <!-- 类型标签 -->
      <div class="control-type-label">
        {{ currentFunction?.label || modelValue.commandType }}
      </div>

      <!-- 输入区域 -->
      <div v-if="currentFunction?.config" class="control-settings">
        <ParamInput
          :configs="currentFunction.config"
          :values="values"
          @update="handleInputUpdate"
        />
      </div>

      <!-- 操作按钮 -->
      <q-btn-dropdown
        v-if="showBranchButton"
        flat
        dense
        dropdown-icon="add"
        size="sm"
        no-icon-animation
        class="control-btn"
      >
        <q-list>
          <q-item
            v-for="func in branchOptions"
            :key="func.value"
            v-close-popup
            clickable
            @click="addBranch(func.value)"
            class="row items-center no-wrap q-py-none"
          >
            <q-icon :name="func.icon" class="q-mr-md" />
            <q-item-label>{{ func.label }}</q-item-label>
          </q-item>
        </q-list>
      </q-btn-dropdown>
    </div>
  </div>
</template>

<script>
import { defineComponent } from "vue";
import ParamInput from "components/composer/common/ParamInput.vue";

export default defineComponent({
  name: "ControlCommand",
  components: {
    ParamInput,
  },
  props: {
    modelValue: {
      type: Object,
      required: true,
    },
  },
  emits: ["update:modelValue", "addBranch"],
  data() {
    return {
      defaultArgvs: {},
    };
  },
  computed: {
    currentFunction() {
      return this.modelValue.subCommands?.find(
        (f) => f.value === this.modelValue.commandType
      );
    },
    values() {
      if (!this.currentFunction?.config) return [];
      return this.currentFunction.config.map(
        (input) => this.argvs[input.key] || ""
      );
    },
    showBranchButton() {
      return (
        this.modelValue.subCommands?.length > 2 &&
        this.modelValue.subCommands?.[0]?.value === this.modelValue.commandType
      );
    },
    branchOptions() {
      return this.modelValue.subCommands?.slice(1, -1);
    },
    argvs() {
      return (
        this.modelValue.argvs || this.parseCodeToArgvs(this.modelValue.code)
      );
    },
  },
  methods: {
    handleInputUpdate(index, value) {
      const input = this.currentFunction.config[index];
      this.updateArgvs(input.key, value);
    },
    updateArgvs(key, value) {
      const argvs = {
        ...this.argvs,
        [key]: value,
      };
      this.updateModelValue(argvs);
    },
    addBranch(type) {
      this.$emit("addBranch", {
        chainId: this.modelValue.chainId,
        commandType: type,
        value: this.modelValue.value,
      });
      this.updateModelValue(this.argvs || {});
    },
    generateCode(argvs) {
      if (!this.currentFunction?.codeTemplate) return "";

      let code = this.currentFunction.codeTemplate;

      const variablePattern = /\${(\w+)}/g;
      code = code.replace(variablePattern, (_, key) => {
        return argvs[key] || "";
      });

      return code;
    },
    parseCodeToArgvs(code) {
      if (!code) return this.defaultArgvs;
      if (!this.currentFunction?.codeTemplate) return {};

      const template = this.currentFunction.codeTemplate;
      const argvs = {};

      // 如果没有变量模板，直接返回空对象
      if (!template.includes("${")) return {};

      // 将模板转换为正则表达式
      const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
      let pattern = escapeRegExp(template);

      // 收集所有变量名
      const variables = [];
      const variablePattern = /\${(\w+)}/g;
      let match;

      while ((match = variablePattern.exec(template)) !== null) {
        variables.push(match[1]);
        pattern = pattern.replace(escapeRegExp(`\${${match[1]}}`), "([^}]*?)");
      }

      // 创建正则表达式并匹配代码
      const regex = new RegExp(`^${pattern}$`);
      const matches = code.match(regex);

      if (matches) {
        // 从第二个元素开始，依次赋值给变量
        variables.forEach((variable, index) => {
          argvs[variable] = matches[index + 1] || "";
        });
        return argvs;
      }

      return this.defaultArgvs;
    },
    updateModelValue(argvs) {
      const code = this.generateCode(argvs);

      this.$emit("update:modelValue", {
        ...this.modelValue,
        argvs,
        code,
      });
    },
  },
  created() {
    // 初始化默认值
    if (this.currentFunction?.config) {
      this.currentFunction.config.forEach((config) => {
        this.defaultArgvs[config.key] = config.defaultValue || "";
      });
    }
  },
  mounted() {
    if (!this.modelValue.code) {
      this.updateModelValue(this.defaultArgvs);
    }
  },
});
</script>

<style scoped>
.control-command-wrapper {
  width: 100%;
  display: flex;
}

.control-command {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
}

.control-type-label {
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  opacity: 0.9;
  user-select: none;
  flex-shrink: 0;
}

.control-settings {
  display: flex;
  flex: 1;
  min-width: 0;
  margin-right: auto;
}

/* ParamInput 容器样式 */
.control-settings :deep(.param-grid) {
  display: flex;
  flex-wrap: wrap;
  gap: var(--grid-gap);
  width: 100%;
  --grid-gap: 8px;
}

/* 输入项容器样式 */
.control-settings :deep(.grid-item) {
  min-width: 50px;
  margin: 0;
  display: flex;
  justify-content: center;
  align-items: center;
}

/* 输入框样式 */
.control-settings :deep(.grid-item > *) {
  flex: 1;
  min-width: 0;
}

.control-btn {
  opacity: 0.7;
  flex-shrink: 0;
  margin-left: auto;
}

.control-btn:hover {
  opacity: 1;
  transform: scale(1.1);
}

/* 暗色模式适配 */
.body--dark .control-btn {
  color: rgba(255, 255, 255, 0.7);
}

.body--dark .control-btn:hover {
  color: var(--q-primary);
}
</style>
