<template>
  <div class="implement-page">
    <div class="implement-form">
      <!-- 步骤一：选择实施采购方式 -->
      <div class="step-section">
        <div class="step-header">
          <span class="step-number" :class="{ completed: step1Completed && !isEditingStep1 }">1</span>
          <span class="step-title">选择实施采购方式</span>
          <el-tag v-if="step1Completed && !isEditingStep1" type="success" size="small">已完成</el-tag>
        </div>
        <div class="step-content">
          <el-form-item label="实施采购方式" required>
            <el-radio-group v-model="implementType" :disabled="step1Completed && !isEditingStep1">
              <el-radio :label="IMPLEMENT_TYPE.SELF_ORGANIZED">自行组织采购</el-radio>
              <el-radio :label="IMPLEMENT_TYPE.ENTRUST_AGENT">委托代理采购</el-radio>
            </el-radio-group>
          </el-form-item>
          <!-- 步骤一未完成：显示保存按钮 -->
          <el-form-item v-if="!step1Completed">
            <el-button type="primary" :loading="saveTypeSubmitting" :disabled="!implementType" @click="handleSaveImplementType">保存</el-button>
          </el-form-item>
          <!-- 步骤一已完成但正在编辑：显示修改确认按钮 -->
          <el-form-item v-else-if="isEditingStep1">
            <el-button type="primary" :loading="saveTypeSubmitting" :disabled="!implementType" @click="handleReSaveImplementType">确认修改</el-button>
            <el-button @click="cancelEditStep1">取消</el-button>
          </el-form-item>
          <!-- 步骤一已完成且未在编辑：显示修改按钮 -->
          <el-form-item v-else>
            <el-button type="default" @click="startEditStep1">修改</el-button>
          </el-form-item>
        </div>
      </div>

      <!-- 步骤二：分配代理（仅委托代理采购且步骤一完成时显示） -->
      <div v-if="showStep2" class="step-section">
        <div class="step-header">
          <span class="step-number" :class="{ completed: step2Completed }">2</span>
          <span class="step-title">分配代理机构</span>
          <el-tag v-if="step2Completed" type="success" size="small">已完成</el-tag>
        </div>
        <div class="step-content">
          <el-form-item label="分配方式">
            <el-radio-group v-model="agentMode">
              <el-radio label="designated">指定代理</el-radio>
              <el-radio label="random">随机分配</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item v-if="agentMode === 'designated'" label="选择代理">
            <el-select v-model="selectedAgentId" placeholder="请选择招标代理" filterable style="width: 100%" :loading="agentListLoading">
              <el-option v-for="item in agentList" :key="item.id" :label="item.agentName" :value="item.id" />
            </el-select>
          </el-form-item>
          <el-form-item v-if="agentMode === 'random'" label="随机结果">
            <div class="agent-roller">
              <span v-if="rollingAgentName" class="rolling">{{ rollingAgentName }}</span>
              <span v-else-if="assignedAgentName" class="assigned">已分配：{{ assignedAgentName }}</span>
              <span v-else class="placeholder">点击下方按钮进行随机分配</span>
            </div>
          </el-form-item>
          <el-form-item v-if="applyRow?.agentName" label="当前代理">
            <el-tag>{{ applyRow.agentName }}</el-tag>
            <!-- 发送状态 -->
            <el-tag v-if="applyRow?.agentSent === YES_NO.YES" type="success" style="margin-left: 8px;">已发送</el-tag>
            <el-tag v-else type="info" style="margin-left: 8px;">未发送</el-tag>
          </el-form-item>
          <!-- 指定代理按钮：未发送招标代理时可操作 -->
          <el-form-item v-if="agentMode === 'designated' && canReassignAgent">
            <el-button type="primary" :loading="assignAgentSubmitting" :disabled="!selectedAgentId" @click="handleAssignAgentDesignated">{{ step2Completed ? '重新指定' : '指定代理' }}</el-button>
          </el-form-item>
          <!-- 随机分配按钮：未发送招标代理时可操作 -->
          <el-form-item v-if="agentMode === 'random' && canReassignAgent">
            <el-button type="primary" :loading="assignAgentSubmitting" @click="handleAssignAgentRandom">随机分配</el-button>
          </el-form-item>
          <!-- 发送招标代理按钮 -->
          <el-form-item v-if="canSendToAgent">
            <el-button type="success" :loading="sendToAgentSubmitting" @click="handleSendToAgent">发送招标代理</el-button>
          </el-form-item>
          <!-- 撤回招标代理按钮 -->
          <el-form-item v-if="canRevokeAgent">
            <el-button type="warning" :loading="revokeAgentSubmitting" @click="handleRevokeAgent">撤回</el-button>
          </el-form-item>
        </div>
      </div>
    </div>
    <!-- 底部按钮：编辑步骤一时隐藏 -->
    <div v-if="!isEditingStep1" class="implement-footer">
      <el-button @click="handleClose">取消</el-button>
      <!-- 只有步骤一完成后才显示确定按钮 -->
      <el-button v-if="step1Completed" type="primary" :loading="implementSubmitting" @click="handleImplementSubmit">确定</el-button>
    </div>
  </div>
