<!-- 起降场划设面板 -->
<template>
  <div class="panel-qjchs flex flex-col aside-left-inner">
    <div class="title-main">起降场规划</div>
    <el-steps :active="currentStep" finish-status="success" align-center>
      <el-step title="起降场划设" />
      <el-step title="起降场评估" />
    </el-steps>

    <div class="flex-1 relative mb-4">
      <Transition name="emerge-left">
        <el-form ref="formRef" v-show="currentStep === 0" :model="form" :rules="rules" label-position="left"
          size="large" class="p-form p-main" hide-required-asterisk>
          <el-form-item label="名称" prop="name">
            <el-input v-model="form.name" clearable></el-input>
          </el-form-item>
          <el-form-item label="无人机类型" prop="aircraftType">
            <el-select v-model="form.aircraftType" placeholder="">
              <el-option v-for="item in uavList" :label="item.label" :value="item.value" />
            </el-select>
          </el-form-item>
          <el-form-item label="时间类型" prop="type">
            <el-radio-group v-model="form.type" size="large">
              <el-radio-button label="长期" value="长期" />
              <el-radio-button label="临时" value="临时" />
            </el-radio-group>
          </el-form-item>
          <template v-if="form.type === '临时'">
            <el-form-item label="日期" prop="startDate">
              <el-date-picker v-model="form.startDate" value-format="YYYY-MM-DD" type="date"
                class="flex-1"></el-date-picker>
              <div class="mx-3">--</div>
              <el-date-picker v-model="form.endDate" value-format="YYYY-MM-DD" type="date"
                class="flex-1"></el-date-picker>
            </el-form-item>
            <el-form-item label="时间" prop="startTime">
              <el-time-select v-model="form.startTime" :max-time="form.endTime" placeholder="" start="00:00"
                step="00:15" end="23:45" class="flex-1" />
              <div class="mx-3">--</div>
              <el-time-select v-model="form.endTime" :min-time="form.startTime" placeholder="" start="00:00"
                step="00:15" end="23:45" class="flex-1" />
            </el-form-item>
            <el-form-item label="划设方式" prop="dataType">
              <el-radio-group v-model="form.dataType" size="large">
                <el-radio label="手动划设" value="手动划设" />
                <el-radio label="导入" value="导入" />
              </el-radio-group>
            </el-form-item>
          </template>
          <el-form-item label="类型" prop="drawType" v-if="form.dataType === '手动划设'">
            <el-radio-group v-model="form.drawType" size="large">
              <el-radio-button v-for="item in drawTypes" :label="item.label" :value="item.value" />
            </el-radio-group>
          </el-form-item>
          <el-form-item label="上传文件" prop="file" v-else>
            <el-upload v-model:file-list="form.file" action="" class="single-uplaod">
              <div class="upload-trigger">点击上传文件</div>
            </el-upload>
          </el-form-item>
          <el-form-item label="高度" prop="height" v-if="form.drawType !== 'funnel'">
            <el-input v-model="form.height" type="number" clearable>
              <template #suffix>
                <span>米</span>
              </template>
            </el-input>
          </el-form-item>
          <el-form-item label="顶半径" prop="topRadius" v-if="['mesh', 'point', 'funnel'].includes(form.drawType)">
            <el-input v-model="form.topRadius" type="number" clearable>
              <template #suffix>
                <span>米</span>
              </template>
            </el-input>
          </el-form-item>
          <el-form-item label="底半径" prop="bottomRadius" v-if="['mesh', 'funnel'].includes(form.drawType)">
            <el-input v-model="form.bottomRadius" type="number" clearable>
              <template #suffix>
                <span>米</span>
              </template>
            </el-input>
          </el-form-item>
          <template v-if="form.drawType === 'funnel'">
            <el-form-item label="顶高度" prop="topHeight">
              <el-input v-model="form.topHeight" type="number" clearable>
                <template #suffix>
                  <span>米</span>
                </template>
              </el-input>
            </el-form-item>
            <el-form-item label="底高度" prop="bottomHeight">
              <el-input v-model="form.bottomHeight" type="number" clearable>
                <template #suffix>
                  <span>米</span>
                </template>
              </el-input>
            </el-form-item>
          </template>
          <el-form-item label="绘制空域">
            <el-button class="btn-secondary" @click="handleDraw">绘制</el-button>
          </el-form-item>
        </el-form>
      </Transition>
      <Transition name="emerge-right">
        <div v-show="currentStep === 1" class="p-main  flex flex-col pr-0">
          <el-form-item label="网格查询">
            <el-button class="btn-secondary ml-4" @click="handleInspect(true)">查询网格</el-button>
            <el-button class="btn-secondary ml-4" @click="handleInspect(false)">关闭网格</el-button>
          </el-form-item>

          <div class="flex-1 overflow-y-auto pr-2">
            <div v-if="isSafe" class="msg-safe mb-2">当前空域无冲突!</div>

            <template v-else>
              <div v-for="item in results" :key="item.title" class="mb-3">
                <div class="title-sub">
                  {{ item.title }}
                  <div class="flex-1 flex justify-between items-center pl-2">
                    <span v-if="item.level" class="risk-label"
                      :class="riskTypes.find(i => i.value === item.level).color">{{
                        riskTypes.find(i => i.value === item.level).label
                      }}</span>
                    <i v-else></i>
                    <span class="btn-inline" @click="handleReInspect">重新评估</span>
                  </div>
                </div>
                <table class="table-default stripe mt-2">
                  <thead>
                    <tr>
                      <th v-for="th in item.cols">{{ th }}</th>
                      <th class="w-20">地图显示</th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr v-for="row in item.details">
                      <td v-for="key in Object.keys(item.cols)">{{ row[key] }}</td>
                      <td class="w-20">
                        <el-checkbox size="large" v-model="row.display"
                          :disabled="(row.id !== '3-3' && !row.cubes.length) || (row.id === '3-3' && item.details.every(r => r.cubes.length === 0))"
                          @change="val => toggleCubeDetail(row, val)"></el-checkbox>
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </template>
          </div>
        </div>
      </Transition>
    </div>
    <div class="text-center">
      <el-button v-if="currentStep === 0" :disabled="!hasDraw" class="btn-main" @click="toNext">下一步</el-button>
      <template v-if="currentStep === 1">
        <el-button class="btn-main" @click="toPrev">上一步</el-button>
        <el-button class="btn-main" @click="handleSave" :loading="loading.save">保存</el-button>
      </template>
    </div>

  </div>
