<template>
  <div class="task-setting-container">
    <!-- 背景网格 -->
    <div class="grid-bg"></div>

    <!-- 顶部栏：标题 + 控制按钮 -->
    <div class="header">
      <div class="header-logo flex items-center">
        <i class="el-icon-shield text-red-500 mr-2 text-xl"></i>
        <h1>任务想定编辑</h1>
        <div class="info-value">{{ currentT0HMS }}</div>
        <small v-if="isRealtime">（实时）</small>
      </div>
      <div class="header-controls">
        <el-button class="btn军事" icon="el-icon-back" type="success" @click="goBack">返回</el-button>
        <el-button class="btn军事" icon="el-icon-save" type="primary" @click="saveTask">保存任务</el-button>
        <el-button class="btn军事" icon="el-icon-refresh" type="warning" @click="resetTask">重置</el-button>
      </div>
    </div>

    <!-- 三段式主布局 -->
    <el-container class="h-[calc(100vh-60px)] flex-row overflow-hidden">
      <!-- 左侧：装备树 -->
      <el-aside class="min-w-[240px] border-right border-[#0c4a6e] relative" width="10%">
        <div class="equipment-tree-container col-span-1">
          <div class="section-card h-full">
            <el-tree
              :data="equipmentTree"
              :expand-on-click-node="false"
              :indent="15"
              :props="defaultProps"
              class="equipment-tree"
              default-expand-all
              node-key="id"
              @node-click="handleEquipmentClick"
            />
          </div>
        </div>
      </el-aside>

      <!-- 中间：概览 + 甘特图 + 时序计划 -->
      <el-main class="p-0 h-full flex flex-col relative">
        <div class="main-border-decoration"></div>

        <div class="equipment-content-box flex-1 p-4 middle-layout">
          <!-- 1) 装备数量概览 -->
          <div class="section-card mb-4 overview-card">
            <div class="section-header">
              <h4 class="section-title">
                <i class="el-icon-dashboard mr-2"></i>
                装备数量概览
              </h4>
            </div>
            <div class="equipment-status-grid p-4 grid grid-cols-4 gap-3">
              <div class="status-card p-3 border border-blue-500/30 rounded">
                <div class="status-title text-sm text-gray-400 mb-1">总装备数</div>
                <div class="status-value text-2xl font-bold">{{ stastic.sumTotal }}</div>
              </div>
              <div class="status-card p-3 border border-green-500/30 rounded">
                <div class="status-title text-sm text-gray-400 mb-1">测量装备数</div>
                <div class="status-value text-2xl font-bold text-green-400">{{ stastic.cc }}</div>
              </div>
              <div class="status-card p-3 border border-purple-500/30 rounded">
                <div class="status-title text-sm text-gray-400 mb-1">干扰装备数</div>
                <div class="status-value text-2xl font-bold text-purple-400">{{ stastic.gr }}</div>
              </div>
              <div class="status-card p-3 border border-red-500/30 rounded">
                <div class="status-title text-sm text-gray-400 mb-1">靶标装备数</div>
                <div class="status-value text-2xl font-bold text-red-400">{{ stastic.bb }}</div>
              </div>
            </div>
          </div>

          <!-- 2) 任务甘特图 -->
          <div class="section-card mb-4 gantt-card">
            <div class="section-header">
              <h4 class="section-title">
                <i class="el-icon-date mr-2"></i>
                任务甘特图
              </h4>
              <div>
                <!--<el-input v-model="taskId" placeholder="任务ID（可选）" size="mini"-->
                <!--          style="width:220px;margin-right:8px;"/>-->
                <!--<el-button size="mini" @click="useDefaultGantt">默认数据</el-button>-->
                <!--<el-button :loading="loadingGantt" size="mini" type="primary" @click="fetchGanttFromApi">-->
                <!--  {{ loadingGantt ? '加载中...' : '接口拉取' }}-->
                <!--</el-button>-->
                <!--<span class="meta" style="margin-left:8px;">T0: {{ t0Display || '-' }}</span>-->
                <span class="meta" style="margin-left:8px;">事件数: {{ currentPreviewEvents.length }}</span>
              </div>
            </div>
            <div class="gantt-body">
              <!-- 子组件入参：时间线数据 + 类型配色 -->
              <GanttChart
                :default-duration="120"
                :time-margin="300"
                :timeline-data="currentPreviewEvents"
                :type-color-map="ganttTypeColorMap"
              />
              <div v-if="ganttError" class="meta" style="color:#ff6b6b;margin-top:6px;">{{ ganttError }}</div>
            </div>
          </div>

          <!-- 3) 时序计划（示例占位；只传入 map-data） -->
          <div class="timeline-wrapper">
            <TargetEquipmentMap
              :map-data="timingPlanData"
              :event-catalog="allKeyEvents"
              :plan="plan"
              @update="onSeqUpdate"
              @delete="onSeqDelete"
              @search-change="onSeqSearch"
            />
          </div>
        </div>
      </el-main>

      <!-- 右侧：任务预览与配置表单 -->
      <el-aside class="min-w-[240px] border-left border-[#0c4a6e] relative" width="20%">
        <div class="aside-border-decoration"></div>
        <div class="task-panel h-full">
          <div class="task-content">
            <!-- 任务基本信息 -->
            <task-basic-info
              :sub-task-id="plan.subTaskId"
              :task-id="plan.taskId"
              @update-targets-by-missile-type="updateTargetsByMissileType"
              @update-targets-by-missile-count="updateTargetsByMissileCount"
            />
            <!-- 理论抛洒点配置 -->
            <!--<runway-drop-setting ref="dropForm" v-model="runwayDrop"/>-->
            <!-- 气象环境配置 -->
            <weather-env-form ref="weatherRef" v-model="weather"/>
            <!-- 理论数据导入（触发弹窗） -->
            <Trajectory @do-import="doImport"/>

            <!-- 导入 Excel 弹窗 -->
            <ExcelImportDialog
              :max-files="10"
              :visible.sync="visible"
              title="导入理论数据"
              @confirm="onBindTargets"
              @error="onSingleError"
              @success="onSingleSuccess"
            />
          </div>
        </div>
      </el-aside>
    </el-container>

    <!-- 装备参数编辑对话框 -->
    <el-dialog
      :close-on-click-modal="false"
      :visible.sync="showEquipmentDialog"
      custom-class="equipment-dialog"
      title="编辑装备参试"
      width="520px"
    >
      <el-form :model="equipmentEditForm" label-width="96px" size="small">
        <el-form-item label="装备名称">
          <el-input v-model="equipmentEditForm.label" disabled/>
        </el-form-item>
        <el-form-item label="工作状态">
          <el-select v-model="equipmentEditForm.status" placeholder="选择工作状态">
            <el-option label="待命" value="standby"/>
            <el-option label="就绪" value="ready"/>
            <el-option label="维护中" value="maintenance"/>
          </el-select>
        </el-form-item>
        <el-form-item label="部署位置">
          <el-select v-model="equipmentEditForm.position" placeholder="选择部署位置">
            <el-option label="左翼" value="left"/>
            <el-option label="右翼" value="right"/>
            <el-option label="中央" value="center"/>
            <el-option label="前沿" value="front"/>
            <el-option label="后方" value="rear"/>
          </el-select>
        </el-form-item>
        <el-form-item label="备注信息">
          <el-input v-model="equipmentEditForm.notes" :rows="3" placeholder="请输入备注" type="textarea"/>
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="showEquipmentDialog = false">取消</el-button>
        <el-button type="primary" @click="confirmEquipmentEdit">保存</el-button>
      </div>
    </el-dialog>
    <!--总关键事件列表-->
    <el-drawer

    >

    </el-drawer>
  </div>