</template>

<script setup lang="ts" name="PurchasingImplement">
import { ref, computed, onMounted, watch, onUnmounted } from 'vue'
import { useRoute } from 'vue-router'
import { getDeptMembers, getObj, assignAgent, sendToAgent, revokeAgent, saveImplementType } from '/@/api/finance/purchasingrequisition'
import { getPage as getAgentPage } from '/@/api/finance/purchaseagent'
import { useMessage } from '/@/hooks/message'
import { Session } from '/@/utils/storage'
import * as orderVue from '/@/api/order/order-key-vue'

// ==================== 常量定义（与后端枚举保持一致） ====================

/** 部门审核角色编码：仅该角色下显示采购代表相关页面和功能，流转至部门审核时需填写采购代表 */
const PURCHASE_DEPT_AUDIT_ROLE_CODE = 'PURCHASE_DEPT_AUDIT'

/** 实施采购方式（与后端 ImplementTypeEnum 一致） */
const IMPLEMENT_TYPE = {
  /** 自行组织采购 */
  SELF_ORGANIZED: '1',
  /** 委托代理采购 */
  ENTRUST_AGENT: '2',
} as const

/** 采购形式（与后端 PurchaseModeEnum 一致） */
const PURCHASE_MODE = {
  /** 部门自行采购 */
  DEPT_SELF: '1',
  /** 学校统一采购 */
  SCHOOL_UNIFIED: '2',
} as const

/** 采购途径（与后端 PurchaseChannelEnum 一致） */
const PURCHASE_CHANNEL = {
  /** 自行采购 */
  SELF: '1',
  /** 委托采购中心采购 */
  ENTRUST_CENTER: '2',
} as const

/** 是否标识（与后端 CommonConstants.YES/NO 一致） */
const YES_NO = {
  NO: '0',
  YES: '1',
} as const

const roleCode = computed(() => Session.getRoleCode() || '')
const isDeptAuditRole = computed(() => roleCode.value === PURCHASE_DEPT_AUDIT_ROLE_CODE)

// 与编辑界面一致：支持流程 dynamic-link 传入 currJob/currElTab，申请单 ID 优先取 currJob.orderId
const props = defineProps({
  currJob: { type: Object, default: null },
  currElTab: { type: Object, default: null }
})
const emit = defineEmits(['handleJob'])

/** 是否被流程 handle 页面通过 dynamic-link 嵌入 */
const isFlowEmbed = computed(() => !!props.currJob)

const route = useRoute()

/** 申请单 ID（数值，用于 getObj 等）：与 add 一致，优先流程 currJob.orderId，否则 route.query.id */
const applyId = computed(() => {
  const raw = applyIdRaw.value
  if (raw == null || raw === '') return null
  const n = Number(raw)
  return Number.isNaN(n) ? null : n
})

/** 申请单 ID 原始字符串（用于 getApplyFiles 的 purchaseId，与编辑页一致，避免类型/精度问题） */
const applyIdRaw = computed(() => {
  if (props.currJob?.orderId != null && props.currJob?.orderId !== '') {
    return String(props.currJob.orderId)
  }
  const id = route.query.id
  return id != null && id !== '' ? String(id) : ''
})

