<script setup lang="ts">
import { computed, provide, ref, watch } from 'vue';

import { useVbenModal } from '@vben/common-ui';
import {
  BpmAutoApproveType,
  BpmModelFormType,
  ProcessVariableEnum,
} from '@vben/constants';
import { IconifyIcon } from '@vben/icons';

import dayjs from 'dayjs';
import {
  ElButton,
  ElCheckbox,
  ElCol,
  ElForm,
  ElFormItem,
  ElInput,
  ElInputNumber,
  ElMention,
  ElOption,
  ElRadio,
  ElRadioGroup,
  ElRow,
  ElSelect,
  ElSwitch,
  ElText,
  ElTooltip,
} from 'element-plus';

import { getForm } from '#/api/bpm/form';
// import {
//   HttpRequestSetting,
//   parseFormFields,
// } from '#/views/bpm/components/simple-process-design';
import { parseFormFields } from '#/components/form-create';

import PrintTemplate from './custom-print-template.vue';

const modelData = defineModel<any>();

/** 自定义 ID 流程编码 */
const timeOptions = ref([
  {
    value: '',
    label: '无',
  },
  {
    value: 'DAY',
    label: '精确到日',
  },
  {
    value: 'HOUR',
    label: '精确到时',
  },
  {
    value: 'MINUTE',
    label: '精确到分',
  },
  {
    value: 'SECOND',
    label: '精确到秒',
  },
]);
const numberExample = computed(() => {
  if (modelData.value.processIdRule.enable) {
    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')
    );
  } else {
    return '';
  }
});

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

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

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

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

/** 表单字段 */
const formFields = ref<Array<{ field: string; title: string }>>([]);
const formFieldOptions4Title = computed(() => {
  const cloneFormField = formFields.value.map((item) => {
    return {
      label: item.title,
      value: item.field,
    };
  });
  // 固定添加发起人 ID 字段
  cloneFormField.unshift({
    label: '流程名称',
    value: ProcessVariableEnum.PROCESS_DEFINITION_NAME,
  });
  cloneFormField.unshift({
    label: '发起时间',
    value: ProcessVariableEnum.START_TIME,
  });
  cloneFormField.unshift({
    label: '发起人',
    value: ProcessVariableEnum.START_USER_ID,
  });
  return cloneFormField;
});
const formFieldOptions4Summary = computed(() => {
  return formFields.value.map((item) => {
    return {
      label: item.title,
      value: item.field,
    };
  });
});
const unParsedFormFields = ref<string[]>([]); // 未解析的表单字段
provide('formFields', unParsedFormFields); // 暴露给子组件 HttpRequestSetting 使用

/** 兼容以前未配置更多设置的流程 */
function initData() {
  if (!modelData.value.processIdRule) {
    modelData.value.processIdRule = {
      enable: false,
      prefix: '',
      infix: '',
      postfix: '',
      length: 5,
    };
  }
  if (!modelData.value.printTemplateSetting) {
    modelData.value.printTemplateSetting = {
      enable: false,
      template: '',
    };
  }
  if (!modelData.value.autoApprovalType) {
    modelData.value.autoApprovalType = BpmAutoApproveType.NONE;
  }
  if (!modelData.value.titleSetting) {
    modelData.value.titleSetting = {
      enable: false,
      title: '',
    };
  }
  if (!modelData.value.summarySetting) {
    modelData.value.summarySetting = {
      enable: false,
      summary: [],
    };
  }
  if (modelData.value.processBeforeTriggerSetting) {
    processBeforeTriggerEnable.value = true;
  }
  if (modelData.value.processAfterTriggerSetting) {
    processAfterTriggerEnable.value = true;
  }
  if (modelData.value.taskBeforeTriggerSetting) {
    taskBeforeTriggerEnable.value = true;
  }
  if (modelData.value.taskAfterTriggerSetting) {
    taskAfterTriggerEnable.value = true;
  }
  if (modelData.value.allowWithdrawTask === undefined) {
    modelData.value.allowWithdrawTask = false;
  }
}

/** 监听表单 ID 变化，加载表单数据 */
watch(
  () => modelData.value.formId,
  async (newFormId) => {
    if (newFormId && modelData.value.formType === BpmModelFormType.NORMAL) {
      const data = await getForm(newFormId);
      const result: Array<{ field: string; title: string }> = [];
      if (data.fields) {
        unParsedFormFields.value = data.fields;
        data.fields.forEach((fieldStr: string) => {
          parseFormFields(JSON.parse(fieldStr), result);
        });
      }
      formFields.value = result;
    } else {
      formFields.value = [];
      unParsedFormFields.value = [];
    }
  },
  { immediate: true },
);
const formRef = ref(); // 表单引用

