<template>
  <div class="water-disaster">
    <!-- 基本信息 -->
    <PanelItem title="基本信息" v-if="!isContinue">
      <van-form>
        <!-- 路况类别 -->
        <BasePicker v-model="formData.roadConditionType" :options="options['waterRoadConditionType']" label="路况类别" placeholder="请选择" />

        <!-- 是否阻断 (event.isBlocked) -->
        <BasePicker v-model="formData.event.isBlocked" :options="options['yesNoBool']" label="是否阻断" placeholder="请选择" />

        <!-- 抢险进度 (event.repairProgress) -->
        <BasePicker v-model="formData.event.repairProgress" :options="options['repairProgress']" label="抢险进度" placeholder="请选择" />

        <!-- 水毁处数 (event.damageCount) -->
        <van-field v-model="formData.event.damageCount" label="水毁处数" placeholder="请填写" type="number" />

        <!-- 阻断里程 (event.blockedMileage) -->
        <van-field v-model="formData.event.blockedMileage" label="阻断里程" placeholder="请填写" type="digit">
          <template #button>
            <span class="field-unit">公里</span>
          </template>
        </van-field>

        <!-- 发生时间 (顶层 occurTime) -->
        <BaseDatePicker v-model="formData.occurTime" label="发生时间" placeholder="请选择时间" :columnsType="['year', 'month', 'day', 'hour', 'minute']" />
        <div class="calibrate-time-btn" @click="calibrateTime">
          <van-icon name="replay" />
          <span>校准时间</span>
        </div>

        <!-- 线路编号 (顶层 routeNo) -->
        <RoadRoutesPicker v-model="formData.routeNo" label="线路编号" placeholder="请线路" @change="handleRouteNoChange" />

        <!-- 起点桩号 (event.startStakeNo) -->
        <van-field v-model="formData.event.startStakeNo" label="起点桩号(K)" placeholder="请填写" />

        <!-- 止点桩号 (event.endStakeNo) -->
        <van-field v-model="formData.event.endStakeNo" label="止点桩号(K)" placeholder="请填写" />

        <van-field v-model="formData.event.longitude" label="经度" placeholder="请填写" />

        <van-field v-model="formData.event.latitude" label="纬度" placeholder="请填写" />

        <!-- 路况位置 (occurLocation) -->
        <van-field v-model="formData.occurLocation" label="路况位置" placeholder="请填写" />

        <!-- 阻断点小地名 (event.blockedPointName) -->
        <van-field v-model="formData.event.blockedPointName" label="阻断点小地名" placeholder="请填写" />
      </van-form>
    </PanelItem>

    <!-- 处置情况 (report) -->
    <PanelItem title="处置情况">
      <div class="disposal-measures">
        <span class="measures-label">处置措施</span>
        <div class="measures-options">
          <van-row gutter="10">
            <van-col v-for="(item, index) in options['disposalMeasures']" :span="24 / options['disposalMeasures'].length" :key="index">
              <van-button block plain :type="item.value === formData.report.disposalMeasures ? 'primary' : 'default'" @click="formData.report.disposalMeasures = item.value">
                {{ item.label }}
              </van-button>
            </van-col>
          </van-row>
        </div>
      </div>

      <!-- 预计恢复时间 (report.expectRecoverTime) -->
      <BaseDatePicker v-model="formData.report.expectRecoverTime" label="预计恢复时间" placeholder="请选择时间" :min-date="minDate" :max-date="maxDate" type="datetime" />

      <!-- 实际恢复时间 (report.actualRecoverTime) -->
      <BaseDatePicker v-model="formData.report.actualRecoverTime" label="实际恢复时间" placeholder="请选择时间" :min-date="minDate" :max-date="maxDate" type="datetime" />
    </PanelItem>

    <!-- 人员车辆 (report) -->
    <PanelItem title="人员车辆">
      <van-form>
        <van-field v-model="formData.report.injuredCount" label="受伤人员" placeholder="请填写" type="number">
          <template #button>
            <span class="field-unit">人</span>
          </template>
        </van-field>
        <van-field v-model="formData.report.deadCount" label="死亡人员" placeholder="请填写" type="number">
          <template #button>
            <span class="field-unit">人</span>
          </template>
        </van-field>
        <van-field v-model="formData.report.strandedPersonCount" label="滞留人员" placeholder="请填写" type="number">
          <template #button>
            <span class="field-unit">人</span>
          </template>
        </van-field>
        <van-field v-model="formData.report.damagedVehicleCount" label="损坏车辆" placeholder="请填写" type="number">
          <template #button>
            <span class="field-unit">辆</span>
          </template>
        </van-field>
        <van-field v-model="formData.report.strandedVehicleCount" label="滞留车辆" placeholder="请填写" type="number">
          <template #button>
            <span class="field-unit">辆</span>
          </template>
        </van-field>
      </van-form>
    </PanelItem>

    <!-- 灾毁损失 (lossList) -->
    <PanelItem title="灾毁损失">
      <LossList v-model="formData.lossList" />
      <van-field v-model="formData.report.remark" label="处理情况" placeholder="请填写（选填）" />
      <van-field v-model="formData.report.totalLossAmount" label="损失总金额" placeholder="请填写（选填）" type="digit">
        <template #button>
          <span class="field-unit">万元</span>
        </template>
      </van-field>
    </PanelItem>

    <!-- 投入资源 (report) -->
    <PanelItem>
      <van-field v-model="formData.report.investedMachinery" label="投入机械" placeholder="请填写" type="digit">
        <template #button>
          <span class="field-unit">台/班</span>
        </template>
      </van-field>
      <van-field v-model="formData.report.investedManpower" label="投入人力" placeholder="请填写" type="number">
        <template #button>
          <span class="field-unit">人次</span>
        </template>
      </van-field>
      <van-field v-model="formData.report.investedFunds" label="投入资金" placeholder="请填写" type="digit">
        <template #button>
          <span class="field-unit">万元</span>
        </template>
      </van-field>
      <van-field v-model="formData.report.siteDescription" label="现场描述" placeholder="请填写" type="textarea" rows="2" autosize />
      <van-field label="附件" center>
        <template #input>
          <van-uploader accept="video/*,image/*" :modelValue="getFileList()" :after-read="afterRead" multiple :max-count="7" @delete="removeFile" />
        </template>
      </van-field>
    </PanelItem>
    <PanelItem v-if="!isContinue || (isContinue && !detail?.event.needsRecovery)">
      <!-- 是否需要恢复重建 (event.needsRecovery) -->
      <BasePicker v-model="formData.event.needsRecovery" :options="options['yesNoBool']" label="是否需要恢复重建" placeholder="请选择" />
      <!-- 恢复重建预估费用 (event.estimatedRecoveryCost) -->
      <van-field v-model="formData.event.estimatedRecoveryCost" v-if="formData?.event.needsRecovery" label="恢复重建预估费用" placeholder="请填写" type="digit">
        <template #button>
          <span class="field-unit">万元</span>
        </template>
      </van-field>
    </PanelItem>

    <!-- 提交按钮 -->
    <van-button type="primary" class="footer-btn" @click="handleSubmit" :loading="submitting"> 提交 </van-button>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue'
