<!--
   模型列表
 * 文件: list.vue
 * 功能: 流程模型列表视图，按分类展示模型并提供模型的新增、编辑、复制、发布、历史、清理与删除等操作。
 * 主要逻辑:
 * - 组件挂载时调用 `fetchModelList`，通过 `getBpmModelList` 获取所有模型、通过 `getBpmCategorySimpleList` 获取分类列表，
 *   并将模型按分类聚合为 `categoryModelList` 用于渲染折叠面板。
 * - 使用 Ant Design 的 `a-collapse` 与 `a-table` 渲染分类下的模型列表，`columns` 定义表格列，`bodyCell` 插槽用于自定义列渲染：
 *   - `visibleRange`：根据 `startUsers` / `startDepts` 的数量展示“全部可见”或首项预览并用 `a-tooltip` 显示完整列表。
 *   - `flowType`：根据 `type` 字段显示 BPMN / SIMPLE 标签样式。
 *   - `lastPublishTime`：若存在 `processDefinition` 则显示发布时间与版本标签，否则显示“未发布”。
 * - `onAction` 根据 `ACTION` 枚举处理操作：
 *   - `ADD`：跳转到新建模型页面；
 *   - `EDIT` / `COPY`：跳转到编辑/复制页面并携带对应 `id` 与 `type`；
 *   - `PUBLISH`：弹出确认框，调用 `postBpmModelDeploy` 发布并刷新列表；
 *   - `HISTORY`：跳转到流程定义历史页（基于 `flowKey`）；
 *   - `CLEAN`：确认后调用 `postBpmModelClean` 清理模型数据并刷新；
 *   - `REMOVE`：调用 `postBpmModelDelete` 删除模型并刷新列表。
 * - 所有与后端交互的操作均在 Promise 返回后刷新数据或展示提示，目前以简单的成功回调处理为主，建议根据需要补充错误处理与 loading 状态。
 * 注意事项:
 * - `fetchModelList` 将所有模型按分类分组，若分类或模型数据结构变更需同步字段匹配（如 `categoryName`、`processDefinition` 等）。
 * - 表格内的操作按钮使用链接/下拉菜单实现，新增操作请在 `ACTION` 中拓展并在 `onAction` 中加入处理逻辑。
-->
<script setup lang="ts">
import { CaretRightOutlined, PlusCircleOutlined, SearchOutlined } from '@ant-design/icons-vue';
import { message, Modal } from 'ant-design-vue';
import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import { getBpmCategorySimpleList } from '@/api/modules/bpmDefinition/bpMliuchengfenleikongzhiqi';
import { getBpmModelList, postBpmModelClean, postBpmModelDelete, postBpmModelDeploy } from '@/api/modules/bpmDefinition/guanlihoutailiuchengmoxing';
import { ACTION } from '../enum';

defineOptions({
  name: 'FlowModelList',
});
const router = useRouter();
const content = ref<string>('');
const activeKey = ref<string[]>(['1']);
const customStyle = 'background: #f7f7f7;border-radius: 4px;margin-bottom: 24px;border: 0;overflow: hidden';
const columns = [
  {
    title: '流程名称',
    dataIndex: 'name',
    key: 'name',
  },
  {
    title: '可见范围',
    dataIndex: 'visibleRange',
    key: 'visibleRange',
  },
  {
    title: '流程类型',
    dataIndex: 'flowType',
    key: 'flowType',
  },
  {
    title: '表单信息',
    dataIndex: 'formCustomCreatePath',
    key: 'formCustomCreatePath',
  },
  {
    title: '最后发布时间',
    dataIndex: 'lastPublishTime',
    key: 'lastPublishTime',
  },
  {
    title: '操作',
    dataIndex: 'action',
    key: 'action',
    width: 200,
  },
];
const allModeList = ref<any[]>([]);
const categoryList = ref<any[]>([]);
const categoryModelList = ref<any[]>([]);

async function fetchModelList() {
  const modelistRes = await getBpmModelList({ name: content.value });
  if (modelistRes && modelistRes.data) {
    allModeList.value = modelistRes.data;
  }
  const categoryRes = await getBpmCategorySimpleList();
  if (categoryRes && categoryRes.data) {
    categoryList.value = categoryRes.data;
  }
  categoryModelList.value = categoryList.value.map((category: any) => ({
    ...category,
    modelList: allModeList.value.filter((model: any) => model.categoryName === category.name),
  }));
}

