<template>
  <view class="page">
    <view class="card">
      <view class="title">担架运送申请</view>

      <!-- 申报科室 -->
      <view class="form-item">
        <text class="label required">申报科室</text>
        <picker mode="multiSelector" :range="deptMultiRange"
          :value="deptMultiValue" @columnchange="onDeptColumnChange"
          @change="onDeptChange">
          <view class="picker-value" :class="{ placeholder: !form.decDept }">
            {{ currentDeptName || '请选择所在科室' }}
          </view>
        </picker>
      </view>

      <!-- 申报床号 -->
      <view class="form-item">
        <text class="label required">申报床号</text>
        <input class="input" type="text" v-model="form.decBedNo"
          placeholder="请输入床号" />
      </view>

      <!-- 申报手机 -->
      <view class="form-item">
        <text class="label required">申报手机</text>
        <input class="input" type="number" maxlength="11" v-model="form.decTel"
          placeholder="请输入手机号码" />
      </view>

      <!-- 运送工具 -->
      <view class="form-item">
        <text class="label required">运送工具</text>
        <picker mode="selector" :range="toolNames" @change="onPickTool">
          <view class="picker-value"
            :class="{ placeholder: !form.carryingtools }">
            {{ currentToolName || '请选择所需运送工具' }}
          </view>
        </picker>
      </view>

      <!-- 工具数量 -->
      <view class="form-item">
        <text class="label required">工具数量</text>
        <input class="input" type="number"
          v-model.number="form.carryingtoolsCount" placeholder="请输入工具数量" />
      </view>

      <!-- 承运人数量 -->
      <view class="form-item">
        <text class="label required">承运人数量</text>
        <input class="input" type="number" v-model.number="form.outnumber"
          placeholder="请输入所需运送人员数量" />
      </view>

      <!-- 是否预约 -->
      <view class="form-item">
        <text class="label">是否预约</text>
        <switch :checked="form.isOrdered" @change="onToggleOrdered" />
      </view>

      <!-- 预约时间 -->
      <view v-if="form.isOrdered" class="form-item">
        <text class="label">预约时间</text>
        <picker mode="time" :value="form.orderedDatetime || ''"
          @change="onPickTime">
          <view class="picker-value"
            :class="{ placeholder: !form.orderedDatetime }">
            {{ form.orderedDatetime || '请选择' }}
          </view>
        </picker>
      </view>

      <!-- 支付方式 -->
      <view class="form-item">
        <text class="label required">支付方式</text>
        <picker mode="selector" :range="payNames" @change="onPickPay">
          <view class="picker-value"
            :class="{ placeholder: !form.paymentMethod }">
            {{ currentPayName || '请选择支付方式' }}
          </view>
        </picker>
      </view>

      <view class="btns">
        <button class="btn outline" :disabled="!isCancelSubmit"
          @tap="onCancelAgent">取消申请</button>
        <button class="btn primary" :disabled="!isSubmit"
          @tap="onSubmit">申请</button>
      </view>
    </view>

    <!-- 等待接单浮层 -->
    <view v-if="isShowProgress" class="overlay">
      <view class="overlay-card">
        <text class="overlay-title">等待骑手接单</text>
        <text class="overlay-time">{{ countdownText }}</text>
        <button class="btn outline" @tap="onCancelAgent">取消申请</button>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { computed, onMounted, onUnmounted, reactive, ref } from 'vue'
// JS 服务以 any 导入，避免类型声明缺失导致报错
// @ts-ignore
import util from '@/utils/util.js'
// @ts-ignore
import queryService from '@/service/queryService.js'
// @ts-ignore
import getService from '@/service/getService.js'
// @ts-ignore
import config from '@/config.js'

// 表单数据（字段需与旧版保持一致）
const form = reactive({
  needcontactDept: null as any,
  needcontact: null as any,
  needcontactTel: null as any,
  decChannel: null as any,
  decDepts: null as any,
  decDept: null as any,
  decBedNo: null as any,
  decTel: null as any,
  openid: null as any,
  carryingtools: null as any,
  carryingtoolsCount: 1,
  outnumber: 1,
  isOrdered: false,
  orderedDatetime: null as any,
  paymentMethod: '01'
})

// 选项数据
const formData = reactive({
  decDeptDatas: [] as Array<any>,
  carryingtoolsDatas: [] as Array<any>,
  paymentMethodDatas: [] as Array<any>
})

// UI & 轮询相关
const isSubmit = ref(true)
const isCancelSubmit = ref(false)
const isShowProgress = ref(false)
const list = ref<any[] | null>(null)

const COUNTDOWN_MAX = 5 * 60 * 1000 // 5 分钟
const countdown = ref(COUNTDOWN_MAX)
let pollTimer: any = null
let cdTimer: any = null

