<!--
  全局「发起审批」悬浮按钮
  与「钉钉审批」按钮一致：当前页存在 mes_xsl_ding_tpl_bind 绑定且钉钉模板启用时显示；
  弹窗内可选该页业务表下已发布的 MES 审批流。
  支持两种发起方式：
  1）列表多选联动：在列表勾选数据后点击，弹窗自动带入选中单据并可批量发起；
  2）手动选择：未勾选时，在弹窗内搜索选择单条单据发起。
  @author GHT
  @date 2026-05-29 for：【QH-MES审批流设计】发起审批运行时
-->
<template>
  <div v-if="show" class="approval-float" :style="floatStyle">
    <div class="approval-float-btn" title="发起审批" @click="openModal">
      <Icon icon="ant-design:audit-outlined" :size="20" />
      <span class="approval-float-text">发起审批</span>
    </div>

    <a-modal v-model:open="visible" title="发起审批" :width="540" :confirmLoading="loading" okText="发起审批" @ok="handleLaunch">
      <a-form layout="vertical" style="margin-top: 8px">
        <a-form-item label="单据类型（审批流）" required>
          <a-select v-model:value="flowId" placeholder="请选择审批流" :options="flowOptions" @change="onFlowChange" allowClear />
        </a-form-item>

        <!-- 批量模式：直接展示列表勾选的单据 -->
        <a-form-item v-if="isBatch" :label="`已选单据（共 ${batchItems.length} 条）`" required>
          <div class="approval-float-batch">
            <div v-for="it in batchItems" :key="it.bizDataId" class="approval-float-batch-item">
              <Icon icon="ant-design:file-text-outlined" :size="14" />
              <span class="approval-float-batch-title">{{ it.bizTitle }}</span>
            </div>
          </div>
        </a-form-item>

        <!-- 手动模式：搜索选择单条单据 -->
        <a-form-item v-else label="选择单据" required>
          <a-select
            v-model:value="bizDataId"
            show-search
            placeholder="请选择需要发起审批的单据"
            :filter-option="false"
            :options="recordOptions"
            :disabled="!flowId"
            @search="onSearch"
            @change="onRecordChange"
          >
            <template #notFoundContent>
              <a-spin v-if="recordLoading" size="small" />
              <span v-else>无单据数据</span>
            </template>
          </a-select>
          <div v-if="flowId && !recordOptions.length && !recordLoading" class="approval-float-tip">
            该单据暂无数据，或审批流未配置“单据标题字段”
          </div>
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<script lang="ts" setup>
  import { computed, reactive, ref, watch } from 'vue';
  import { useRouter } from 'vue-router';
  import { debounce } from 'lodash-es';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { getPublishedFlows, getBizRecords, launchApproval, launchApprovalBatch } from '/@/views/approval/flow/launch.api';
  import { getBindingByRoute } from '/@/views/xslmes/dingtalk/dingTplBind/dingTplBind.api';
  import { useApprovalSelection } from './useApprovalSelection';

  defineOptions({ name: 'ApprovalLaunchFloat' });

  const { createMessage } = useMessage();
  const { currentRoute } = useRouter();
  const approvalSelection = useApprovalSelection();

  const visible = ref(false);
  const loading = ref(false);
  const recordLoading = ref(false);

  const flowId = ref<string>();
  const bizDataId = ref<string>();
  const bizTitle = ref<string>('');

  const binding = ref<any>(null);
  const flowList = ref<any[]>([]);
  const recordList = ref<any[]>([]);
  // 打开弹窗时快照的列表勾选行（批量模式数据源）
  const batchRows = ref<any[]>([]);

  // 悬浮位置（右下角）
  const floatStyle = reactive({ right: '24px', bottom: '120px' });

  // 与钉钉审批按钮一致：按 mes_xsl_ding_tpl_bind + 路由解析是否显示
  const show = computed(() => !!binding.value);

  const matchedFlows = computed(() => flowList.value);

  const flowOptions = computed(() =>
    matchedFlows.value.map((f) => ({
      label: `${f.flowName}（${f.bizTableName || f.bizTable}）`,
      value: f.id,
    }))
  );

  // 当前选中的审批流对象
  const currentFlow = computed(() => matchedFlows.value.find((f) => f.id === flowId.value));

  // 是否批量模式（列表有勾选）
  const isBatch = computed(() => batchRows.value.length > 0);

  // 批量模式下的单据项（用审批流的标题字段取展示标题）
  const batchItems = computed(() => {
    const titleField = currentFlow.value?.titleField;
    return batchRows.value
      .filter((r) => r && r.id != null)
      .map((r) => ({
        bizDataId: String(r.id),
        bizTitle: titleField && r[titleField] != null ? String(r[titleField]) : String(r.id),
      }));
  });

  const recordOptions = computed(() =>
    recordList.value.map((r) => ({
      label: r.title ?? r.id,
      value: r.id,
    }))
  );

  watch(
    () => currentRoute.value?.path,
    async (path) => {
      binding.value = null;
      flowList.value = [];
      if (!path || path === '/' || path.startsWith('/login')) {
        return;
      }
      try {
        const bind = await getBindingByRoute(path);
        binding.value = bind || null;
        if (binding.value) {
          flowList.value = (await getPublishedFlows(path)) || [];
        }
      } catch {
        binding.value = null;
        flowList.value = [];
      }
    },
    { immediate: true },
  );

  function resetSelection() {
    flowId.value = undefined;
    bizDataId.value = undefined;
    bizTitle.value = '';
    recordList.value = [];
    batchRows.value = [];
  }

  async function openModal() {
    if (!matchedFlows.value.length) {
      createMessage.warning('当前页面暂无已发布的 MES 审批流，请先在审批流设计中发布');
      return;
    }
    visible.value = true;
    resetSelection();
    // 读取当前列表页的勾选行
    batchRows.value = approvalSelection.getRowsByPath(currentRoute.value?.path || '');
    // 当前页只匹配到一个审批流时自动选中
    if (matchedFlows.value.length === 1) {
      flowId.value = matchedFlows.value[0].id;
    }
    // 手动模式且已确定审批流时预加载单据列表
    if (!isBatch.value && flowId.value) {
      await loadRecords();
    }
  }

  async function loadRecords(keyword?: string) {
    if (!flowId.value) return;
    try {
      recordLoading.value = true;
      recordList.value = (await getBizRecords({ flowId: flowId.value, keyword })) || [];
    } finally {
      recordLoading.value = false;
    }
  }

  function onFlowChange() {
    bizDataId.value = undefined;
    bizTitle.value = '';
    recordList.value = [];
    if (!isBatch.value && flowId.value) loadRecords();
  }

  const onSearch = debounce((val: string) => {
    loadRecords(val);
  }, 350);

  function onRecordChange() {
    const hit = recordList.value.find((r) => r.id === bizDataId.value);
    bizTitle.value = hit ? hit.title ?? hit.id : '';
  }

  async function handleLaunch() {
    if (!flowId.value) {
      createMessage.warning('请选择审批流');
      return;
    }
    try {
      loading.value = true;
      if (isBatch.value) {
        await launchApprovalBatch({ flowId: flowId.value, items: batchItems.value });
        createMessage.success(`已发起 ${batchItems.value.length} 条审批！`);
      } else {
        if (!bizDataId.value) {
          createMessage.warning('请选择需要发起审批的单据');
          return;
        }
        await launchApproval({ flowId: flowId.value, bizDataId: bizDataId.value, bizTitle: bizTitle.value });
        createMessage.success('发起成功！');
      }
      visible.value = false;
    } finally {
      loading.value = false;
    }
  }