onMounted(() => {
  fetchModelList();
});

function onAction(key: ACTION, record?: any) {
  switch (key) {
    case ACTION.ADD:
      router.push({ name: 'flowmodelCreate' });
      break;
    case ACTION.EDIT:
      router.push({ name: 'flowmodelUpdate', params: { type: 'edit', id: record.id } });
      break;
    case ACTION.COPY:
      router.push({ name: 'flowmodelUpdate', params: { type: 'copy', id: record.id } });
      break;
    case ACTION.PUBLISH:
      Modal.confirm({
        title: '发布确认',
        content: '是否确认发布该流程？',
        onOk: () => {
          postBpmModelDeploy({ id: record.id }).then((deployRes) => {
            if (deployRes.success) {
              message.success('发布成功');
              fetchModelList();
            }
          });
        },
        onCancel() {},
      });
      break;
    case ACTION.HISTORY:
      router.push({ name: 'flowmodelDefinition', params: { flowKey: record.key } });
      break;
    case ACTION.CLEAN:
      Modal.confirm({
        title: '清理确认',
        content: `是否确认清理流程名字为${record.name}的数据项？`,
        onOk: () => {
          postBpmModelClean({ id: record.id }).then((res) => {
            if (res.success) {
              message.success('清理成功');
              fetchModelList();
            }
          });
        },
        onCancel() {},
      });
      break;
    case ACTION.REMOVE:
      Modal.confirm({
        title: '确定删除该模型吗?',
        okText: '确认',
        okType: 'danger',
        cancelText: '取消',
        onOk() {
          postBpmModelDelete({ id: record.id }).then((res: API.ResponseDataBoolean) => {
            if (res.success) {
              message.success('删除成功！');
              fetchModelList();
            }
          });
        },
        onCancel() {},
      });
      break;
  }
}
</script>