import { showToast, showFailToast, showLoadingToast } from 'vant'
import PanelItem from '@/components/PanelItem.vue'
import BasePicker from '@/components/BasePicker.vue'
import BaseDatePicker from '@/components/BaseDatePicker.vue'
import RoadRoutesPicker from '../RoadRoutesPicker.vue'
import LossList from './LossList.vue'
import { useRouter, useRoute } from 'vue-router'
import { request } from '@shared/utils/request'
import { useOptions } from '@shared/composables/useOptions'
import mockFormData from '../waterDisasterFormData.json'

const route = useRoute()
const { options } = useOptions()
// 是否为续报
const isContinue = computed(() => route.query.isContinue)

// 表单数据 - 按 Request 接口结构定义，使用 ref 包装
const formData = ref({
  // 顶层字段
  occurLocation: '', // 发生地点
  occurTime: null, // 发生时间
  roadConditionType: '', // 路况类别
  routeNo: '', // 线路编号

  // event 对象
  event: {
    blockedMileage: '', // 阻断里程
    blockedPointName: '', // 阻断点小地名
    contactPerson: '', // 联系人
    contactPhone: '', // 联系电话
    damageCount: '', // 水毁处数
    district: '', // 上报区县
    endStakeNo: '', // 止点桩号
    estimatedRecoveryCost: '', // 恢复重建预估费用
    inspectionMileage: '', // 巡查里程
    isBlocked: '', // 是否阻断
    needsRecovery: '', // 是否需要恢复重建
    repairProgress: '', // 抢险进度
    reporterUnit: '', // 填报单位
    startStakeNo: '' // 起点桩号
  },

  // report 对象
  report: {
    actualRecoverTime: '', // 实际恢复时间
    damagedVehicleCount: '', // 损坏车辆
    deadCount: '', // 死亡人员
    disposalMeasures: '', // 处置措施（单个值，不再用逗号分隔）
    expectRecoverTime: '', // 预计恢复时间
    injuredCount: '', // 受伤人员
    investedFunds: '', // 已投资金
    investedMachinery: '', // 已投机械
    investedManpower: '', // 已投人力
    remark: '', // 处理情况/备注
    siteDescription: '', // 现场描述
    strandedPersonCount: '', // 滞留人员
    strandedVehicleCount: '', // 滞留车辆
    totalLossAmount: '' // 损失总金额
  },

  // lossList 数组
  lossList: [],

  // fileList 数组
  fileList: []
})

