<!--
 * 文件: step1.vue
 * 功能: 流程模型创建的第一步表单（基本信息），包括流程标识、名称、分类、描述、流程类型、可见性、发起人范围与流程管理员等基础配置。
 * 主要逻辑:
 * - 使用 `defineModel` 获取父组件传入的 `modelData` 并作为表单数据源，表单项通过 `a-form` 与 `rules` 做校验。
 * - 提供选择人员/部门的能力：通过 `selectUser` / `selectOrg` 打开组织/人员选择器，选中后将结果同步到本地 `selectedStartUsers` / `selectedStartDepts` / `selectedManagerUsers`，并再同步回 `modelData`（如 `startUserIds`、`startDeptIds`、`managerUserIds`）。
 * - 通过 `watch` 监听 `modelData` 中相关字段的变化并初始化本地选中数组，保证父组件异步注入数据时也能正确渲染已选项。
 * - 当 `name` 字段变更时，会尝试将 `bpmnXml` 中的旧名称替换为新名称，保证流程图内节点名称同步更新。
 * - 暴露 `validateForm` 方法供父组件在切换步骤前触发校验。
 * 注意事项:
 * - 校验规则中对 `managerUserIds` 使用自定义校验函数 `checkManagerUserIds`，保证至少选择一个管理员；
 * - 选择人员/部门后需要同步 `modelData` 的对应 id 列表，避免表单提交时丢失数据；
 * - 若 `modelData` 结构或后端字段发生变更（如 id 字段命名），需同步本组件的映射逻辑。
-->

<script setup lang="ts">
import type { Rule } from 'ant-design-vue/es/form';
import type { Org, User } from './flow/ts/flow';
import { selectOrg, selectUser } from '@pubinfo/module-rbac';
import { nextTick } from 'vue';
import { getBpmCategorySimpleList } from '@/api/modules/bpmDefinition/bpMliuchengfenleikongzhiqi';

defineOptions({
  name: 'CreateStep1',
});
const route = useRoute();
const operateType = ref<string>('create');

const formRef = ref<any>();
const modelData = defineModel<any>();
const rules: Record<string, any> = {
  name: [{ required: true, message: '请输入流程名称', trigger: ['change', 'blur'] }],
  key: [{ required: true, validator: checkKey, trigger: ['change', 'blur'] }],
  category: [{ required: true, message: '请选择流程分类', trigger: 'change' }],
  type: [{ required: true, message: '请选择流程类型', trigger: 'change' }],
  visible: [{ required: true, message: '请选择是否可见', trigger: 'change' }],
  managerUserIds: [{ type: 'array', required: true, validator: checkManagerUserIds, trigger: ['change', 'blur'] }],
};

async function checkKey(_rule: Rule, value: string) {
  const pattern = /^[a-z][a-z0-9-]{0,29}$/i;
  if (!value) {
    return Promise.reject(new Error('请输入流程标识'));
  }
  if (!pattern.test(value)) {
    return Promise.reject(new Error('流程标识只能包含字母、数字、-，必须以字母开头，长度不超过30个字符'));
  }
  return Promise.resolve();
}

async function checkManagerUserIds(_rule: Rule, value: any[]) {
  if (!value || value.length === 0) {
    return Promise.reject(new Error('请选择流程管理员'));
  }
  return Promise.resolve();
}

const categoryOptions = ref<{ label: string, value: string }[]>([]);
const startUserTypeOptions = [
  { label: '全员', value: 0 },
  { label: '指定人员', value: 1 },
  { label: '指定部门', value: 2 },
];

function fetchCategoryOptions() {
  getBpmCategorySimpleList().then((response) => {
    if (response && response.data) {
      categoryOptions.value = [];
      response.data.forEach((item: any) => {
        categoryOptions.value.push({ label: item.name, value: item.code });
      });
    }
  });
}