<template>
  <div
    py-10px
    px-10px
    w-full
    h-full
  >
    <div w-full h-full bg="#ffffff" p-10px rounded-8px flex flex-col>
      <div class="flex items-center justify-between mb-10px border-b border-b-solid border-b-1px border-b-#e8e8e8 pb-10px">
        <a-input v-model:value="content" placeholder="请输入流程模型名关键字，按回车键搜索" style="width: 300px;" @press-enter="fetchModelList">
          <template #prefix>
            <SearchOutlined />
          </template>
        </a-input>
        <a-button type="primary" @click="onAction(ACTION.ADD)">
          <PlusCircleOutlined />
          新建模型
        </a-button>
      </div>
      <div flex-1 h-0px overflow-auto>
        <a-collapse
          v-model:active-key="activeKey"
          :bordered="false"
          style="background: transparent;"
        >
          <template #expandIcon="slotProps">
            <CaretRightOutlined :style="{ fontSize: '16px' }" :rotate="slotProps?.isActive ? 90 : 0" />
          </template>
          <a-collapse-panel
            v-for="(category, index) in categoryModelList"
            :key="index + 1"
            :style="customStyle"
          >
            <template #header>
              <span text-16px font-bold>{{ `${category.name} (${category.modelList.length})` }}</span>
            </template>
            <a-table :columns="columns" :data-source="category.modelList" :pagination="false">
              <template #bodyCell="{ column, record }">
                <template v-if="column.dataIndex === 'visibleRange'">
                  <span v-if="!record.startUsers?.length && !record.startDepts?.length"> 全部可见 </span>
                  <span v-else-if="record.startUsers.length === 1">
                    {{ record.startUsers[0].nickname }}
                  </span>
                  <span v-else-if="record.startDepts?.length === 1">
                    {{ record.startDepts[0].name }}
                  </span>
                  <span v-else-if="record.startDepts?.length > 1">
                    <a-tooltip>
                      <template #title>{{ `${record.startDepts.map((dept: any) => dept.name).join('、')}` }}</template>
                      {{ record.startDepts[0].name }}等 {{ record.startDepts.length }} 个部门可见
                    </a-tooltip>
                  </span>
                  <span v-else>
                    <a-tooltip>
                      <template #title>{{ `${record.startUsers.map((user: any) => user.nickname).join('、')}` }}</template>
                      {{ record.startUsers[0].nickname }}等 {{ record.startUsers.length }} 人可见
                    </a-tooltip>
                  </span>
                </template>
                <template v-if="column.dataIndex === 'flowType'">
                  <span v-if="record.type === 10" class="blue">
                    BPMN 设计器
                  </span>
                  <span v-if="record.type === 20" class="green">
                    SIMPLE 设计器
                  </span>
                </template>
                <template v-if="column.dataIndex === 'lastPublishTime'">
                  <div v-if="record.processDefinition">
                    <a-tag
                      v-if="record.processDefinition?.suspensionState === 2"
                      color="warning"
                    >
                      已停用
                    </a-tag>
                    <div v-else flex items-center>
                      <span>
                        {{ record.processDefinition.deploymentTime }}
                      </span>
                      <a-tag class="ml-6px!" color="green">
                        v{{ record.processDefinition.version }}
                      </a-tag>
                    </div>
                  </div>

                  <a-tag v-else color="warning">
                    未发布
                  </a-tag>
                </template>
                <template v-if="column.dataIndex === 'action'">
                  <a-space class="btn-panel">
                    <a-button type="link" @click="onAction(ACTION.EDIT, record)">
                      {{ ACTION.EDIT }}
                    </a-button>
                    <a-button type="link" @click="onAction(ACTION.COPY, record)">
                      {{ ACTION.COPY }}
                    </a-button>
                    <a-button type="link" @click="onAction(ACTION.PUBLISH, record)">
                      {{ ACTION.PUBLISH }}
                    </a-button>
                    <a-dropdown>
                      <a class="ant-dropdown-link" @click.prevent>
                        更多
                      </a>
                      <template #overlay>
                        <a-menu>
                          <a-menu-item v-if="record.processDefinition">
                            <a class="text-[#1677ff]! hover:text-[#69b1ff]!" @click="onAction(ACTION.HISTORY, record)">{{ ACTION.HISTORY }}</a>
                          </a-menu-item>
                          <a-menu-item>
                            <a class="text-[#1677ff]! hover:text-[#69b1ff]!" @click="onAction(ACTION.CLEAN, record)">{{ ACTION.CLEAN }}</a>
                          </a-menu-item>
                          <a-menu-item>
                            <a class="text-[#1677ff]! hover:text-[#69b1ff]!" @click="onAction(ACTION.REMOVE, record)">{{ ACTION.REMOVE }}</a>
                          </a-menu-item>
                        </a-menu>
                      </template>
                    </a-dropdown>
                  </a-space>
                </template>
              </template>
            </a-table>
          </a-collapse-panel>
        </a-collapse>
      </div>
    </div>
  </div>
</template>

<style scoped>
:deep(.ant-collapse-item) {
  background: transparent !important;
  border: 1px solid #d9d9d9 !important;
}
:deep(.ant-collapse-content-box) {
  padding: 0 !important;
  padding-bottom: 16px !important;
}
:deep(.ant-table-thead>tr>th) {
  padding: 6px 16px !important;
  background-color: rgb(237, 239, 240) !important;
}
:deep(.ant-table-container table>thead>tr:first-child >*:first-child) {
  border-top-left-radius: 0 !important;
}
:deep(.ant-table-container table>thead>tr:first-child >*:last-child) {
  border-top-right-radius: 0 !important;
}

.green {
  padding: 2px 9px;
  color: #67c23a;
  background-color: rgb(239.8, 248.9, 235.3);
  border: 1px solid rgb(224.6, 242.8, 215.6);
  border-radius: 4px;
}
.blue {
  padding: 2px 9px;
  color: #409eff;
  background-color: #ecf5ff;
  border: 1px solid #d9ecff;
  border-radius: 4px;
}
.grey {
  padding: 2px 9px;
  color: #909399;
  background-color: rgb(243.9, 244.2, 244.8);
  border: 1px solid rgb(232.8, 233.4, 234.6);
  border-radius: 4px;
}
.btn-panel :deep(.ant-btn) {
  padding: 0 !important;
}
</style>