const applyRow = ref<any>(null)
const implementType = ref<string>(IMPLEMENT_TYPE.SELF_ORGANIZED)
const implementSubmitting = ref(false)

/** 步骤控制 */
const step1Completed = ref(false)
const saveTypeSubmitting = ref(false)
const isEditingStep1 = ref(false)
const originalImplementType = ref<string>('')

const representorMode = ref<'single' | 'multi'>('single')
const representorTeacherNo = ref<string>('')
const representorsMulti = ref<string[]>([])
const deptMembers = ref<any[]>([])

/** 分配代理相关 */
const agentMode = ref<'designated' | 'random'>('designated')
const selectedAgentId = ref<string>('')
const agentList = ref<any[]>([])
const agentListLoading = ref(false)
const assignAgentSubmitting = ref(false)
const rollingAgentName = ref<string>('')
const assignedAgentName = ref<string>('')
const sendToAgentSubmitting = ref(false)
const revokeAgentSubmitting = ref(false)
let rollInterval: ReturnType<typeof setInterval> | null = null

/** 是否可以分配代理：委托代理采购 且 (学校统一采购 或 部门自行采购且委托采购中心采购) 且 步骤一已完成 */
const canAssignAgent = computed(() => {
  // 自行组织采购不需要分配代理
  if (implementType.value !== IMPLEMENT_TYPE.ENTRUST_AGENT) return false
  // 步骤一必须完成
  if (!step1Completed.value) return false
  const row = applyRow.value
  if (!row) return false
  // 学校统一采购 或 部门自行采购且委托采购中心采购
  return row.purchaseMode === PURCHASE_MODE.SCHOOL_UNIFIED
    || (row.purchaseMode === PURCHASE_MODE.DEPT_SELF && row.purchaseChannel === PURCHASE_CHANNEL.ENTRUST_CENTER)
})

/** 是否显示步骤二：委托代理采购 且 步骤一已完成 且 不在编辑步骤一 */
const showStep2 = computed(() => {
  return step1Completed.value && !isEditingStep1.value && implementType.value === IMPLEMENT_TYPE.ENTRUST_AGENT
})

/** 步骤二是否完成：已分配代理 */
const step2Completed = computed(() => {
  return !!applyRow.value?.agentId
})

/** 是否可以发送招标代理：委托代理采购 且 已分配代理 且 未发送 */
const canSendToAgent = computed(() => {
  // 自行组织采购不需要发送
  if (implementType.value !== IMPLEMENT_TYPE.ENTRUST_AGENT) return false
  const row = applyRow.value
  if (!row) return false
  // 已分配代理 且 未发送
  return !!row.agentId && row.agentSent !== YES_NO.YES
})

/** 是否可以重新分配代理：未发送招标代理时可操作 */
const canReassignAgent = computed(() => {
  const row = applyRow.value
  if (!row) return false
  // 未发送招标代理时可重新分配
  return row.agentSent !== YES_NO.YES
})

/** 是否可以撤回招标代理：已发送招标代理时可撤回 */
const canRevokeAgent = computed(() => {
  const row = applyRow.value
  if (!row) return false
  // 已分配代理 且 已发送招标代理时可撤回
  return !!row.agentId && row.agentSent === YES_NO.YES
})

const loadAgentList = async () => {
  agentListLoading.value = true
  try {
    const res = await getAgentPage({ size: 500, current: 1 })
    const records = res?.data?.records ?? res?.records ?? []
    agentList.value = Array.isArray(records) ? records : []
  } catch (_) {
    agentList.value = []
  } finally {
    agentListLoading.value = false
  }
}