/** 表单校验 */
async function validate() {
  await formRef.value?.validate();
}

/** 自定义打印模板模态框 */
const [PrintTemplateModal, printTemplateModalApi] = useVbenModal({
  connectedComponent: PrintTemplate,
  destroyOnClose: true,
});

/** 弹出自定义打印模板弹窗 */
function openPrintTemplateModal() {
  printTemplateModalApi
    .setData({ template: modelData.value.printTemplateSetting.template })
    .open();
}

/** 默认的打印模板， 目前自定义模板没有引入自定义样式。 看后续是否需要 */
const defaultTemplate = `<p style="text-align: center;font-size: 1.25rem;"><strong><span data-w-e-type="mention" data-value="流程名称" data-info="%7B%22id%22%3A%22processName%22%7D">@流程名称</span></strong></p>
<p style="text-align: right;">打印人员：<span data-w-e-type="mention" data-info="%7B%22id%22%3A%22printUser%22%7D">@打印人</span></p>
<p style="text-align: left;">流程编号：<span data-w-e-type="mention" data-value="流程编号" data-info="%7B%22id%22%3A%22processNum%22%7D">@流程编号</span></p>
<p>&nbsp;</p>
<table style="width: 100%; height: 72.2159px;">
<tbody>
<tr style="height: 36.108px;">
<td style="width: 21.7532%; border: 1px solid;" colspan="1" rowspan="1" width="auto">发起人</td>
<td style="width: 30.5551%; border: 1px solid;" colspan="1" rowspan="1" width="auto"><span data-w-e-type="mention" data-value="发起人" data-info="%7B%22id%22%3A%22startUser%22%7D">@发起人</span></td>
<td style="width: 21.7532%; border: 1px solid;" colspan="1" rowspan="1" width="auto">发起时间</td>
<td style="width: 26.0284%; border: 1px solid;" colspan="1" rowspan="1" width="auto"><span data-w-e-type="mention" data-value="发起时间" data-info="%7B%22id%22%3A%22startTime%22%7D">@发起时间</span></td>
</tr>
<tr style="height: 36.108px;">
<td style="width: 21.7532%; border: 1px solid;" colspan="1" rowspan="1" width="auto">所属部门</td>
<td style="width: 30.5551%; border: 1px solid;" colspan="1" rowspan="1" width="auto"><span data-w-e-type="mention" data-w-e-is-void="" data-w-e-is-inline="" data-value="发起人部门" data-info="%7B%22id%22%3A%22startUserDept%22%7D">@发起人部门</span></td>
<td style="width: 21.7532%; border: 1px solid;" colspan="1" rowspan="1" width="auto">流程状态</td>
<td style="width: 26.0284%; border: 1px solid;" colspan="1" rowspan="1" width="auto"><span data-w-e-type="mention" data-value="流程状态" data-info="%7B%22id%22%3A%22processStatus%22%7D">@流程状态</span></td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<div contenteditable="false" data-w-e-type="process-record" data-w-e-is-void="">
<table class="process-record-table" style="width: 100%; border-collapse: collapse; border: 1px solid;">
<tr>
	<td style="width: 100%; border: 1px solid; text-align: center;" colspan="2">流程记录</td>
</tr>
<tr>
	<td style="width: 25%; border: 1px solid;">节点</td>
	<td style="width: 75%; border: 1px solid;">操作</td>
</tr>
</table>
</div>
<p>&nbsp;</p>`;

const printTemplateEnable = computed<boolean>({
  get() {
    return !!modelData.value?.printTemplateSetting?.enable;
  },
  set(val: boolean) {
    if (!modelData.value.printTemplateSetting) {
      modelData.value.printTemplateSetting = {
        enable: false,
        template: '',
      };
    }
    modelData.value.printTemplateSetting.enable = val;
  },
}); // 自定义打印模板开关

function handlePrintTemplateEnableChange(checked: any) {
  const val = !!checked;
  if (val && !modelData.value.printTemplateSetting.template) {
    modelData.value.printTemplateSetting.template = defaultTemplate;
  }
}

function confirmPrintTemplate(template: string) {
  modelData.value.printTemplateSetting.template = template;
}