</template>

<script setup>
import { onBeforeUnmount, ref, watch, reactive, computed } from 'vue';
import { drawArea, clearDraw, InspectCube, showShapes, InspectPathCube } from '@/utils/map/addLayer'
import { useMapStore } from '@/store/map';
import { uavList } from '@/utils/options';
import { AddPlot } from '@/service/http';
import { riskTypes } from '@/utils/options';
import useLayoutStore from '@/store/layout';

const layoutStore = useLayoutStore()
const mapStore = useMapStore()

const currentStep = ref(0)

const form = ref({
  aircraftType: '01',
  dataType: '手动划设',
  type: '长期',
  drawType: 'funnel',
  height: '100',
  topHeight: '110',
  bottomHeight: '60',
  topRadius: '150',
  bottomRadius: '50'
})

const drawTypes = [
  { label: '漏斗', value: 'funnel', geoType: '5', shapeType: 'funnel' },
  { label: '圆台', value: 'mesh', geoType: '6', shapeType: 'frustum-cone' },
  { label: '圆锥', value: 'point', geoType: '4', shapeType: 'inverted-cone' }
]

const rules = {
  name: [{ required: true, message: '请输入空域名称', trigger: 'none' }],
  height: [{ required: true, message: '此项不可为空', trigger: 'none' }],
  topRadius: [{ required: true, message: '此项不可为空', trigger: 'none' }],
  bottomRadius: [{ required: true, message: '此项不可为空', trigger: 'none' }],
  topHeight: [{ required: true, message: '此项不可为空', trigger: 'none' }],
  bottomHeight: [{ required: true, message: '此项不可为空', trigger: 'none' }],
}

const formRef = ref(null)