/** 随机分配代理 - 滚动动画 */
const startRollingAnimation = (finalAgentName: string) => {
  if (agentList.value.length === 0) return

  // 清除之前的动画
  if (rollInterval) {
    clearInterval(rollInterval)
    rollInterval = null
  }

  rollingAgentName.value = ''
  assignedAgentName.value = ''

  let currentIndex = 0
  const totalDuration = 2000 // 总动画时间 2秒
  const intervalTime = 80 // 滚动间隔

  rollInterval = setInterval(() => {
    rollingAgentName.value = agentList.value[currentIndex].agentName
    currentIndex = (currentIndex + 1) % agentList.value.length
  }, intervalTime)

  // 2秒后停止并显示最终结果
  setTimeout(() => {
    if (rollInterval) {
      clearInterval(rollInterval)
      rollInterval = null
    }
    rollingAgentName.value = ''
    assignedAgentName.value = finalAgentName
  }, totalDuration)
}

const handleAssignAgentRandom = async () => {
  const id = applyRow.value?.id ?? applyId.value
  if (!id) {
    useMessage().warning('无法获取申请单ID')
    return
  }
  assignAgentSubmitting.value = true
  try {
    const res = await assignAgent(Number(id), 'random')
    // 后端返回分配结果后，展示滚动动画
    const finalAgentName = res?.data?.agentName || res?.agentName || ''
    if (finalAgentName) {
      startRollingAnimation(finalAgentName)
    } else {
      useMessage().success('随机分配代理成功')
      await loadData()
    }
  } catch (e: any) {
    useMessage().error(e?.msg || '随机分配代理失败')
  } finally {
    assignAgentSubmitting.value = false
  }
}

const handleAssignAgentDesignated = async () => {
  const id = applyRow.value?.id ?? applyId.value
  if (!id) {
    useMessage().warning('无法获取申请单ID')
    return
  }
  if (!selectedAgentId.value) {
    useMessage().warning('请选择招标代理')
    return
  }
  assignAgentSubmitting.value = true
  try {
    await assignAgent(Number(id), 'designated', selectedAgentId.value)
    useMessage().success('指定代理成功')
    await loadData()
  } catch (e: any) {
    useMessage().error(e?.msg || '指定代理失败')
  } finally {
    assignAgentSubmitting.value = false
  }
}

/** 发送招标代理 */
const handleSendToAgent = async () => {
  const id = applyRow.value?.id ?? applyId.value
  if (!id) {
    useMessage().warning('无法获取申请单ID')
    return
  }
  sendToAgentSubmitting.value = true
  try {
    await sendToAgent(Number(id))
    useMessage().success('已发送招标代理')
    await loadData()
  } catch (e: any) {
    useMessage().error(e?.msg || '发送招标代理失败')
  } finally {
    sendToAgentSubmitting.value = false
  }
}

/** 撤回招标代理 */
const handleRevokeAgent = async () => {
  const id = applyRow.value?.id ?? applyId.value
  if (!id) {
    useMessage().warning('无法获取申请单ID')
    return
  }
  revokeAgentSubmitting.value = true
  try {
    await revokeAgent(Number(id))
    useMessage().success('已撤回招标代理')
    await loadData()
  } catch (e: any) {
    useMessage().error(e?.msg || '撤回招标代理失败')
  } finally {
    revokeAgentSubmitting.value = false
  }
}

/** 步骤一：保存实施采购方式 */
const handleSaveImplementType = async () => {
  const id = applyRow.value?.id ?? applyId.value
  if (!id) {
    useMessage().warning('无法获取申请单ID')
    return
  }
  if (!implementType.value) {
    useMessage().warning('请选择实施采购方式')
    return
  }
  saveTypeSubmitting.value = true
  try {
    await saveImplementType(Number(id), implementType.value)
    useMessage().success('保存成功')
    step1Completed.value = true
    originalImplementType.value = implementType.value
    // 流程嵌入场景：通知流程 Tab 已保存
    if (isFlowEmbed.value && props.currJob && props.currElTab?.id) {
      orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true, emit)
    }
    // 如果是委托代理采购，加载代理列表
    if (implementType.value === IMPLEMENT_TYPE.ENTRUST_AGENT) {
      await loadAgentList()
    }
  } catch (e: any) {
    useMessage().error(e?.msg || '保存失败')
  } finally {
    saveTypeSubmitting.value = false
  }
}