// 申报科室两列联动：左列父级、右列子级（无子项则显示占位）
const deptMultiRange = ref<string[][]>([[], []])
const deptParents = ref<any[]>([])
const deptChildrenMap = ref<Record<string, any[]>>({}) // parentId -> children[]
const deptMultiValue = ref<number[]>([0, 0])
const toolNames = computed(() => formData.carryingtoolsDatas.map(d => d.name || d.label || ''))
const payNames = computed(() => formData.paymentMethodDatas.map(d => d.name || d.label || ''))

const currentDeptName = computed(() => {
  if (!form.decDept) return ''
  // 优先在子集里找
  for (const p of deptParents.value) {
    const children = deptChildrenMap.value[p.id] || []
    const c = children.find((it: any) => it.id === form.decDept)
    if (c) return c.gridFullname || c.gridName || c.name || c.label || ''
  }
  // 子集中没有，则在父集中找
  const p = deptParents.value.find((it: any) => it.id === form.decDept)
  return p ? (p.gridFullname || p.gridName || p.name || p.label || '') : ''
})
const currentToolName = computed(() => {
  const found = formData.carryingtoolsDatas.find(d => d.id === form.carryingtools)
  return found ? (found.name || found.label) : ''
})
const currentPayName = computed(() => {
  const found = formData.paymentMethodDatas.find(d => d.id === form.paymentMethod)
  return found ? (found.name || found.label) : ''
})

const countdownText = computed(() => {
  const total = Math.max(0, countdown.value)
  const h = Math.floor(total / 3600000)
  const m = Math.floor((total % 3600000) / 60000)
  const s = Math.floor((total % 60000) / 1000)
  const pad = (n: number) => String(n).padStart(2, '0')
  return `${pad(h)}:${pad(m)}:${pad(s)}`
})

function onDeptColumnChange(e: any) {
  const { column, value } = e.detail
  // 切换父列，联动更新子列
  if (column === 0) {
    deptMultiValue.value[0] = value
    const parent = deptParents.value[value]
    const children = (parent && deptChildrenMap.value[parent.id]) || []
    deptMultiRange.value[1] = children.length > 0
      ? children.map((c: any) => c.gridFullname || c.gridName || c.name || c.label || '')
      : ['- 无子项 -']
    deptMultiValue.value[1] = 0
  }
}

function onDeptChange(e: any) {
  const [pi, ci] = e.detail.value as number[]
  const parent = deptParents.value[pi]
  const children = (parent && deptChildrenMap.value[parent.id]) || []
  if (children.length > 0) {
    const child = children[ci]
    if (!child) return
    form.decDept = child.id
    form.decDepts = ['', child.id]
  } else {
    if (!parent) return
    form.decDept = parent.id
    form.decDepts = ['', parent.id]
  }
}

function onPickTool(e: any) {
  const idx = Number(e.detail.value)
  const item = formData.carryingtoolsDatas[idx]
  if (!item) return
  form.carryingtools = item.id
}

function onPickPay(e: any) {
  const idx = Number(e.detail.value)
  const item = formData.paymentMethodDatas[idx]
  if (!item) return
  form.paymentMethod = item.id
}

function onPickTime(e: any) {
  form.orderedDatetime = e.detail.value
}

function onToggleOrdered(e: any) {
  form.isOrdered = !!e.detail.value
}

function validate(): boolean {
  // 简单校验，保持与旧版规则一致
  if (!form.decDept && (!form.decDepts || (Array.isArray(form.decDepts) && form.decDepts.length <= 1))) {
    uni.showToast({ title: '申报科室不能为空', icon: 'none' })
    return false
  }
  if (!form.decBedNo) {
    uni.showToast({ title: '床号不能为空', icon: 'none' })
    return false
  }
  if (!form.decTel) {
    uni.showToast({ title: '申报电话不能为空', icon: 'none' })
    return false
  }
  if (!form.carryingtools) {
    uni.showToast({ title: '运送工具不能为空', icon: 'none' })
    return false
  }
  if (!form.carryingtoolsCount) {
    uni.showToast({ title: '工具数量不能为空', icon: 'none' })
    return false
  }
  if (!form.outnumber) {
    uni.showToast({ title: '所需运送人员数量不能为空', icon: 'none' })
    return false
  }
  if (!form.paymentMethod) {
    uni.showToast({ title: '支付方式不能为空', icon: 'none' })
    return false
  }
  if (form.isOrdered && !form.orderedDatetime) {
    uni.showToast({ title: '请选择预约时间', icon: 'none' })
    return false
  }
  return true
}