const getFileList = () => {
  const fileList = formData.value.fileList?.map((item) => {
    return {
      url: item.fileUrl,
      name: item.fileName
    }
  })

  return fileList
}

const submitting = ref(false)

// 时间选择器范围
const minDate = new Date(2020, 0, 1)
const maxDate = new Date(2030, 11, 31)

const initFormData = (newVal) => {
  if (newVal && Object.keys(newVal).length > 0) {
    // 深度合并数据 - 直接替换整个对象
    formData.value = {
      occurLocation: newVal.occurLocation || '',
      occurTime: newVal.occurTime || formatTime(),
      roadConditionType: newVal.roadConditionType || '',
      routeNo: newVal.routeNo || '',
      event: { ...formData.value.event, ...(newVal.event || {}) },
      report: { ...formData.value.report, ...(newVal.report || {}) },
      lossList: newVal.lossList || [],
      fileList: newVal.fileList || []
    }
  }
}

// 校准时间
const calibrateTime = () => {
  const now = new Date()
  const formatted = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`
  formData.value.occurTime = formatted
  showToast('时间已校准为当前时间')
}

// 图片上传处理
const afterImageRead = (file) => {
  console.log('图片上传:', file)
}

const onOversize = () => {
  showFailToast('图片大小不能超过500KB')
}

const afterVideoRead = (file) => {
  console.log('视频上传:', file)
}

const onVideoOversize = () => {
  showFailToast('视频大小不能超过20MB')
}

const isImageFile = (file) => {
  // 根据url后缀判断
  const imageExtensions = /\.(jpg|jpeg|png|gif|webp|bmp|svg)$/i
  if (file.fileUrl && imageExtensions.test(file.fileUrl)) return true
  // 根据文件类型判断
  if (file.type && file.type.startsWith('image/')) return true
  return false
}

const isVideoFile = (file) => {
  // 根据url后缀判断
  const videoExtensions = /\.(mp4|avi|mov|wmv|flv|mkv)$/i
  if (file.fileUrl && videoExtensions.test(file.fileUrl)) return true
}

const handleRouteNoChange = (item) => {
  formData.value.event.startStakeNo = item.startStakeNo
  formData.value.event.endStakeNo = item.endStakeNo
}

/**
 * 判断图片是否可以上传
 * @param {File} file - 图片文件
 * @returns {boolean} 是否允许上传
 */
const isValidImage = (file) => {
  // 校验文件类型
  const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'

  if (!isJpgOrPng) {
    showFailToast('只能上传 JPG/PNG 格式的图片！')
    return false
  }

  // 校验文件大小（500KB = 500 * 1024 bytes）
  const isLt500k = file.size / 1024 < 500

  if (!isLt500k) {
    showFailToast(`图片大小不能超过 500KB！当前大小：${(file.size / 1024).toFixed(2)}KB`)
    return false
  }

  return true
}

/**
 * 判断视频是否可以上传
 * @param {File} file - 视频文件
 * @returns {boolean} 是否允许上传
 */
const isValidVideo = (file) => {
  // 校验文件类型
  const allowedTypes = ['video/mp4', 'video/quicktime', 'video/x-msvideo', 'video/webm']
  const isValidType = allowedTypes.includes(file.type)

  if (!isValidType) {
    showFailToast('请上传有效的视频文件（MP4、MOV、AVI、WEBM格式）！')
    return false
  }

  // 校验文件大小（50MB = 50 * 1024 * 1024 bytes）
  const maxSize = 50 * 1024 * 1024
  const isValidSize = file.size <= maxSize

  if (!isValidSize) {
    showFailToast(`视频大小不能超过 50MB！当前大小：${(file.size / 1024 / 1024).toFixed(2)}MB`)
    return false
  }

  return true
}

/**
 * 统一的上传前校验
 * @param {File} file - 上传的文件
 * @returns {boolean} 是否允许上传
 */
const checkFile = (file) => {
  // 判断是否为图片
  if (file.type.startsWith('image/')) {
    const imageCount = formData.value.fileList?.filter((item) => item.fileType === 1).length
    if (imageCount == 6) {
      showFailToast('只能上传六张图片！')
      return false
    }

    return isValidImage(file)
  }

  // 判断是否为视频
  if (file.type.startsWith('video/')) {
    const videoCount = formData.value.fileList?.filter((item) => item.fileType === 2).length
    if (videoCount == 1) {
      showFailToast('只能上传一个视频文件！')
      return false
    }

    return isValidVideo(file)
  }

  showFailToast('只支持图片和视频文件！')
  return false
}

const afterRead = async (options) => {
  const file = options.file
  if (!checkFile(file)) return
  const toast = showLoadingToast({
    message: '上传中...',
    forbidClick: true,
    duration: 0 // 设置为0表示不会自动关闭
  })
  try {
    const uploadFormData = new FormData()
    uploadFormData.append('file', file)
    const res = await request({
      url: '/snow-ops-platform/file/upload',
      method: 'post',
      data: uploadFormData
    })
    toast.close()
    if (res.code === '00000') {
      const name = file.name
      const url = res.data
      const type = isImageFile({ fileUrl: url}) ? 1 : isVideoFile({ fileUrl: url}) ? 2 : 3
      const fileData = {
        fileName: name,
        fileUrl: url,
        fileType: type,
        fileSize: file.size
      }
      if (!formData.value.fileList) formData.value.fileList = []
      formData.value.fileList.push(fileData)
    } else {
      throw new Error(res.message)
    }
  } catch (error) {
    toast.close()
    showToast({
      type: 'fail',
      message: error.message
    })
  }
}

const removeFile = (file, index) => {
  // 删除文件
  formData.value.fileList.splice(index, 1)
}

// 简单的空值判断
const isEmpty = (value) => {
  return value === null || value === undefined || value === ''
}

const validate = () => {
  if (isEmpty(formData.value.roadConditionType)) {
    showToast('请选择路况类别')
    return false
  }
  if (isEmpty(formData.value.event?.isBlocked)) {
    showToast('请选择是否阻断')
    return false
  }
  if (isEmpty(formData.value.event?.repairProgress)) {
    showToast('请选择抢险进度')
    return false
  }
  if (isEmpty(formData.value.report?.disposalMeasures)) {
    showToast('请选择处置措施')
    return false
  }
  if (isEmpty(formData.value.event?.damageCount)) {
    showToast('请输入水毁处数')
    return false
  }
  if (isEmpty(formData.value.event?.blockedMileage)) {
    showToast('请输入阻断里程')
    return false
  }
  if (isEmpty(formData.value.occurTime)) {
    showToast('请选择发生时间')
    return false
  }
  if (isEmpty(formData.value.report?.expectRecoverTime)) {
    showToast('请输入预计恢复时间')
    return false
  }
  if (isEmpty(formData.value.routeNo)) {
    showToast('请输入线路编号')
    return false
  }
  if (isEmpty(formData.value.event?.startStakeNo)) {
    showToast('请输入起点桩号')
    return false
  }
  if (isEmpty(formData.value.event?.endStakeNo)) {
    showToast('请输入止点桩号')
    return false
  }
  if (isEmpty(formData.value.occurLocation)) {
    showToast('请输入路况位置')
    return false
  }
  if (isEmpty(formData.value.event?.blockedPointName)) {
    showToast('请输入阻断点小地名')
    return false
  }
  if (isEmpty(formData.value.event?.longitude)) {
    showToast('请输入经度')
    return false
  }
  if (isEmpty(formData.value.event?.latitude)) {
    showToast('请输入纬度')
    return false
  }
  if (isEmpty(formData.value.event?.needsRecovery)) {
    showToast('请选择是否需要恢复重建')
    return false
  }
  if (formData.value.event?.needsRecovery && isEmpty(formData.value.event?.estimatedRecoveryCost)) {
    showToast('请输入恢复重建预估费用')
    return false
  }
  return true
}

// 获取表单数据 - 返回 formData.value 的副本
const getFormData = () => {
  return { ...formData.value }
}

// 提交表单
const handleSubmit = async () => {
  // 验证表单
  if (!validate()) return

  submitting.value = true
  try {
    // 获取表单数据
    let formData = getFormData()

    // 添加事件类型和站点信息
    const submitData = {
      ...formData
      // 可以在这里添加站点信息等其他数据
    }

    const res = await request({
      url: '/snow-ops-platform/water-damage/addOrUpdate',
      method: 'post',
      data: submitData
    })

    if (res?.code === '00000') {
      showSuccessToast('提交成功')
      let isRebuilded = false
      if (isContinue && detail.value.event.needsRecovery) {
        // 如果之前已经进行了项目重建的流程，后续不再进行该流程
        isRebuilded = true
      }
      if (!isRebuilded && submitData.event.needsRecovery) {
        router.replace({
          name: 'RebuildAdd',
          params: {
            data: res.data.id
          }
        })
      } else {
        // 提交成功后返回列表页
        setTimeout(() => {
          router.replace('/disasterManagement')
        }, 500)
      }
    } else {
      showFailToast(res.message)
    }
  } catch (error) {
    showFailToast('提交失败，请重试')
    console.error('提交失败:', error)
  } finally {
    submitting.value = false
  }
}

const detail = ref(null)

// 获取灾毁详情
const getDisasterDetail = async () => {
  const id = route.query.id
  if (!id) {
    return
  }

  try {
    const result = await request({
      url: `/snow-ops-platform/water-damage/getById`,
      method: 'get',
      params: { id }
    })

    if (result?.data) {
      // 接口返回 Data 结构
      const data = result.data
      detail.value = result.data
      const newFormData = {
        ...data,
        lossList: null,
        report: route.query?.mock ? mockFormData : {},
        fileList: null
      }
      initFormData(newFormData)
    } else {
      showToast(result.message || '获取详情失败')
    }
  } catch (error) {
    console.error('获取灾毁详情失败:', error)
    showToast('获取详情失败，请稍后重试')
  }
}

// 日期格式化
const formatTime = (date = new Date()) => {
  const pad = (n) => n.toString().padStart(2, '0')
  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ` + `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`
}