const results = ref([
  {
    title: '空域评估',
    level: null,
    cols: { areaName: '冲突空域', time: '冲突时段', height: '冲突高度' },
    details: []
  },
  {
    title: '计划冲突',
    level: null,
    cols: { areaName: '冲突空域', time: '冲突时段', height: '冲突高度' },
    details: []
  },
  {
    title: '障碍物分析',
    level: null,
    cols: { object: '冲突空域', height: '冲突高度' },
    details: []
  },
  {
    title: '地面安全评估',
    level: null,
    cols: { element: '要素', coverage: '覆盖率' },
    details: []
  }
])

const isSafe = computed(() => {
  return results.value.every(i => i.level === 1)
})

const hasDraw = ref(false)

async function handleDraw() {
  formRef.value.validateField(['height', 'topRadius', 'bottomRadius', 'topHeight', 'bottomHeight'], async (isValid) => {
    if (!isValid) return
    if (hasDraw.value) {
      showShapes({
        id: 'qjchs_drew_non_editable',
        data: null
      })
      await new Promise((res) => {
        setTimeout(() => res(), 500);
      })
    }
    // 处理绘制
    drawArea({
      ...form.value,
      color: [0, 255, 0, 0.5]
    })
  })
}

function getShapeInfo() {
  let res = {}
  const { height, topRadius, bottomRadius, topHeight, bottomHeight } = form.value
  const geoType = drawTypes.find(i => i.value === form.value.drawType).geoType
  const { x, y, z } = drawGeometry
  switch (geoType) {
    case '4':
      res = {
        point: { x, y, z },
        height: +height,
        radius: +topRadius
      }
      break;
    case '5':
      res = {
        point: { x, y, z },
        coneHeight: +topHeight,
        cylinderHeight: +bottomHeight,
        topRadius: +topRadius,
        bottomRadius: +bottomRadius
      }
      break;
    case '6':
      res = {
        point: { x, y, z },
        height: +height,
        topRadius: +topRadius,
        bottomRadius: +bottomRadius
      }
      break;
  }
  return res
}

function handleInspect(show = true) {
  if (show) {
    layoutStore.toggleGlobalLoading(true)
  }
  InspectCube({
    type: drawTypes.find(i => i.value === form.value.drawType).shapeType,
    id: 'inspect_qjchs',
    show,
    shape: show ? getShapeInfo() : {}
  })
}

let drawGeometry

watch(() => mapStore.draw_geometry, (val) => {
  console.log('draw_geometry:', val)
  drawGeometry = val
  hasDraw.value = true
}, { deep: true })

watch(() => mapStore.cubeResult, (val) => {
  console.log('cubeResult:', val)
  formatResult(val)
}, { deep: true })

function clearResults() {
  results.value.forEach(v => {
    v.details = []
    v.level = null
  })
}

function formatResult(res) {
  console.log('formatResult:', res)

  clearResults()
  clearAllCubeDetail()
  const { groundSafety, lineConflictArray, obstacle, spaceConflictArray, spaceRisk, lineRisk } = res

  results.value[0].level = spaceRisk
  results.value[1].level = lineRisk
  results.value[2].level = obstacle.risk
  results.value[3].level = groundSafety.risk

  results.value[0].details = spaceConflictArray.map((i, index) => ({
    id: `0-${index}`,
    areaName: i.gridName,
    height: i.heightRange,
    time: i.conflictTime,
    cubes: i.gridEntityList,
    display: false,
  }))

  results.value[1].details = lineConflictArray.map((i, index) => ({
    id: `1-${index}`,
    areaName: i.gridName,
    height: i.heightRange,
    time: i.conflictTime,
    cubes: i.gridEntityList,
    display: false
  }))

  results.value[2].details = [
    {
      id: '2-0', time: '01-249:00-01-25 10-00', object: '建筑物',
      height: obstacle.buildingConflictHeight, cubes: obstacle.buildingsConflictArray, display: false
    },
    {
      id: '2-1', time: '01-249:00-01-25 10-00', object: '建筑物缓冲区',
      height: obstacle.buildingBufferConflictHeight, cubes: obstacle.buildingsBufferConflictArray, display: false
    },
  ]

  const toPercent = (num) => {
    return Math.round(num * 100) + '%'
  }

  results.value[3].details = [
    { id: '3-0', element: '道路', coverage: toPercent(groundSafety.road), cubes: groundSafety.gridGoupMap.road, display: false },
    { id: '3-1', element: '河流', coverage: toPercent(groundSafety.river), cubes: groundSafety.gridGoupMap.river, display: false },
    { id: '3-2', element: '绿化', coverage: toPercent(groundSafety.green), cubes: groundSafety.gridGoupMap.green, display: false },
    { id: '3-3', element: '综合占比', coverage: toPercent(groundSafety.road + groundSafety.river + groundSafety.green), display: false },
  ]

  layoutStore.toggleGlobalLoading(false)
}