async function onSubmit() {
  if (!validate()) return

  // 兼容旧逻辑：若 decDepts 长度>1，则取第二位作为 decDept
  if (form.decDepts && Array.isArray(form.decDepts) && form.decDepts.length > 1) {
    form.decDept = form.decDepts[1]
  }

  const openid = uni.getStorageSync('openid')
  form.openid = openid ? openid : config.defaultOpenId

  // 组装后端要求的预约时间格式：yyyy-MM-dd HH:mm:ss
  const payload: any = { ...form }
  if (form.isOrdered) {
    payload.orderedDatetime = toFullDateTime(form.orderedDatetime as any)
  } else {
    payload.orderedDatetime = null
  }

  try {
    const res = await util.request({ url: '/API/stretchertransport/create', method: 'POST', data: payload })
    if (res.data && res.data.code === 0) {
      isSubmit.value = false
      isCancelSubmit.value = true
      isShowProgress.value = true
      startPoll()
      startCountdown()
      uni.showToast({ title: '担架运送申请成功，等待骑手接单！', icon: 'none' })
    } else {
      throw new Error('create failed')
    }
  } catch (err) {
    uni.showToast({ title: '担架运送申请失败，请重新申请！', icon: 'none' })
    isShowProgress.value = false
    isSubmit.value = true
    isCancelSubmit.value = false
  }
}

async function onCancel() {
  try {
    const res = await util.request({ url: `/API/stretchertransport/redis/delete/${form.decTel}`, method: 'GET' })
    if (res.data && res.data.code === 0) {
      isSubmit.value = true
      isCancelSubmit.value = false
      isShowProgress.value = false
      stopPoll()
      stopCountdown()
      uni.showToast({ title: '担架运送申请取消成功！', icon: 'none' })
    } else {
      throw new Error('cancel failed')
    }
  } catch (err) {
    uni.showToast({ title: '担架运送申请取消失败！', icon: 'none' })
  }
}

async function onCancelAgent() {
  const res = await uni.showModal({ title: '确认取消申请提示', content: '您确定要取消本次申请吗？' })
  // res: [error, result] in promise? In uni-app promise, returns [err, res]? Using any below
  const result: any = Array.isArray(res) ? res[1] : (res as any)
  if (result && result.confirm) {
    onCancel()
  }
}

function startPoll() {
  if (pollTimer) return
  pollTimer = setInterval(async () => {
    const data = { decDept: form.decDept, decBedNo: form.decBedNo, decTel: form.decTel }
    try {
      const res = await queryService.queryStretcherReceiptTask(data)
      if (res.data && res.data.code === 0) {
        list.value = res.data.data
        if (list.value && list.value.length > 0) {
          // 接单成功
          isShowProgress.value = false
          isCancelSubmit.value = false
          isSubmit.value = true
          stopPoll()
          stopCountdown()
          resetForm()
          uni.showToast({ title: '申请已被骑手接单！', icon: 'success', duration: 3000 })
        }
      }
    } catch { }
  }, 1000)
}

function stopPoll() {
  if (pollTimer) clearInterval(pollTimer)
  pollTimer = null
}

function startCountdown() {
  countdown.value = COUNTDOWN_MAX
  if (cdTimer) clearInterval(cdTimer)
  cdTimer = setInterval(() => {
    countdown.value -= 1000
    if (countdown.value <= 0) {
      onCountdownEnd()
    }
  }, 1000)
}

function stopCountdown() {
  if (cdTimer) clearInterval(cdTimer)
  cdTimer = null
}

function onCountdownEnd() {
  stopPoll()
  stopCountdown()
  uni.showToast({ title: '申请未被接单，请重新申请！', icon: 'success', duration: 4000 })
  isShowProgress.value = false
  isCancelSubmit.value = false
  isSubmit.value = true
}

function resetForm() {
  form.decDepts = null
  form.decDept = null
  form.decBedNo = null
  form.decTel = null
  form.carryingtools = null
  form.carryingtoolsCount = 1
  form.outnumber = 1
  form.isOrdered = false
  form.orderedDatetime = null
}

async function getCarryToolsType() {
  try {
    const res = await queryService.getDataDictionary('db_tasksheetcarryingtools_type')
    if (res.data && res.data.code === 0) {
      formData.carryingtoolsDatas = res.data.data.dictionaryList || []
      if (formData.carryingtoolsDatas.length > 0) {
        form.carryingtools = formData.carryingtoolsDatas[0].id
      }
    } else {
      uni.showToast({ title: '获取运送工具类别失败！', icon: 'none' })
    }
  } catch {
    uni.showToast({ title: '获取运送工具类别失败！', icon: 'none' })
  }
}

