<!--
 * 文件: index.vue (CreateStep4)
 * 功能: 流程模型创建的第四步——更多设置，包含流程编码规则、自动去重、标题与摘要设置，以及流程/任务的前后置 HTTP 通知配置。
 * 主要逻辑:
 * - 使用 `defineModel` 获取父组件传入的 `modelData`，作为当前步骤的配置数据源（如 `processIdRule`、`titleSetting`、`summarySetting`、通知配置等）。
 * - 提供流程编码样例（`flowCodeExample`），根据 `processIdRule` 的前缀/中缀/后缀与时间粒度动态生成示例字符串。
 * - 支持标题与摘要设置：通过 `a-mentions` 和多选 `a-select` 插入或选择表单字段，`formFieldOptions4Title` 与 `formFieldOptions4Summary` 提供可选字段列表（并预置启动人、发起时间等字段）。
 * - 支持四类 HTTP 通知设置（流程前置/后置、任务前置/后置），每类通过开关控制显示相应的 `HttpRequestSetting` 子组件，并在 `validateStep4` 中对开启的通知设置执行校验。
 * - 暴露 `validateStep4` 方法供父组件在切换步骤或保存时调用，聚合所有子组件的校验 Promise 并返回结果。
 * 注意事项:
 * - `HttpRequestSetting` 组件需要实现 `validateSetting` 方法以供校验调用；
 * - 当 `modelData` 中的表单字段来源变更时（例如字段名或结构变化），需同步更新 `formFields` 的解析逻辑及选项生成；
 * - 建议在提交前对通知 URL 与响应规则做额外校验以避免运行时错误。
-->

<script setup lang="ts">
import dayjs from 'dayjs';
import HttpRequestSetting from './components/httpRequestSetting.vue';

defineOptions({
  name: 'CreateStep4',
});
const formRef = ref<any>();
const modelData = defineModel<any>();

const timeOptions = ref([
  {
    value: '',
    label: '无',
  },
  {
    value: 'DAY',
    label: '精确到日',
  },
  {
    value: 'HOUR',
    label: '精确到时',
  },
  {
    value: 'MINUTE',
    label: '精确到分',
  },
  {
    value: 'SECOND',
    label: '精确到秒',
  },
]);

const flowCodeExample = computed<string>(() => {
  if (!modelData.value.processIdRule.enable) {
    return '不启用流程编码规则';
  }
  let infix = '';
  switch (modelData.value.processIdRule.infix) {
    case 'DAY':
      infix = dayjs().format('YYYYMMDD');
      break;
    case 'HOUR':
      infix = dayjs().format('YYYYMMDDHH');
      break;
    case 'MINUTE':
      infix = dayjs().format('YYYYMMDDHHmm');
      break;
    case 'SECOND':
      infix = dayjs().format('YYYYMMDDHHmmss');
      break;
    default:
      break;
  }
  return (
    modelData.value.processIdRule.prefix
    + infix
    + modelData.value.processIdRule.postfix
    + '1'.padStart(modelData.value.processIdRule.length - 1, '0')
  );
});

const radioStyle = reactive({
  display: 'flex',
  height: '30px',
  lineHeight: '30px',
});
/** 已解析表单字段 */
const formFields = ref<Array<{ field: string, title: string }>>([]);
/** 未解析的表单字段 */
// const unParsedFormFields = ref<string[]>([]);
const formFieldOptions4Title = computed(() => {
  const cloneFormField = formFields.value.map((item) => {
    return {
      label: item.title,
      value: item.field,
    };
  });
  // 固定添加发起人 ID 字段
  cloneFormField.unshift({
    label: '流程名称',
    value: 'PROCESS_DEFINITION_NAME',
  });
  cloneFormField.unshift({
    label: '发起时间',
    value: 'PROCESS_START_TIME',
  });
  cloneFormField.unshift({
    label: '发起人',
    value: 'PROCESS_START_USER_ID',
  });
  return cloneFormField;
});

const formFieldOptions4Summary = computed(() => {
  return formFields.value.map((item) => {
    return {
      label: item.title,
      value: item.field,
    };
  });
});

/** 是否开启流程前置通知 */
const processBeforeTriggerEnable = ref(false);
function handleProcessBeforeTriggerEnableChange(val: boolean | string | number) {
  if (val) {
    modelData.value.processBeforeTriggerSetting = {
      url: '',
      header: [],
      body: [],
      response: [],
    };
  }
  else {
    modelData.value.processBeforeTriggerSetting = null;
  }
}

/** 是否开启流程后置通知 */
const processAfterTriggerEnable = ref(false);
function handleProcessAfterTriggerEnableChange(val: boolean | string | number) {
  if (val) {
    modelData.value.processAfterTriggerSetting = {
      url: '',
      header: [],
      body: [],
      response: [],
    };
  }
  else {
    modelData.value.processAfterTriggerSetting = null;
  }
}