function handleDisplay(row, val) {
  console.log(row, val)
}

function toNext() {
  formRef.value.validate(valid => {
    if (valid) {
      layoutStore.toggleGlobalLoading(true)
      clearDraw()
      showShapes({
        id: 'qjchs_drew_non_editable',
        data: [{
          type: drawTypes.find(i => i.value === form.value.drawType).shapeType,
          shape: {
            ...getShapeInfo(),
            color: [0, 255, 0, 0.5]
          }
        }]
      })
      handleInspect(true)
      currentStep.value = 1
    }
  })
}

let addedCubeDetailIds = []

function toggleCubeDetail(row, status) {
  console.log(row, status)
  if (row.id === '3-3') {
    // 处理综合占比
    results.value[3].details.forEach(gRow => {
      if (gRow.display !== status && gRow.cubes.length) {
        gRow.display = status
        toggleCubeDetail(gRow, status)
      }
    })
  } else {
    if (!row.cubes.length) return
    const id = 'hxhs_' + row.id
    if (status) {
      addedCubeDetailIds.push(id)
    } else {
      const targetIndex = addedCubeDetailIds.findIndex(i => i === id)
      addedCubeDetailIds.splice(targetIndex, 1)
    }
    InspectPathCube({
      id,
      show: status,
      points: row.cubes.map(c => ({
        x: c.x,
        y: c.y,
        z: c.z,
        color: c.color
      })),
      size: {
        x: row.cubes[0].boxSize.lonLength,
        y: row.cubes[0].boxSize.latLength,
        z: row.cubes[0].boxSize.height
      }
    })
  }
}

function clearAllCubeDetail() {
  addedCubeDetailIds.forEach(id => {
    InspectPathCube({
      id,
      show: false,
    })
  })
  addedCubeDetailIds = []
}

function handleReInspect() {
  layoutStore.toggleGlobalLoading(true)
  handleInspect(false)
  setTimeout(() => {
    handleInspect(true)
  }, 500);
}

function toPrev() {
  currentStep.value = 0
  handleInspect(false)
  clearAllCubeDetail()
  clearResults()
}

const loading = reactive({
  save: false
})

function handleSave() {
  loading.save = true
  let params = {
    ...form.value,
    spaceType: form.value.areaType,
    geoType: drawTypes.find(i => i.value === form.value.drawType).geoType,
    upRadius: form.value.topRadius,
    downRadius: form.value.bottomRadius,
    nature: form.value.type,
    drawType: '01',
    shape: JSON.stringify(getShapeInfo())
  }
  AddPlot(params).then(({ data: res }) => {
    if (res.msg === 'success') {
      ElMessage({ offset: 90, type: 'success', message: '保存成功' })
    } else {
      ElMessage({ offset: 90, type: 'error', message: `保存失败，${res.msg}` })
    }
  }).catch((e) => {
    ElMessage({ offset: 90, type: 'error', message: `保存失败，${e}` })
  }).finally(() => {
    loading.save = false
  })
}

onBeforeUnmount(() => {
  clearDraw()
  handleInspect(false)
  showShapes({
    id: 'qjchs_drew_non_editable',
    data: null
  })
  clearResults()
  clearAllCubeDetail()
})

</script>

<style lang="scss">
@use '../../../assets/styles/panel-form.scss';
</style>

<style lang="scss" scoped>
.panel-qjchs {
  :deep(.p-form) {
    .el-form-item__label {
      width: 125px;
    }
  }
}
</style>