/** 开始编辑步骤一 */
const startEditStep1 = () => {
  originalImplementType.value = implementType.value
  isEditingStep1.value = true
}

/** 取消编辑步骤一 */
const cancelEditStep1 = () => {
  implementType.value = originalImplementType.value
  isEditingStep1.value = false
}

/** 重新保存实施采购方式（修改后确认） */
const handleReSaveImplementType = async () => {
  const id = applyRow.value?.id ?? applyId.value
  if (!id) {
    useMessage().warning('无法获取申请单ID')
    return
  }
  if (!implementType.value) {
    useMessage().warning('请选择实施采购方式')
    return
  }
  saveTypeSubmitting.value = true
  try {
    await saveImplementType(Number(id), implementType.value)
    useMessage().success('修改成功')
    isEditingStep1.value = false
    originalImplementType.value = implementType.value
    // 如果从委托代理采购改为自行组织采购，清空代理相关状态
    if (implementType.value === IMPLEMENT_TYPE.SELF_ORGANIZED) {
      assignedAgentName.value = ''
      selectedAgentId.value = ''
    }
    // 如果改为委托代理采购，加载代理列表
    if (implementType.value === IMPLEMENT_TYPE.ENTRUST_AGENT) {
      await loadAgentList()
    }
    // 流程嵌入场景：通知流程 Tab 已保存
    if (isFlowEmbed.value && props.currJob && props.currElTab?.id) {
      orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true, emit)
    }
  } catch (e: any) {
    useMessage().error(e?.msg || '修改失败')
  } finally {
    saveTypeSubmitting.value = false
  }
}

const isInIframe = () => typeof window !== 'undefined' && window.self !== window.top

const postMessage = (type: string, payload?: any) => {
  if (typeof window !== 'undefined' && window.parent) {
    window.parent.postMessage({ type, ...payload }, '*')
  }
}

const loadData = async () => {
  const id = applyId.value
  if (!id) {
    useMessage().warning('缺少申请单ID')
    return
  }
  const needDeptMembers = isDeptAuditRole.value
  try {
    const requests: [ReturnType<typeof getObj>, ReturnType<typeof getDeptMembers>?] = [getObj(id)]
    if (needDeptMembers) requests.push(getDeptMembers())
    const results = await Promise.all(requests)
    const detailRes = results[0]
    const membersRes = needDeptMembers ? results[1] : null

    applyRow.value = detailRes?.data ? { ...detailRes.data, id: detailRes.data.id ?? id } : { id }
    const row = applyRow.value
    if (row?.implementType) {
      implementType.value = row.implementType
      originalImplementType.value = row.implementType
      // 已有 implementType 说明步骤一已完成
      step1Completed.value = true
    }
    // 回显需求部门初审-采购代表人方式与人员
    if (row?.representorTeacherNo) {
      representorMode.value = 'single'
      representorTeacherNo.value = row.representorTeacherNo ?? ''
      representorsMulti.value = []
    } else if (row?.representors) {
      representorMode.value = 'multi'
      representorTeacherNo.value = ''
      const parts = typeof row.representors === 'string' ? row.representors.split(',') : []
      representorsMulti.value = parts.map((s: string) => s.trim()).filter(Boolean)
    } else {
      representorTeacherNo.value = ''
      representorsMulti.value = []
    }
    deptMembers.value = needDeptMembers && membersRes?.data ? membersRes.data : []

    // 加载代理列表并回显已分配代理（委托代理采购时）
    if (step1Completed.value && implementType.value === IMPLEMENT_TYPE.ENTRUST_AGENT) {
      // 先判断是否可以分配代理（学校统一采购 或 部门自行采购且委托采购中心采购）
      const canLoadAgent = row.purchaseMode === PURCHASE_MODE.SCHOOL_UNIFIED
        || (row.purchaseMode === PURCHASE_MODE.DEPT_SELF && row.purchaseChannel === PURCHASE_CHANNEL.ENTRUST_CENTER)
      if (canLoadAgent) {
        await loadAgentList()
        // 回显已分配代理
        if (row?.agentId) {
          selectedAgentId.value = row.agentId
          assignedAgentName.value = row.agentName || ''
        }
      }
    }
  } catch (_) {
    applyRow.value = { id }
    deptMembers.value = []
  }
}