onMounted(() => {
  formData.value.occurTime = formatTime()
  if (route.query.id) {
    getDisasterDetail()
  } else {
    initFormData(route.query?.mock ? mockFormData : {})
  }
})

// 暴露方法给父组件
defineExpose({
  validate,
  initFormData,
  getFormData
})
</script>

<style lang="scss" scoped>
.water-disaster {
  .coordinate-row {
    display: flex;
    gap: 8px;
    .coordinate-field {
      flex: 1;
    }
  }

  .calibrate-time-btn,
  .calibrate-coord-btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 12px;
    color: #1989fa;
    margin: 8px 0 8px 12px;
    padding: 4px 8px;
    background: #f0f7ff;
    border-radius: 20px;
    cursor: pointer;
    width: fit-content;
  }

  .field-unit {
    color: #969799;
    font-size: 14px;
    margin-left: 4px;
  }

  .disposal-measures {
    margin-bottom: 16px;
    .measures-label {
      font-size: 14px;
      color: #323233;
      display: block;
      margin-bottom: 8px;
    }
    .measures-options {
      :deep(.van-radio-group) {
        display: flex;
        flex-wrap: wrap;
        gap: 16px;
      }
      :deep(.van-radio) {
        margin-right: 0;
      }
    }
  }

  .attachment-tip {
    font-size: 12px;
    color: #969799;
    margin-bottom: 12px;
  }

  .upload-area {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
    .upload-btn {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      width: 80px;
      height: 80px;
      background: #f8f9fa;
      border: 1px dashed #dcdee0;
      border-radius: 8px;
      gap: 4px;
      font-size: 12px;
      color: #969799;
      cursor: pointer;
    }
  }

  .video-preview {
    margin-top: 12px;
  }

  :deep(.van-field__label) {
    width: 110px;
  }
}
.footer-btn {
  position: fixed;
  bottom: 15px;
  left: 50%;
  transform: translateX(-50%);
  width: calc(100% - 32px);
  max-width: 340px;
  border-radius: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  cursor: pointer;
  z-index: 10;

  &:active {
    opacity: 0.9;
    transform: translateX(-50%) scale(0.98);
  }
}
</style>