</script>

<style lang="less" scoped>
  .approval-float {
    position: fixed;
    z-index: 999;

    .approval-float-btn {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 2px;
      width: 60px;
      height: 60px;
      border-radius: 50%;
      background: linear-gradient(135deg, #3296fa, #1668dc);
      color: #fff;
      cursor: pointer;
      box-shadow: 0 4px 14px rgba(50, 150, 250, 0.45);
      transition: transform 0.18s, box-shadow 0.18s;
      user-select: none;

      .approval-float-text {
        font-size: 11px;
        line-height: 1;
        transform: scale(0.92);
      }

      &:hover {
        transform: scale(1.08);
        box-shadow: 0 6px 20px rgba(50, 150, 250, 0.6);
      }
    }
  }

  .approval-float-batch {
    max-height: 220px;
    overflow-y: auto;
    border: 1px solid #f0f0f0;
    border-radius: 6px;
    padding: 6px 8px;

    .approval-float-batch-item {
      display: flex;
      align-items: center;
      gap: 6px;
      padding: 4px 2px;
      font-size: 13px;
      border-bottom: 1px dashed #f0f0f0;

      &:last-child {
        border-bottom: none;
      }

      .approval-float-batch-title {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
    }
  }

  .approval-float-tip {
    margin-top: 6px;
    font-size: 12px;
    color: #faad14;
  }
</style>