async function getPaymentMethodType() {
  try {
    const res = await queryService.getDataDictionary('db_payment_mode_type')
    if (res.data && res.data.code === 0) {
      formData.paymentMethodDatas = res.data.data.dictionaryList || []
      if (formData.paymentMethodDatas.length > 0) {
        form.paymentMethod = formData.paymentMethodDatas[0].id
      }
    } else {
      uni.showToast({ title: '获取支付方式列表失败！', icon: 'none' })
    }
  } catch {
    uni.showToast({ title: '获取支付方式列表失败！', icon: 'none' })
  }
}

async function getGrids() {
  try {
    const res = await queryService.getGrids()
    if (res.data && res.data.code === 0) {
      formData.decDeptDatas = res.data.data || []
      // 构建父子结构
      deptParents.value = formData.decDeptDatas
      deptChildrenMap.value = {}
      deptParents.value.forEach((p: any) => {
        deptChildrenMap.value[p.id] = Array.isArray(p.children) ? p.children : []
      })
      // 初始化两列
      deptMultiRange.value[0] = deptParents.value.map((p: any) => p.gridFullname || p.gridName || p.name || p.label || '')
      const firstParent = deptParents.value[0]
      const firstChildren = firstParent ? (deptChildrenMap.value[firstParent.id] || []) : []
      deptMultiRange.value[1] = firstChildren.length > 0
        ? firstChildren.map((c: any) => c.gridFullname || c.gridName || c.name || c.label || '')
        : ['无子项']
      deptMultiValue.value = [0, 0]

      // 默认选择：若有子项选第一个子项，否则选第一个父项
      if (firstParent) {
        if (firstChildren.length > 0) {
          form.decDept = firstChildren[0].id
          form.decDepts = ['', firstChildren[0].id]
        } else {
          form.decDept = firstParent.id
          form.decDepts = ['', firstParent.id]
        }
      }
    } else {
      uni.showToast({ title: '获取网格列表失败！', icon: 'none' })
    }
  } catch {
    uni.showToast({ title: '获取网格列表失败！', icon: 'none' })
  }
}

onMounted(async () => {
  // 获取 openid（仅在微信小程序）
  // #ifdef MP-WEIXIN
  const openid = uni.getStorageSync('openid')
  if (!openid) {
    try { getService.getOpenId && getService.getOpenId() } catch { }
  }
  // #endif

  await Promise.all([getCarryToolsType(), getPaymentMethodType(), getGrids()])
})

onUnmounted(() => {
  stopPoll()
  stopCountdown()
})

function toFullDateTime(timeStr: string): string {
  const now = new Date()
  const yyyy = now.getFullYear()
  const MM = String(now.getMonth() + 1).padStart(2, '0')
  const dd = String(now.getDate()).padStart(2, '0')
  if (!timeStr) return `${yyyy}-${MM}-${dd} 00:00:00`
  const parts = String(timeStr).split(':')
  const h = String(parts[0] ?? '00').padStart(2, '0')
  const m = String(parts[1] ?? '00').padStart(2, '0')
  const s = String(parts[2] ?? '00').padStart(2, '0')
  return `${yyyy}-${MM}-${dd} ${h}:${m}:${s}`
}
</script>

<style scoped>
.page {
  min-height: 100vh;
  background: #f5f7fb;
}

.card {
  margin: 24rpx;
  padding: 24rpx;
  background: #fff;
  border-radius: 16rpx;
  box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.06);
}

.title {
  font-size: 34rpx;
  font-weight: 600;
  margin-bottom: 12rpx;
  color: #111;
}

.form-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20rpx 0;
  border-bottom: 1rpx solid #f0f0f0;
}

.label {
  color: #333;
  font-size: 28rpx;
}

.required::before {
  content: '*';
  color: #ff4d4f;
  margin-right: 8rpx;
}

.input {
  text-align: right;
  flex: 1;
  margin-left: 24rpx;
  font-size: 28rpx;
  color: #333;
}

.picker-value {
  flex: 1;
  text-align: right;
  margin-left: 24rpx;
  color: #333;
  font-size: 28rpx;
}

.picker-value.placeholder {
  color: #999;
}

.btns {
  display: flex;
  gap: 20rpx;
  margin-top: 24rpx;
}

.btn {
  flex: 1;
  padding: 0 20rpx;
  border-radius: 12rpx;
  font-size: 30rpx;
}

.btn.primary {
  background: #007aff;
  color: #fff;
}

.btn.outline {
  background: #fff;
  color: #007aff;
  border: 2rpx solid #007aff;
}

.overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 999;
}

.overlay-card {
  width: 80%;
  background: #fff;
  border-radius: 16rpx;
  padding: 32rpx;
  text-align: center;
}

.overlay-title {
  display: block;
  font-size: 30rpx;
  color: #333;
  margin-bottom: 12rpx;
}

.overlay-time {
  display: block;
  font-size: 40rpx;
  color: #007aff;
  margin-bottom: 16rpx;
  font-weight: 600;
}
</style>