const selectedStartUsers = ref<User[]>([]);
// 如果父组件异步设置了 modelData.startUsers，需要把值同步到本地 selectedStartUsers
watch(
  () => modelData.value?.startUsers,
  (newVal) => {
    const arr = newVal ?? [];
    selectedStartUsers.value = arr.map((item: any) => {
      return {
        orgId: item.deptId ?? item.orgId ?? '',
        userId: item.id ?? item.userId ?? '',
        userName: item.nickname ?? item.userName ?? item.account ?? '',
      };
    });
  },
  { immediate: true, deep: true },
);
function chooseUsers() {
  selectUser({
    multiple: true,
    modelValue: selectedStartUsers.value,
    onSubmit: (selectedUsers: any[]) => {
      selectedStartUsers.value = selectedUsers.map((user) => {
        return {
          orgId: user.orgId,
          userId: user.userId,
          userName: user.userName,
        };
      });
    },
  });
}

function handleStartUsersClose(tag: User) {
  selectedStartUsers.value = selectedStartUsers.value.filter(item => item.userId !== tag.userId);
}

watch(
  () => selectedStartUsers.value,
  (newVal) => {
    modelData.value.startUserIds = newVal.map(item => item.userId);
  },
  { deep: true },
);

const selectedStartDepts = ref<Org[]>([]);
// 如果父组件异步设置了 modelData.startDepts，需要把值同步到本地 selectedStartDepts
watch(
  () => modelData.value?.startDepts,
  (newVal) => {
    const arr = newVal ?? [];
    selectedStartDepts.value = arr.map((org: any) => {
      return {
        orgId: org.id ?? org.orgId ?? '',
        orgName: org.name ?? org.orgName ?? '',
      };
    });
  },
  { immediate: true, deep: true },
);
function chooseDepts() {
  selectOrg({
    multiple: true,
    modelValue: selectedStartDepts.value,
    onSubmit: (selectedOrgs: any[]) => {
      selectedStartDepts.value = selectedOrgs.map((org) => {
        return {
          orgId: org.orgId,
          orgName: org.orgName,
        };
      });
    },
  });
}

function handleStartDeptsClose(tag: Org) {
  selectedStartDepts.value = selectedStartDepts.value.filter(item => item.orgId !== tag.orgId);
}

watch(
  () => selectedStartDepts.value,
  (newVal) => {
    modelData.value.startDeptIds = newVal.map(item => item.orgId);
  },
  { deep: true },
);

// 选择流程管理员
const selectedManagerUsers = ref<User[]>([]);
// 当父组件（create.vue）通过 v-model 或 provide 更新 modelData.managerUsers 时，需要同步到本地 selectedManagerUsers
watch(
  () => modelData.value?.managerUsers,
  (newVal) => {
    const arr = newVal ?? [];
    selectedManagerUsers.value = arr.map((item: any) => {
      return {
        orgId: item.deptId ?? '',
        userId: item.id ?? '',
        userName: item.nickname ?? '',
      };
    });
  },
  { immediate: true, deep: true },
);

function chooseManagers() {
  selectUser({
    multiple: true,
    modelValue: selectedManagerUsers.value,
    onSubmit: (selectedUsers: any[]) => {
      selectedManagerUsers.value = selectedUsers.map((user) => {
        return {
          orgId: user.orgId,
          userId: user.userId,
          userName: user.userName,
        };
      });
    },
  });
}

function handleManagerUsersClose(tag: User) {
  selectedManagerUsers.value = selectedManagerUsers.value.filter(item => item.userId !== tag.userId);
}

watch(
  () => selectedManagerUsers.value,
  (newVal) => {
    modelData.value.managerUserIds = newVal.map(item => item.userId);
    // 当选择的管理员变化时，主动触发表单对该字段的校验
    nextTick(() => {
      if (formRef.value) {
        if (typeof formRef.value.validateFields === 'function') {
          formRef.value.validateFields(['managerUserIds']).catch(() => {});
        }
      }
    });
  },
  { deep: true },
);
// 当名称改变时，要保证对应的 bpmnXml 中的 name 也改变
const oldName = ref<string>(modelData.value?.name ?? '');
watch(
  () => modelData.value?.name,
  (newName, prevName) => {
    // prevName 可能为 undefined（首次），使用 oldName 作为回退
    const previous = prevName ?? oldName.value;
    if (!previous || newName === previous) {
      oldName.value = newName ?? '';
      return;
    }
    const xml = modelData.value?.bpmnXml;
    if (xml && typeof xml === 'string' && previous) {
      // 全文替换旧名称为新名称
      modelData.value.bpmnXml = xml.replaceAll(previous, newName ?? '');
    }
    oldName.value = newName ?? '';
  },
  { deep: false },
);