</template>

<script>
/**
 * 任务想定编辑父组件（精简版）
 * - 左侧：装备树
 * - 中间：概览 + 甘特图 + 时序计划
 * - 右侧：任务表单、抛洒点、气象、理论数据导入
 * - 导入流程：Trajectory 发出 @do-import -> 打开 ExcelImportDialog -> @confirm 拿到映射关系
 */
import axios from 'axios'
import {mapGetters} from 'vuex'
import TaskBasicInfo from './components/BasicInfo.vue'
import RunwayDropSetting from './components/RunwayDropSetting.vue'
import WeatherEnvForm from './components/WeatherEnvForm.vue'
import Trajectory from './components/Trajectory.vue'
import ExcelImportDialog from './components/ExcelImportDialog.vue'
import TargetEquipmentMap from './components/TargetEquipmentMap.vue'
import GanttChart from './components/GanttChartWithEndTime.vue'
import {getEquTree} from "@/api/faultSimulation";
import {getSubPlanZbStatistics, getSubPlanZbTsList} from "@/api/subPlanZb";
import {battlefieldEnvironmentInsert, getBattlefieldEnvironment} from "@/api/battlefieldEnvironment";
import {saveJson} from "@/api/deductionTask";

/** 默认甘特数据（示例） */
const DEFAULT_GANTT_PAYLOAD = {
  t0: '2025-09-16T03:00:00Z',
  legend_types: [
    {kind: '测量装备', color: '#5470c6'},
    {kind: '靶标装备', color: '#91cc75'},
    {kind: '干扰装备', color: '#fac858'}
  ],
  y_order: ['雷达A', '靶机B', '干扰车C'],
  devices: [
    {
      name: '雷达A', kind: '测量装备', events: [
        {start_sec: 120, duration_sec: 600, title: '上电', desc: '自检', trigger_type: '自动'},
        {start_sec: 900, duration_sec: 300, title: '工作', desc: '跟踪', trigger_type: '手动'}
      ]
    },
    {
      name: '靶机B', kind: '靶标装备', events: [
        {start_sec: 150, duration_sec: 1200, title: '起飞', desc: '', trigger_type: '计划'}
      ]
    }
  ]
}