/** 是否开启任务前置通知 */
const taskBeforeTriggerEnable = ref(false);
function handleTaskBeforeTriggerEnableChange(val: boolean | string | number) {
  if (val) {
    modelData.value.taskBeforeTriggerSetting = {
      url: '',
      header: [],
      body: [],
      response: [],
    };
  }
  else {
    modelData.value.taskBeforeTriggerSetting = null;
  }
}

/** 是否开启任务后置通知 */
const taskAfterTriggerEnable = ref(false);
function handleTaskAfterTriggerEnableChange(val: boolean | string | number) {
  if (val) {
    modelData.value.taskAfterTriggerSetting = {
      url: '',
      header: [],
      body: [],
      response: [],
    };
  }
  else {
    modelData.value.taskAfterTriggerSetting = null;
  }
}

onMounted(() => {
  // 初始化开关状态
  processBeforeTriggerEnable.value = !!modelData.value.processBeforeTriggerSetting;
  processAfterTriggerEnable.value = !!modelData.value.processAfterTriggerSetting;
  taskBeforeTriggerEnable.value = !!modelData.value.taskBeforeTriggerSetting;
  taskAfterTriggerEnable.value = !!modelData.value.taskAfterTriggerSetting;
});

const processAfterTriggerSettingRef = ref<any>();
const processBeforeTriggerSettingRef = ref<any>();
const taskBeforeTriggerSettingRef = ref<any>();
const taskAfterTriggerSettingRef = ref<any>();

function validateStep4() {
  const validatePromises = [];
  if (processBeforeTriggerEnable.value && processBeforeTriggerSettingRef.value) {
    validatePromises.push(processBeforeTriggerSettingRef.value.validateSetting());
  }
  if (processAfterTriggerEnable.value && processAfterTriggerSettingRef.value) {
    validatePromises.push(processAfterTriggerSettingRef.value.validateSetting());
  }
  if (taskBeforeTriggerEnable.value && taskBeforeTriggerSettingRef.value) {
    validatePromises.push(taskBeforeTriggerSettingRef.value.validateSetting());
  }
  if (taskAfterTriggerEnable.value && taskAfterTriggerSettingRef.value) {
    validatePromises.push(taskAfterTriggerSettingRef.value.validateSetting());
  }
  return Promise.all(validatePromises);
}

defineExpose({
  validateStep4,
});
</script>