defineExpose({ initData, validate });
</script>
<template>
  <ElForm
    ref="formRef"
    :model="modelData"
    label-width="120px"
    class="mt-5 px-5"
  >
    <ElFormItem class="mb-5" label="提交人权限">
      <div class="flex flex-col gap-2">
        <ElCheckbox v-model="modelData.allowCancelRunningProcess">
          允许撤销审批中的申请
        </ElCheckbox>
        <div class="ml-6 text-sm">
          <ElText type="warning">
            第一个审批节点通过后，提交人仍可撤销申请
          </ElText>
        </div>
      </div>
    </ElFormItem>
    <ElFormItem class="mb-5" label="审批人权限">
      <div class="flex flex-col gap-2">
        <ElCheckbox v-model="modelData.allowWithdrawTask">
          允许审批人撤回任务
        </ElCheckbox>
        <div class="ml-6 text-sm">
          <ElText type="info">审批人可撤回正在审批节点的前一节点</ElText>
        </div>
      </div>
    </ElFormItem>
    <ElFormItem v-if="modelData.processIdRule" class="mb-5" label="流程编码">
      <ElRow :gutter="8">
        <ElCol :span="1">
          <ElCheckbox v-model="modelData.processIdRule.enable" />
        </ElCol>
        <ElCol :span="5">
          <ElInput
            v-model="modelData.processIdRule.prefix"
            placeholder="前缀"
            :disabled="!modelData.processIdRule.enable"
          />
        </ElCol>
        <ElCol :span="6">
          <ElSelect
            v-model="modelData.processIdRule.infix"
            clearable
            placeholder="中缀"
            :disabled="!modelData.processIdRule.enable"
          >
            <ElOption
              v-for="option in timeOptions"
              :key="option.value"
              :value="option.value"
              :label="option.label"
            />
          </ElSelect>
        </ElCol>
        <ElCol :span="4">
          <ElInput
            v-model="modelData.processIdRule.postfix"
            placeholder="后缀"
            :disabled="!modelData.processIdRule.enable"
          />
        </ElCol>
        <ElCol :span="4">
          <ElInputNumber
            v-model="modelData.processIdRule.length"
            :min="5"
            :disabled="!modelData.processIdRule.enable"
          />
        </ElCol>
      </ElRow>
      <div class="ml-6 mt-2" v-if="modelData.processIdRule.enable">
        <ElText type="success">编码示例：{{ numberExample }}</ElText>
      </div>
    </ElFormItem>
    <ElFormItem class="mb-5" label="自动去重">
      <div class="flex flex-col">
        <div class="mb-2">
          <ElText>同一审批人在流程中重复出现时：</ElText>
        </div>
        <ElRadioGroup v-model="modelData.autoApprovalType">
          <div class="flex flex-col gap-2">
            <ElRadio :value="0">不自动通过</ElRadio>
            <ElRadio :value="1">
              仅审批一次，后续重复的审批节点均自动通过
            </ElRadio>
            <ElRadio :value="2">仅针对连续审批的节点自动通过</ElRadio>
          </div>
        </ElRadioGroup>
      </div>
    </ElFormItem>
    <ElFormItem v-if="modelData.titleSetting" class="mb-5" label="标题设置">
      <div class="flex flex-col gap-2">
        <ElRadioGroup v-model="modelData.titleSetting.enable">
          <div class="flex flex-col gap-2">
            <ElRadio :value="false">
              系统默认
              <ElText type="success"> 展示流程名称 </ElText>
            </ElRadio>
            <ElRadio :value="true">
              <div class="inline-flex items-center">
                自定义标题
                <ElTooltip
                  content="输入字符 '{' 即可插入表单字段"
                  placement="top"
                >
                  <IconifyIcon
                    icon="lucide:circle-help"
                    class="ml-1 size-4 text-gray-500"
                  />
                </ElTooltip>
              </div>
            </ElRadio>
          </div>
        </ElRadioGroup>
        <ElMention
          v-if="modelData.titleSetting.enable"
          v-model="modelData.titleSetting.title"
          class="w-full min-w-[400px]"
          type="textarea"
          prefix="{"
          split="}"
          :options="formFieldOptions4Title"
          placeholder="请插入表单字段（输入 '{' 可以选择表单字段）或输入文本"
        />
      </div>
    </ElFormItem>
    <ElFormItem
      v-if="
        modelData.summarySetting &&
        modelData.formType === BpmModelFormType.NORMAL
      "
      class="mb-5"
      label="摘要设置"
    >
      <div class="flex flex-col gap-2">
        <ElRadioGroup v-model="modelData.summarySetting.enable">
          <div class="flex flex-col gap-2">
            <ElRadio :value="false">
              系统默认
              <ElText type="info">展示表单前 3 个字段</ElText>
            </ElRadio>
            <ElRadio :value="true"> 自定义摘要 </ElRadio>
          </div>
        </ElRadioGroup>
        <ElSelect
          v-if="modelData.summarySetting.enable"
          v-model="modelData.summarySetting.summary"
          multiple
          placeholder="请选择要展示的表单字段"
          class="w-full min-w-[400px]"
        >
          <ElOption
            v-for="option in formFieldOptions4Summary"
            :key="option.value"
            :value="option.value"
            :label="option.label"
          />
        </ElSelect>
      </div>
    </ElFormItem>
    <ElFormItem class="mb-5" label="流程前置通知">
      <ElRow class="mt-1">
        <ElCol :span="24">
          <div class="flex items-center">
            <ElSwitch
              v-model="processBeforeTriggerEnable"
              @change="handleProcessBeforeTriggerEnableChange"
            />
            <span class="ml-4">流程启动后通知</span>
          </div>
        </ElCol>
      </ElRow>
      <ElRow v-if="processBeforeTriggerEnable">
        <ElCol :span="24" class="mt-6">
          <!-- <HttpRequestSetting
            v-model:setting="modelData.processBeforeTriggerSetting"
            :response-enable="true"
            form-item-prefix="processBeforeTriggerSetting"
          /> -->
        </ElCol>
      </ElRow>
    </ElFormItem>
    <ElFormItem class="mb-5" label="流程后置通知">
      <ElRow class="mt-1">
        <ElCol :span="24">
          <div class="flex items-center">
            <ElSwitch
              v-model="processAfterTriggerEnable"
              @change="handleProcessAfterTriggerEnableChange"
            />
            <span class="ml-4">流程结束后通知</span>
          </div>
        </ElCol>
      </ElRow>
      <ElRow v-if="processAfterTriggerEnable" class="mt-2">
        <ElCol :span="24">
          <HttpRequestSetting
            v-model:setting="modelData.processAfterTriggerSetting"
            :response-enable="true"
            form-item-prefix="processAfterTriggerSetting"
          />
        </ElCol>
      </ElRow>
    </ElFormItem>
    <ElFormItem class="mb-5" label="任务前置通知">
      <ElRow class="mt-1">
        <ElCol :span="24">
          <div class="flex items-center">
            <ElSwitch
              v-model="taskBeforeTriggerEnable"
              @change="handleTaskBeforeTriggerEnableChange"
            />
            <span class="ml-4">任务执行时通知</span>
          </div>
        </ElCol>
      </ElRow>
      <ElRow v-if="taskBeforeTriggerEnable" class="mt-2">
        <ElCol :span="24">
          <HttpRequestSetting
            v-model:setting="modelData.taskBeforeTriggerSetting"
            :response-enable="true"
            form-item-prefix="taskBeforeTriggerSetting"
          />
        </ElCol>
      </ElRow>
    </ElFormItem>
    <ElFormItem class="mb-5" label="任务后置通知">
      <ElRow class="mt-1">
        <ElCol :span="24">
          <div class="flex items-center">
            <ElSwitch
              v-model="taskAfterTriggerEnable"
              @change="handleTaskAfterTriggerEnableChange"
            />
            <span class="ml-4">任务结束后通知</span>
          </div>
        </ElCol>
      </ElRow>
      <ElRow v-if="taskAfterTriggerEnable" class="mt-2">
        <ElCol :span="24">
          <HttpRequestSetting
            v-model:setting="modelData.taskAfterTriggerSetting"
            :response-enable="true"
            form-item-prefix="taskAfterTriggerSetting"
          />
        </ElCol>
      </ElRow>
    </ElFormItem>
    <ElFormItem class="mb-5" label="自定义打印模板">
      <div class="flex w-full flex-col">
        <div class="flex items-center">
          <ElSwitch
            v-model="printTemplateEnable"
            @change="handlePrintTemplateEnableChange"
          />
          <ElButton
            v-if="printTemplateEnable"
            class="ml-2 flex items-center"
            link
            @click="openPrintTemplateModal"
          >
            <template #icon>
              <IconifyIcon icon="lucide:pencil" />
            </template>
            编辑模板
          </ElButton>
        </div>
      </div>
    </ElFormItem>
    <PrintTemplateModal
      :form-fields="formFields"
      @confirm="confirmPrintTemplate"
    />
  </ElForm>
</template>