export default {
  name: 'OrderEdit',
  components: {
    TaskBasicInfo,
    RunwayDropSetting,
    WeatherEnvForm,
    Trajectory,
    ExcelImportDialog,
    TargetEquipmentMap,
    GanttChart
  },
  data() {
    return {
      plan:JSON.parse(this.$route.query.plan),
      /** 表格数据：由父组件持有与更新 */
      timingPlanData: [],
      /** 关键事件总表：用于“新增抽屉”里多选 */
      allKeyEvents: [
        { id: 'E1', strikeDomain: '对陆', timing: 'T+30',  keyEvent: '测量系统上电' },
        { id: 'E2', strikeDomain: '对陆', timing: 'T+60',  keyEvent: '目标进入监视区' },
        { id: 'E3', strikeDomain: '对海', timing: 'T+90',  keyEvent: '干扰装备启动' },
        { id: 'E4', strikeDomain: '对海', timing: 'T+120', keyEvent: '目标锁定' },
        { id: 'E5', strikeDomain: '对陆', timing: 'T+150', keyEvent: '导弹准备' },
        { id: 'E6', strikeDomain: '对海', timing: 'T+180', keyEvent: '导弹发射' },
        { id: 'E7', strikeDomain: '对陆', timing: 'T+210', keyEvent: '数据记录开始' },
        { id: 'E8', strikeDomain: '对海', timing: 'T+240', keyEvent: '拦截评估' }
      ],
      /** 导入弹窗显隐 */
      visible: false,

      /** 气象参数（作为 WeatherEnvForm 的 v-model） */
      weather: {
        temp: 20,
        rh: 55,
        pressure: 1013,
        wind: 5.5,
        windDir: 270,
        fallSpeed: 0.8,
        airDensity: 1200,
        visibility: 5000,
        rain: 0,
        weather: 'sunny'
      },

      /** 抛洒点配置（RunwayDropSetting 的 v-model） */
      runwayDrop: {
        runwayHead: {lon: 116.397, lat: 39.907, alt: 35},
        groups: [
          {hOffset: 120, vOffset: -50},
          {hOffset: 0, vOffset: 0},
          {hOffset: -60, vOffset: 80}
        ]
      },

      /** 甘特相关输入与状态 */
      taskId: '',
      loadingGantt: false,
      ganttError: '',
      ganttTimelineData: [],
      ganttTypeColorMap: {'测量装备': '#5470c6', '靶标装备': '#91cc75', '干扰装备': '#fac858'},
      t0Ms: null,

      /** 示例时序计划（传入 TargetEquipmentMap） */


      /** 任务基本信息（传入 TaskBasicInfo） */
      taskForm: {
        ts:"2025-10-15 14:30:00",
        name: '红旗-9B防空导弹拦截试验',
        category: 'combat',
        type: 'air-defense',
        missileType: 'surface-to-air',
        missileCount: 6,
        executeTime: '2025-10-15 14:30:00',
        description: '验证在强电子干扰环境下的作战效能。',
        targets: [
          {
            id: 1,
            name: '模拟指挥所靶标',
            type: '空中靶标',
            coordinates: '东经121°25′，北纬30°15′',
            threatLevel: 5,
            equipmentId: 'A1'
          },
          {
            id: 2,
            name: '模拟雷达站靶标',
            type: '空中靶标',
            coordinates: '东经121°30′，北纬30°20′',
            threatLevel: 4,
            equipmentId: 'A1'
          },
          {
            id: 3,
            name: '模拟机场跑道靶标',
            type: '空中靶标',
            coordinates: '东经121°20′，北纬30°25′',
            threatLevel: 5,
            equipmentId: 'B2'
          }
        ]
      },

      /** 装备树（左侧） */
      equipmentTree: [
        {
          id: 'category1',
          label: '测量装备',
          children: [
            {
              id: 'A1',
              label: '高空观测装置A1',
              indicatorClass: 'bg-blue-500',
              status: 'ready',
              position: 'front',
              notes: '',
              details: []
            },
            {
              id: 'B2',
              label: '地面观测装置B2',
              indicatorClass: 'bg-blue-500',
              status: 'ready',
              position: 'center',
              notes: '',
              details: []
            },
            {
              id: 'C3',
              label: '移动观测装置C3',
              indicatorClass: 'bg-blue-500',
              status: 'standby',
              position: 'rear',
              notes: '',
              details: []
            }
          ]
        },
        {
          id: 'category2',
          label: '干扰装备',
          children: [
            {
              id: 'D1',
              label: '雷达干扰器D1',
              indicatorClass: 'bg-purple-500',
              status: 'standby',
              position: 'left',
              notes: '',
              details: []
            },
            {
              id: 'E2',
              label: '光电干扰器E2',
              indicatorClass: 'bg-purple-500',
              status: 'ready',
              position: 'right',
              notes: '',
              details: []
            }
          ]
        },
        {
          id: 'category3',
          label: '靶标装备',
          children: [
            {
              id: 'redA',
              label: '空中靶标A集群',
              indicatorClass: 'bg-red-500',
              status: 'ready',
              position: 'front',
              notes: '',
              details: []
            },
            {
              id: 'redB',
              label: '海上靶标B',
              indicatorClass: 'bg-red-500',
              status: 'standby',
              position: 'front',
              notes: '',
              details: []
            }
          ]
        }
      ],
      defaultProps: {children: 'equList', label: 'name'},
      // 统计数据
      stastic:{},

      /** 装备参数对话框 */
      selectedEquipment: null,
      showEquipmentDialog: false,
      equipmentEditForm: {id: '', label: '', status: '', position: '', notes: ''},

      /** WebSocket 相关引用（保存/释放监听用） */
      wsOff: null,
      offMsg: null
    }
  },
  computed: {
    ...mapGetters('tTime', ['currentT0HMS', 'isRealtime']),
    // 时序图格式化数据
    currentPreviewEvents() {
      const list = [];
      this.timingPlanData.forEach(t => {
        if (!t.ts) return;
        list.push({
          id:t.id,
          time: `T0+${this.formatSeconds(t.ts.split('-')[0])}`,
          endTime: `T0+${this.formatSeconds(t.ts.split('-')[1])}`,
          name: t.zbName,
          rawTime: this.formatSeconds(t.seconds),
          title: t.seconds === '0' ? '初始化' : t.behavior,
          desc: `${t.zbName}`,
          zbType: this.$getDictNameByValue('zb_type', t.zbType),
        });
      });

      return list.sort((a, b) => this.hhmmssToSec(a.rawTime) - this.hhmmssToSec(b.rawTime));
    },
    /** T0 可读显示 */
    t0Display() {
      if (!this.t0Ms) return ''
      const d = new Date(this.t0Ms)
      const p = n => String(n).padStart(2, '0')
      return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`
    }
  },
  watch: {
    /** 导弹类型变更时，按业务规则筛选靶标 */
    'taskForm.missileType': function () {
      this.updateTargetsByMissileType()
    }
  },
  mounted() {
    this.fetchEqTree()
    this.fetchEquCount()
    this.fetchTsList()
    this.getEnvDate()
    // 默认加载一份甘特示例数据，避免空白
    this.useDefaultGantt()
  },
  methods: {
    formatSeconds(seconds) {
      // 确保输入是有效的数字，并取整数部分
      const totalSeconds = Math.max(0, Math.floor(seconds)); // 处理负数或无效输入

      // 计算小时、分钟和秒
      const hours = Math.floor(totalSeconds / 3600);
      const minutes = Math.floor((totalSeconds % 3600) / 60);
      const secs = totalSeconds % 60;

      // 使用 padStart 确保分钟和秒始终显示为两位数 (e.g., 05, 09, 12)
      const paddedMinutes = String(minutes).padStart(2, '0');
      const paddedSeconds = String(secs).padStart(2, '0');

      // 返回格式: "Hhmmss" 或 "HH:mm:ss"
      // 这里采用更标准的 HH:mm:ss 格式
      return `${hours}:${paddedMinutes}:${paddedSeconds}`;
    },
    hhmmssToSec(hms) {
      const [h = 0, m = 0, s = 0] = (hms || '00:00:00').split(':').map(n => parseInt(n, 10) || 0);
      return h * 3600 + m * 60 + s;
    },
    getEnvDate(){
      // 获取环境信息
      getBattlefieldEnvironment({simulationId:this.plan.id}).then((res)=>{
        if(res.data?.environmentJson){
          this.weather = JSON.parse(res.data?.environmentJson)
        }else {

        }
      })
    },
    fetchEqTree(){
      getEquTree({subTaskId:this.plan.subTaskId}).then((res)=>{
        this.equipmentTree = res.data
      })
    },
    fetchEquCount(){
      getSubPlanZbStatistics({schemeId:this.plan.schemeId}).then((res)=>{
        this.stastic = res.data;
      })
    },
    fetchTsList() {
      getSubPlanZbTsList({simulationId: this.plan.id}).then((res) => {
        this.timingPlanData = res.data
      })
    },
    /** 检索条件变更（如果要联动后端，在这里调接口；不需要就当日志看） */
    onSeqSearch({ strikeDomain, keyEvent }) {
      // 这里通常发请求：/api/xxx?domain=strikeDomain&kw=keyEvent
      // 本地表格筛选已在子组件里做了
      // console.log('检索条件:', strikeDomain, keyEvent)
    },

    /** 编辑保存 */
    onSeqUpdate() {
      this.fetchTsList();
    },

    /** 删除 */
    onSeqDelete(row) {
      // row：原表格行
      this.$confirm(`确定删除「${row.keyEvent}」吗？`, '提示', { type: 'warning' })
        .then(() => {
          this.timingPlanData = this.timingPlanData.filter(r => r.id !== row.id)
          this.$message.success('已删除')
        })
        .catch(() => {})
    },

    /** 去重（按 id 优先，其次按 领域+时序+事件 文本去重） */
    deDupRows(rows) {
      const seen = new Set()
      const out = []
      for (const r of rows) {
        const key = r.id || `${r.strikeDomain}|${r.timing}|${r.keyEvent}`
        if (seen.has(key)) continue
        seen.add(key)
        out.push(r)
      }
      return out
    },
    /** 打开导入弹窗（由 Trajectory 触发） */
    doImport() {
      this.visible = true
    },

    /** 单个文件上传成功（可选） */
    onSingleSuccess({file, upload}) {
      // 可在此处理单个文件返回
    },

    /** 单个文件上传失败（可选） */
    onSingleError({file}) {
      // 可在此处理失败场景
    },

    /** 点击“确定”时拿到全部映射：[{ fileName, targetCode, upload }] */
    onBindTargets(mappings) {
      // 将 upload 与 targetCode 绑定提交给后端
      // 例如：api.bindTheory(mappings.map(m => ({ code: m.targetCode, fileId: m.upload.data.id })))
      this.$message.success(`已提交 ${mappings.length} 个文件的靶标编号关联`)
    },

    /** 载入默认甘特数据 */
    useDefaultGantt() {
      this.consumeGanttPayload(DEFAULT_GANTT_PAYLOAD)
    },

    /** 从接口拉取甘特数据（返回结构参考 DEFAULT_GANTT_PAYLOAD） */
    async fetchGanttFromApi() {
      this.loadingGantt = true
      this.ganttError = ''
      try {
        const {data} = await axios.get('/api/gantt', {params: this.taskId ? {taskId: this.taskId} : {}})
        this.consumeGanttPayload(data)
      } catch (e) {
        this.ganttError = (e && e.message) || '甘特数据请求失败'
        this.ganttTimelineData = []
      } finally {
        this.loadingGantt = false
      }
    },

    /** 归一化 payload -> timelineData + 颜色映射 */
    consumeGanttPayload(payload) {
      if (!payload) {
        this.ganttTimelineData = [];
        return
      }
      // 1) 解析 T0（ISO / epoch 秒 / 毫秒）
      this.t0Ms = this.parseT0(payload.t0)

      // 2) 覆盖颜色映射（legend_types 优先）
      if (Array.isArray(payload.legend_types)) {
        const next = {...this.ganttTypeColorMap}
        payload.legend_types.forEach(it => {
          if (it && it.kind) next[it.kind] = it.color || next[it.kind] || '#bbb'
        })
        this.ganttTypeColorMap = next
      }

      // 3) 扁平化事件
      const yOrder = Array.isArray(payload.y_order) ? payload.y_order.slice() : null
      const flat = this.flattenEvents(payload, yOrder)

      // 4) 扁平 -> timelineData
      this.ganttTimelineData = flat.map(ev => {
        const startSec = this.resolveStartSec(ev)
        const duration = Number.isFinite(ev.duration_sec) ? ev.duration_sec : 120
        return {
          name: ev.name,
          rawTime: this.secToT0HMS(startSec),
          duration,
          title: ev.title || '无标题',
          desc: ev.desc || '',
          kindText: ev.kind || '未知类型',
          triggerTypeText: ev.trigger_type || ''
        }
      })
    },

    /** 扁平化 devices/events 两种结构 */
    flattenEvents(payload, yOrder) {
      const orderIdx = name => {
        if (!yOrder) return Number.MAX_SAFE_INTEGER
        const i = yOrder.indexOf(name)
        return i === -1 ? Number.MAX_SAFE_INTEGER : i
      }

      if (Array.isArray(payload.devices)) {
        const sorted = payload.devices.slice().sort((a, b) => {
          const ia = orderIdx(a.name), ib = orderIdx(b.name)
          if (ia !== ib) return ia - ib
          return String(a.name).localeCompare(String(b.name), 'zh')
        })
        const res = []
        sorted.forEach(dev => {
          (dev.events || []).forEach(ev => {
            res.push({
              name: dev.name,
              kind: dev.kind,
              start_sec: ev.start_sec,
              start_at: ev.start_at,
              duration_sec: ev.duration_sec,
              title: ev.title,
              desc: ev.desc,
              trigger_type: ev.trigger_type
            })
          })
        })
        return res
      }

      if (Array.isArray(payload.events)) {
        return payload.events.slice().sort((a, b) => {
          const ia = orderIdx(a.name), ib = orderIdx(b.name)
          if (ia !== ib) return ia - ib
          return this.resolveStartSec(a) - this.resolveStartSec(b)
        })
      }

      return []
    },

    /** start_sec / start_at -> 相对 T0 的秒 */
    resolveStartSec(ev) {
      if (Number.isFinite(ev.start_sec)) return ev.start_sec
      if (ev.start_at != null) {
        const abs = this.toEpochMs(ev.start_at)
        if (this.t0Ms != null && Number.isFinite(abs)) {
          return Math.max(0, Math.floor((abs - this.t0Ms) / 1000))
        }
      }
      return 0
    },

    /** 时间解析工具 */
    parseT0(t0) {
      if (t0 == null) return null
      if (typeof t0 === 'string') {
        const ms = Date.parse(t0)
        return Number.isFinite(ms) ? ms : null
      }
      if (typeof t0 === 'number') {
        return t0 < 2e10 ? t0 * 1000 : t0
      }
      return null
    },
    toEpochMs(x) {
      if (x == null) return NaN
      if (typeof x === 'number') return x < 2e10 ? x * 1000 : x
      const ms = Date.parse(x)
      return Number.isFinite(ms) ? ms : NaN
    },
    secToT0HMS(sec) {
      const s = Math.max(0, Math.floor(sec || 0))
      const h = String(Math.floor(s / 3600)).padStart(2, '0')
      const m = String(Math.floor((s % 3600) / 60)).padStart(2, '0')
      const ss = String(s % 60).padStart(2, '0')
      return `T0+${h}:${m}:${ss}`
    },

    /** 装备树点击 -> 打开编辑弹窗 */
    handleEquipmentClick(data, node) {
      if (node.level === 2 || (node.level > 2 && (!data.children || !data.children.length))) {
        this.selectedEquipment = {...data}
        this.openEquipmentDialog(data)
      }
    },
    openEquipmentDialog(equipment) {
      this.equipmentEditForm = {
        id: equipment.id || '',
        label: equipment.label || '',
        status: equipment.status || 'standby',
        position: equipment.position || 'center',
        notes: equipment.notes || ''
      }
      this.showEquipmentDialog = true
    },
    confirmEquipmentEdit() {
      const {id, status, position, notes} = this.equipmentEditForm
      const updateNode = (nodes) => {
        for (let i = 0; i < nodes.length; i++) {
          if (nodes[i].id === id) {
            nodes[i] = {...nodes[i], status, position, notes};
            return true
          }
          if (nodes[i].children && nodes[i].children.length) {
            if (updateNode(nodes[i].children)) return true
          }
        }
        return false
      }
      updateNode(this.equipmentTree)
      if (this.selectedEquipment && this.selectedEquipment.id === id) {
        this.selectedEquipment = {...this.selectedEquipment, status, position, notes}
      }
      this.$message.success('参试参数已保存')
      this.showEquipmentDialog = false
    },

    /** 任务保存（示例：初始化 T0、连接 WS） */
    async saveTask() {
      if (this.taskForm.targets.length === 0) {
        this.$message.error('靶标设置不能为空');
        return
      }
      try {
        // 保存环境配置
        await battlefieldEnvironmentInsert({simulationId:this.plan.id,environmentJson:JSON.stringify(this.weatherForm)})
        await saveJson({id:this.plan.id});
        this.$message.success('任务保存成功')
      } catch (e) {

      }
      // this.$store.dispatch('tTime/initFixedT0', 0)
      // this.$ws.connect('telemetry', 'ws://127.0.0.1:9000/telemetry')
      // if (this.wsOff) this.wsOff()
      // this.offMsg = this.$ws.onMessage('telemetry', () => {
      // })
      // if (this.wsOff) this.wsOff()
      // this.wsOff = this.$ws.onMessage('telemetry', (msg) => {
      //   this.$store.dispatch('tTime/ingestFromWs', JSON.parse(msg))
      // })

    },

    /** 返回、重置 */
    goBack() {
      this.$confirm('确定要退出吗？', '提示', {confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning'})
        .then(() => {
          this.$router.go(-1)
        }).catch(() => {
      })
    },
    resetTask() {
      this.$confirm('确定要重置任务配置吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          this.$message.success('任务配置已重置')
        }).catch(() => {
      })
    },

    /** 任务基本信息里变更导弹类型/数量时，按规则调整靶标 */
    updateTargetsByMissileType() {
      if (!this.taskForm.missileType) return
      const compatible = []
      if (['surface-to-air', 'air-to-surface', 'cruise'].includes(this.taskForm.missileType)) compatible.push('空中靶标')
      if (['anti-ship', 'cruise'].includes(this.taskForm.missileType)) compatible.push('海上靶标')
      if (['air-to-surface', 'cruise'].includes(this.taskForm.missileType)) compatible.push('地面靶标')
      this.taskForm.targets = this.taskForm.targets.filter(t => compatible.includes(t.type))
      if (this.taskForm.targets.length === 0) {
        this.taskForm.targets.push({
          id: Date.now(), name: `靶标${compatible[0]}`, type: compatible[0],
          coordinates: '东经120°00′，北纬30°00′', threatLevel: 3, equipmentId: ''
        })
      }
    },
    updateTargetsByMissileCount() {
      const maxTargets = this.taskForm.missileCount * 2
      if (this.taskForm.targets.length > maxTargets) {
        this.taskForm.targets = this.taskForm.targets.slice(0, maxTargets)
        this.$message.info(`靶标数量已调整为${maxTargets}个（不超过导弹数量的2倍）`)
      }
    }
  }
}
</script>

<style lang="scss" scoped>
/* 布局与配色（军事风格） */
.task-setting-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background-color: #050c1a;
  color: #e0f2fe;
  font-family: "Microsoft YaHei", Arial, sans-serif;
  position: relative;
  overflow: hidden;
}

/* 背景网格 */
.grid-bg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-size: 40px 40px;
  background-image: linear-gradient(to right, rgba(14, 55, 107, 0.1) 1px, transparent 1px),
  linear-gradient(to bottom, rgba(14, 55, 107, 0.1) 1px, transparent 1px);
  pointer-events: none;
  z-index: 0;
}

/* 头部 */
.header {
  flex: 0 0 60px;
  background-color: #0f172a;
  background-image: linear-gradient(to right, #0f172a, #1e3a8a);
  display: flex;
  align-items: center;
  padding: 0 20px;
  justify-content: space-between;
  border-bottom: 1px solid #0ea5e9;
  box-shadow: 0 2px 10px rgba(14, 165, 233, 0.2);
  position: relative;
  z-index: 10;

  .header-logo {
    display: flex;
    align-items: center;

    h1 {
      font-size: 1.5rem;
      color: #bae6fd;
      margin: 0;
      white-space: nowrap;
      text-shadow: 0 0 5px rgba(14, 165, 233, 0.5);
    }
  }

  .header-controls {
    display: flex;
    gap: 15px;
  }
}

/* 按钮特效 */
.btn军事 {
  position: relative;
  overflow: hidden;
  transition: all .3s ease;
  border: 1px solid rgba(14, 165, 233, .5) !important;
  box-shadow: 0 0 5px rgba(14, 165, 233, .3);

  &:after {
    content: '';
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .1), transparent);
    transition: all .5s ease;
  }

  &:hover:after {
    left: 100%;
  }
}

/* 装饰线 */
.aside-border-decoration, .main-border-decoration {
  position: absolute;
  top: 0;
  width: 3px;
  height: 100%;
  background: linear-gradient(to bottom, rgba(14, 165, 233, 0) 0%, rgba(14, 165, 233, .5) 50%, rgba(14, 165, 233, 0) 100%);
  z-index: 1;
}

.aside-border-decoration {
  right: 0;
}

.main-border-decoration {
  left: 0;
}

/* 右侧任务面板滚动 */
.task-panel {
  width: 100%;
  background-color: rgba(15, 23, 42, 0.8);
  backdrop-filter: blur(5px);
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
  border-right: 1px solid rgba(14, 165, 233, 0.2);

  .task-content {
    flex: 1;
    overflow-y: auto;
    padding: 15px;
    min-height: 0;

    &::-webkit-scrollbar {
      width: 6px;
      height: 6px;
    }

    &::-webkit-scrollbar-track {
      background: rgba(15, 23, 42, 0.5);
    }

    &::-webkit-scrollbar-thumb {
      background-color: rgba(59, 130, 246, 0.5);
      border-radius: 3px;
    }
  }
}

/* 中间分区 */
.equipment-content-box {
  background-color: rgba(5, 12, 26, 0.9);
  min-height: 0;
  overflow-y: auto;
}

.middle-layout {
  height: 100%;
  grid-template-rows:20% 40% 40%;
}

.overview-card, .gantt-card, .timeline-wrapper {
  min-height: 0;
}

/* 甘特容器 */
.gantt-body {
  //height: 300px;
  padding: 8px 12px 12px 12px;
}

/* 统计卡片 */
.equipment-status-grid {
  display: grid;
  grid-template-columns:repeat(4, 1fr);
  gap: 10px;
}

.status-card {
  background-color: rgba(15, 23, 42, 0.6);
  border-radius: 3px;
  transition: all .2s;

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 3px 10px rgba(14, 165, 233, 0.1);
  }

  .status-title {
    color: #94a3b8;
  }

  .status-value {
    color: #60a5fa;
    text-shadow: 0 0 3px rgba(59, 130, 246, 0.2);
  }
}

/* 树形滚动条 */
.equipment-tree {
  max-height: calc(100% - 20px);
  overflow-y: auto;

  &::-webkit-scrollbar {
    width: 6px;
    height: 6px;
  }

  &::-webkit-scrollbar-track {
    background: rgba(15, 23, 42, 0.5);
  }

  &::-webkit-scrollbar-thumb {
    background-color: rgba(59, 130, 246, 0.5);
    border-radius: 3px;
  }
}

::v-deep .el-tree-node[aria-level="2"] .el-tree-node__expand-icon {
  display: none !important;
}

::v-deep .el-tree-node__expand-icon.is-leaf {
  display: none !important;
}

/* 模块头 */
.section-header {
  background-color: rgba(30, 58, 138, 0.5);
  padding: 8px 15px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid rgba(14, 165, 233, 0.2);

  .section-title {
    color: #bae6fd;
    font-size: 14px;
    margin: 0;
    font-weight: 500;
    display: flex;
    align-items: center;
  }
}

/* 表单控件 */
.el-input__inner, .el-textarea__inner, .el-select .el-input__inner {
  background-color: rgba(15, 23, 42, 0.8);
  border: 1px solid rgba(14, 165, 233, 0.3);
  color: #e0f2fe;
  width: 100%;
  border-radius: 3px;
  height: 32px;
  font-size: 14px;

  &:focus {
    border-color: #3b82f6;
    box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
  }

  &::placeholder {
    color: #64748b;
  }

  &:disabled {
    background-color: rgba(15, 23, 42, 0.5);
    color: #94a3b8;
    cursor: not-allowed;
  }
}

.el-textarea__inner {
  min-height: 80px !important;
  height: auto;
  resize: vertical;
}

::v-deep .el-select-dropdown {
  background-color: rgba(15, 23, 42, 0.95);
  border: 1px solid rgba(14, 165, 233, 0.3);
  border-radius: 3px;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}

::v-deep .el-table {
  background-color: transparent;
  color: #e0f2fe;

  .el-table__empty-text {
    color: #94a3b8;
  }

  .el-table__row:hover > td {
    background-color: rgba(30, 58, 138, 0.2);
  }
}

/* 弹窗皮肤 */
::v-deep .equipment-dialog {
  .el-dialog {
    background-color: rgba(15, 23, 42, 0.95);
    border: 1px solid rgba(14, 165, 233, 0.3);
    border-radius: 4px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, .5);
  }

  .el-dialog__header {
    background-color: rgba(30, 58, 138, 0.6);
    border-bottom: 1px solid rgba(14, 165, 233, 0.3);

    .el-dialog__title {
      color: #bae6fd;
    }
  }

  .el-dialog__body, .el-dialog__footer {
    background-color: rgba(15, 23, 42, 0.95);
    color: #e0f2fe;
  }
}

/* 按钮配色 */
::v-deep .el-button {
  border-radius: 3px;
  border: none;

  &.el-button--primary {
    background-color: #1e40af;
    color: #fff;

    &:hover {
      background-color: #3b82f6;
    }
  }

  &.el-button--success {
    background-color: #065f46;
    color: #fff;

    &:hover {
      background-color: #16a34a;
    }
  }

  &.el-button--warning {
    background-color: #92400e;
    color: #fff;

    &:hover {
      background-color: #d97706;
    }
  }

  &.el-button--text {
    color: #94a3b8;

    &:hover {
      color: #bae6fd;
      background-color: rgba(148, 163, 184, 0.1);
    }
  }
}

/* 其他 */
::v-deep .el-slider .el-slider__runway {
  background-color: rgba(51, 65, 85, 0.5);
}

::v-deep .el-slider .el-slider__bar {
  background-color: #3b82f6;
}

::v-deep .el-slider .el-slider__button {
  border-color: #3b82f6;
}

::v-deep .el-message {
  background-color: rgba(30, 58, 138, 0.8);
  border-color: rgba(14, 165, 233, 0.3);
  color: #e0f2fe;
}

::v-deep .el-container {
  background: transparent;
}

/* 响应式 */
@media (max-width: 1600px) {
  .middle-layout {
    grid-template-rows: 34% 26% 40%;
  }
}

@media (max-width: 1200px) {
  .equipment-status-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  .middle-layout {
    grid-template-rows: 38% 26% 36%;
  }
}

::v-deep .el-tree {
  background: transparent;
}

.meta {
  font-size: 12px;
  color: #9aa0a6;
}
</style>