<template>
  <a-form
    ref="formRef"
    :model="modelData"
    :label-col="{ style: 'width:120px' }"
  >
    <a-form-item label="提交人权限" name="allowCancelRunningProcess">
      <a-checkbox v-model:checked="modelData.allowCancelRunningProcess">
        允许撤销审批中的申请（第一个审批节点通过后，提交人仍可撤销申请）
      </a-checkbox>
    </a-form-item>
    <a-form-item label="流程编码" name="flowcode">
      <a-form-item-rest>
        <div flex items-center>
          <a-checkbox v-model:checked="modelData.processIdRule.enable" />
          <span ml-8px>前缀：</span>
          <a-input v-model:value="modelData.processIdRule.prefix" class="flex-1" :maxlength="30" placeholder="请输入" :disabled="!modelData.processIdRule.enable" />
          <span ml-4px>中缀：</span>
          <a-select v-model:value="modelData.processIdRule.infix" class="flex-1" :options="timeOptions" placeholder="请选择" allow-clear :disabled="!modelData.processIdRule.enable" />
          <span ml-4px>后缀：</span>
          <a-input v-model:value="modelData.processIdRule.postfix" class="flex-1" :maxlength="30" placeholder="请输入" :disabled="!modelData.processIdRule.enable" />
          <span ml-4px>长度：</span>
          <a-input-number v-model:value="modelData.processIdRule.length" class="flex-1" :min="5" :max="20" :disabled="!modelData.processIdRule.enable" />
        </div>
      </a-form-item-rest>
      <div v-if="modelData.processIdRule.enable" flex ml-20px mt-6px>
        编码示例：{{ flowCodeExample }}
      </div>
    </a-form-item>
    <a-form-item label="自动去重" name="autoApprovalType">
      <div flex flex-col mt-5px>
        <div>同一审批人在流程中重复出现时：</div>
        <a-radio-group v-model:value="modelData.autoApprovalType">
          <a-radio :style="radioStyle" :value="0">
            不自动通过
          </a-radio>
          <a-radio :style="radioStyle" :value="1">
            仅审批一次，后续重复的审批节点均自动通过
          </a-radio>
          <a-radio :style="radioStyle" :value="2">
            仅针对连续审批的节点自动通过
          </a-radio>
        </a-radio-group>
      </div>
    </a-form-item>

    <a-form-item label="标题设置" name="titleSetting">
      <a-radio-group v-model:value="modelData.titleSetting.enable">
        <a-radio :style="radioStyle" :value="false">
          系统默认<span class="text-[#909399] ml-6px">展示流程名称</span>
        </a-radio>
        <a-radio :style="radioStyle" :value="true">
          自定义标题
          <a-tooltip>
            <template #title>
              输入字符 '{' 即可插入表单字段
            </template>
            <ExclamationCircleOutlined />
          </a-tooltip>
        </a-radio>
      </a-radio-group>
      <a-mentions
        v-if="modelData.titleSetting.enable"
        v-model="modelData.titleSetting.title"
        class="block! mt-4px!"
        type="textarea"
        rows="2"
        prefix="{"
        split="}"
        whole
        :options="formFieldOptions4Title"
        placeholder="请插入表单字段（输入 '{' 可以选择表单字段）或输入文本"
      />
    </a-form-item>
    <a-form-item label="摘要设置" name="summarySetting">
      <a-radio-group v-model:value="modelData.summarySetting.enable">
        <a-radio :style="radioStyle" :value="false">
          系统默认<span class="text-[#909399] ml-6px">展示表单前 3 个字段</span>
        </a-radio>
        <a-radio :style="radioStyle" :value="true">
          自定义摘要
        </a-radio>
      </a-radio-group>
      <a-select
        v-if="modelData.summarySetting.enable"
        v-model="modelData.summarySetting.summary"
        class="block! mt-4px!"
        multiple
        :options="formFieldOptions4Summary"
        placeholder="请选择要展示的表单字段"
      />
    </a-form-item>
    <a-form-item label="流程前置通知" name="processBeforeTriggerEnable">
      <div mt-5px>
        <a-switch
          v-model:checked="processBeforeTriggerEnable"
          checked-children="开"
          un-checked-children="关"
          @change="handleProcessBeforeTriggerEnableChange"
        />
        <span class="ml-40px">
          流程启动后通知
        </span>
      </div>
      <HttpRequestSetting
        v-if="processBeforeTriggerEnable"
        ref="processBeforeTriggerSettingRef"
        v-model:setting="modelData.processBeforeTriggerSetting"
        class="mt-10px!"
        :response-enable="true"
        form-item-prefix="'processBeforeTriggerSetting'"
      />
    </a-form-item>
    <a-form-item label="流程后置通知" name="processAfterTriggerEnable">
      <div mt-5px>
        <a-switch
          v-model:checked="processAfterTriggerEnable"
          checked-children="开"
          un-checked-children="关"
          @change="handleProcessAfterTriggerEnableChange"
        />
        <span class="ml-40px">
          流程结束后通知
        </span>
      </div>
      <HttpRequestSetting
        v-if="processAfterTriggerEnable"
        ref="processAfterTriggerSettingRef"
        v-model:setting="modelData.processAfterTriggerSetting"
        class="mt-10px!"
        :response-enable="true"
        form-item-prefix="'processAfterTriggerSetting'"
      />
    </a-form-item>
    <a-form-item label="任务前置通知" name="taskBeforeTriggerEnable">
      <div mt-5px>
        <a-switch
          v-model:checked="taskBeforeTriggerEnable"
          checked-children="开"
          un-checked-children="关"
          @change="handleTaskBeforeTriggerEnableChange"
        />
        <span class="ml-40px">
          任务执行时通知
        </span>
      </div>
      <HttpRequestSetting
        v-if="taskBeforeTriggerEnable"
        ref="taskBeforeTriggerSettingRef"
        v-model:setting="modelData.taskBeforeTriggerSetting"
        class="mt-10px!"
        :response-enable="true"
        form-item-prefix="'taskBeforeTriggerSetting'"
      />
    </a-form-item>
    <a-form-item label="任务后置通知" name="taskAfterTriggerEnable">
      <div mt-5px>
        <a-switch
          v-model:checked="taskAfterTriggerEnable"
          checked-children="开"
          un-checked-children="关"
          @change="handleTaskAfterTriggerEnableChange"
        />
        <span class="ml-40px">
          任务结束后通知
        </span>
      </div>
      <HttpRequestSetting
        v-if="taskAfterTriggerEnable"
        ref="taskAfterTriggerSettingRef"
        v-model:setting="modelData.taskAfterTriggerSetting"
        class="mt-10px!"
        :response-enable="true"
        form-item-prefix="'taskAfterTriggerSetting'"
      />
    </a-form-item>
  </a-form>
</template>

<style scoped>
:deep(.ant-form-item .ant-form-item-control-input) {
  align-items: unset !important;
}
</style>