onMounted(() => {
  selectedStartUsers.value = [];
  selectedStartDepts.value = [];
  oldName.value = modelData.value?.name ?? '';
  if (route.params.id) {
    // route params present
    operateType.value = route.params.type as string;
    // 编辑或复制 需要填入数据
    if (modelData.value.startUserType === 1) {
      // 指定人员
      selectedStartUsers.value = (modelData.value.startUsers ?? []).map((item: API.UserSimpleBaseVO) => {
        return {
          orgId: item.deptId,
          userId: item.id,
          userName: item.nickname,
        };
      });
      // console.log('modelData.value.startUsers', modelData.value.startUsers);
    }
    else if (modelData.value.startUserType === 2) {
      // 指定部门
      selectedStartDepts.value = (modelData.value.startDepts ?? []).map((org: API.DeptSimpleBaseVO) => {
        return {
          orgId: org.id,
          orgName: org.name,
        };
      });
    }
  }
  else {
    operateType.value = 'create';
  }

  fetchCategoryOptions();
});

function validateForm() {
  return formRef.value.validate();
}

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

<template>
  <a-form
    ref="formRef"
    :model="modelData"
    :rules="rules"
    :label-col="{ style: 'width:120px' }"
  >
    <a-form-item name="key">
      <template #label>
        <span>流程标识&nbsp;</span>
        <a-tooltip>
          <template #title>
            流程标识是流程的唯一标识，创建后不可修改，只能包含字母、数字、-，必须以字母开头，长度不超过30个字符。
          </template>
          <ExclamationCircleOutlined />
        </a-tooltip>
      </template>
      <a-input v-model:value="modelData.key" :maxlength="30" placeholder="请输入流程标识" :disabled="operateType === 'edit'" />
    </a-form-item>
    <a-form-item label="流程名称" name="name">
      <a-input v-model:value="modelData.name" :maxlength="30" placeholder="请输入流程名称" />
    </a-form-item>
    <a-form-item label="流程分类" name="category">
      <a-select v-model:value="modelData.category" :options="categoryOptions" placeholder="请选择流程分类" allow-clear />
    </a-form-item>
    <a-form-item label="流程描述" name="description">
      <a-textarea v-model:value="modelData.description" placeholder="请输入流程描述" allow-clear />
    </a-form-item>
    <a-form-item label="流程类型" name="type">
      <a-radio-group v-model:value="modelData.type" disabled>
        <a-radio :value="10">
          BPMN设计器
        </a-radio>
        <a-radio :value="20">
          SIMPLE设计器
        </a-radio>
      </a-radio-group>
    </a-form-item>
    <a-form-item label="是否可见" name="visible">
      <a-radio-group v-model:value="modelData.visible">
        <a-radio :value="true">
          是
        </a-radio>
        <a-radio :value="false">
          否
        </a-radio>
      </a-radio-group>
    </a-form-item>
    <a-form-item label="谁可以发起" name="startUserType">
      <a-select v-model:value="modelData.startUserType" :options="startUserTypeOptions" placeholder="请选择" />
      <div v-if="modelData.startUserType === 1" mt-10px>
        <a-tag v-for="(tag, index) in selectedStartUsers" :key="index" closable @close="handleStartUsersClose(tag)">
          {{ tag.userName }}
        </a-tag>
        <a-button size="small" type="primary" @click="chooseUsers">
          选择人员
        </a-button>
      </div>
      <div v-if="modelData.startUserType === 2" mt-10px>
        <a-tag v-for="(tag, index) in selectedStartDepts" :key="index" closable @close="handleStartDeptsClose(tag)">
          {{ tag.orgName }}
        </a-tag>
        <a-button size="small" type="primary" @click="chooseDepts">
          选择部门
        </a-button>
      </div>
    </a-form-item>
    <a-form-item label="流程管理员" name="managerUserIds">
      <a-tag v-for="(tag, index) in selectedManagerUsers" :key="index" closable @close="handleManagerUsersClose(tag)">
        {{ tag.userName }}
      </a-tag>
      <a-button size="small" type="primary" @click="chooseManagers">
        选择人员
      </a-button>
    </a-form-item>
  </a-form>
</template>