const handleClose = () => {
  postMessage('purchasingimplement:close')
  if (!isInIframe()) {
    window.history.back()
  }
}

const handleImplementSubmit = async () => {
  const row = applyRow.value
  if (!row?.id && !applyId.value) return
  const id = row?.id ?? applyId.value
  if (!id) return

  // 步骤一未完成时，先保存步骤一
  if (!step1Completed.value) {
    if (!implementType.value) {
      useMessage().warning('请选择实施采购方式')
      return
    }
    // 自动保存步骤一
    saveTypeSubmitting.value = true
    try {
      await saveImplementType(Number(id), implementType.value)
      step1Completed.value = true
    } catch (e: any) {
      useMessage().error(e?.msg || '保存实施采购方式失败')
      return
    } finally {
      saveTypeSubmitting.value = false
    }
  }

  implementSubmitting.value = true
  try {
    useMessage().success('实施采购已保存')
    postMessage('purchasingimplement:saved')
    // 流程嵌入场景：通知流程当前 Tab 已保存
    if (isFlowEmbed.value && props.currJob && props.currElTab?.id) {
      orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true, emit)
    }
  } catch (err: any) {
    useMessage().error(err?.msg || '实施采购失败')
  } finally {
    implementSubmitting.value = false
  }
}

/** 流程嵌入时供 handle.vue 调用的"保存"回调：与页面按钮保存逻辑保持一致 */
async function flowSubmitForm() {
  await handleImplementSubmit()
}

// 流程切换工单时重新加载数据（与 add 编辑页一致）
watch(
  () => props.currJob?.orderId ?? props.currJob?.id,
  (newVal, oldVal) => {
    if (newVal !== oldVal && applyId.value) {
      loadData()
    }
  }
)

onMounted(async () => {
  await loadData()
  if (isInIframe()) {
    document.documentElement.classList.add('iframe-mode')
    document.body.classList.add('iframe-mode')
  }
  // 流程嵌入：注册 tab 保存回调，供审批页调用（与采购申请编辑页保持一致）
  if (isFlowEmbed.value && props.currJob && props.currElTab?.id) {
    orderVue.currElTabIsExist(props.currJob, props.currElTab.id)
    await orderVue.currElTabIsView({}, props.currJob, props.currElTab.id, flowSubmitForm)
  }
})

onUnmounted(() => {
  // 清理滚动动画定时器
  if (rollInterval) {
    clearInterval(rollInterval)
    rollInterval = null
  }
})
</script>

<style scoped lang="scss">
.implement-page {
  padding: 20px;
  min-height: 100%;
  display: flex;
  flex-direction: column;
}
.implement-form {
  flex: 1;
  .mb-2 {
    margin-bottom: 8px;
  }
}
.implement-form-tip {
  margin-top: 12px;
  padding: 8px 0;
}
.implement-footer {
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid var(--el-border-color-lighter);
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.step-section {
  margin-bottom: 24px;
  padding: 16px;
  background: var(--el-fill-color-lighter);
  border-radius: 8px;
}

.step-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}

.step-number {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--el-color-primary);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  font-size: 14px;

  &.completed {
    background: var(--el-color-success);
  }
}

.step-title {
  font-weight: 500;
  font-size: 16px;
  color: var(--el-text-color-primary);
}

.step-content {
  padding-left: 40px;
}

.agent-roller {
  padding: 12px 16px;
  background: var(--el-fill-color-light);
  border-radius: 4px;
  min-height: 40px;
  display: flex;
  align-items: center;

  .rolling {
    font-size: 16px;
    font-weight: 500;
    color: var(--el-color-primary);
    animation: blink 0.1s infinite;
  }

  .assigned {
    font-size: 16px;
    font-weight: 600;
    color: var(--el-color-success);
  }

  .placeholder {
    color: var(--el-text-color-placeholder);
  }
}

@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.7; }
}
</style>