<template>
  <div class="plan-spec-page" v-loading="pageLoading">
    <!-- 头部 -->
    <div class="page-header">
      <el-button type="text" icon="el-icon-arrow-left" @click="goBack">返回</el-button>
      <span class="page-title">方案详情</span>
      <span v-if="versionCode" class="version-badge">版本 {{ versionCode }}</span>
    </div>

    <!-- 可配置 / 不可配置 切换 -->
    <div class="config-tabs">
      <span
        :class="['config-tab', { active: configMode === 'configurable' }]"
        @click="configMode = 'configurable'"
      >可配置</span>
      <span
        :class="['config-tab', { active: configMode === 'readonly' }]"
        @click="configMode = 'readonly'"
      >不可配置</span>
    </div>

    <div class="main-layout">
      <!-- 左侧段分组 -->
      <div class="left-tree">
        <div
          :class="['tree-item', { active: activeSegmentType === '' }]"
          @click="selectSegmentType('')"
        >全部</div>
        <div
          v-for="seg in segmentTypeTabOptions"
          :key="String(seg.value)"
          :class="['tree-item', { active: String(activeSegmentType) === String(seg.value) }]"
          @click="selectSegmentType(seg.value)"
        >
          <span class="tree-arrow">›</span> {{ seg.label }}
        </div>
      </div>

      <!-- 右侧内容 -->
      <div class="right-content">
        <!-- 搜索栏 -->
        <div class="search-bar">
          <template v-if="activeSegmentType !== '' && activeSegmentType !== undefined && activeSegmentType !== null">
            <span class="search-label">段名称：</span>
            <el-select
              v-model="activeSegmentName"
              placeholder="请选择"
              size="small"
              clearable
              style="width:180px"
              @change="onSegmentNameFilterChange"
            >
              <el-option
                v-for="opt in segmentNameFilterOptions"
                :key="String(opt.value) + '-' + opt.label"
                :label="opt.label"
                :value="opt.value"
              />
            </el-select>
          </template>
          <span class="search-label">点位名称：</span>
          <el-input
            v-model="filterName"
            placeholder="请输入"
            size="small"
            style="width:200px"
            clearable
            @keyup.enter.native="applyFilter"
          />
          <el-button size="mini" type="primary" @click="applyFilter">查询</el-button>
          <el-button size="mini" @click="resetFilter">重置</el-button>
          <el-button
            size="mini"
            type="primary"
            icon="el-icon-plus"
            style="margin-left:auto"
            @click="openPlanDialog()"
          >新建方案点位</el-button>
        </div>

        <!-- 方案点位表 -->
        <el-table
          v-loading="planLoading"
          :data="filteredPlans"
          size="small"
          highlight-current-row
          @current-change="onPlanSelect"
        >
          <el-table-column label="序号" type="index" align="center" />
          <el-table-column label="父级名称" show-overflow-tooltip>
            <template slot-scope="{ row }">{{ segLabel(row.segmentType) }} › {{ row.segmentName || '—' }}</template>
          </el-table-column>
          <el-table-column label="点位名称" prop="pointName" show-overflow-tooltip />
          <el-table-column label="实际值ID" prop="actualValueId" show-overflow-tooltip />
          <el-table-column label="L1设定值ID" prop="l1SetValueId" show-overflow-tooltip />
          <el-table-column label="设定值" prop="targetValue" align="center" />
          <el-table-column label="下限" prop="lowerLimit" align="center" />
          <el-table-column label="上限" prop="upperLimit" align="center" />
          <el-table-column label="操作" align="right">
            <template slot-scope="{ row }">
              <el-button type="text" size="mini" @click.stop="openPlanDialog(row)">编辑</el-button>
              <el-button type="text" size="mini" @click.stop="openParamDialog(row)">参数</el-button>
              <el-button type="text" size="mini" class="btn-danger" @click.stop="removePlan(row)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>

        <!-- 方案参数面板 -->
        <template v-if="selectedPlan">
          <div class="param-header">
            <span>{{ selectedPlan.pointName || selectedPlan.pointCode }} — 参数</span>
            <el-button size="mini" type="primary" icon="el-icon-plus" @click="openParamDialog()">新建参数</el-button>
          </div>
          <el-table v-loading="paramLoading" :data="paramList" size="small">
            <el-table-column label="参数编码" prop="paramCode" show-overflow-tooltip />
            <el-table-column label="参数名称" prop="paramName" show-overflow-tooltip />
            <el-table-column label="设定值" prop="targetValue" align="center" />
            <el-table-column label="下限" prop="lowerLimit" align="center" />
            <el-table-column label="上限" prop="upperLimit" align="center" />
            <el-table-column label="单位" prop="unit" align="center" />
            <el-table-column label="操作" align="right">
              <template slot-scope="{ row }">
                <el-button type="text" size="mini" @click="openParamDialog(null, row)">编辑</el-button>
                <el-button type="text" size="mini" class="btn-danger" @click="removeParam(row)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </template>
      </div>
    </div>

    <!-- 方案点位 dialog -->
    <el-dialog :title="planTitle" :visible.sync="planOpen" width="520px" append-to-body @close="planForm = {}">
      <el-form ref="planFormRef" :model="planForm" :rules="planRules" label-width="90px" size="small">
        <el-form-item label="段类型" prop="segmentType">
          <el-select v-model="planForm.segmentType" style="width:100%">
            <el-option v-for="s in segmentFormOptionsForDialog" :key="String(s.value)" :label="s.label" :value="s.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="段名称" prop="segmentName">
          <el-input v-model="planForm.segmentName" maxlength="100" />
        </el-form-item>
        <el-form-item label="点位名称" prop="pointName">
          <el-input v-model="planForm.pointName" maxlength="200" />
        </el-form-item>
        <el-form-item label="点位编码" prop="pointCode">
          <el-input v-model="planForm.pointCode" maxlength="64" />
        </el-form-item>
        <el-form-item label="实际值ID" prop="actualValueId">
          <el-input v-model="planForm.actualValueId" maxlength="64" />
        </el-form-item>
        <el-form-item label="L1设定值ID" prop="l1SetValueId">
          <el-input v-model="planForm.l1SetValueId" maxlength="64" />
        </el-form-item>
        <el-form-item label="设定值" prop="targetValue">
          <el-input v-model="planForm.targetValue" />
        </el-form-item>
        <el-form-item label="下限" prop="lowerLimit">
          <el-input v-model="planForm.lowerLimit" />
        </el-form-item>
        <el-form-item label="上限" prop="upperLimit">
          <el-input v-model="planForm.upperLimit" />
        </el-form-item>
        <el-form-item label="排序">
          <el-input-number v-model="planForm.sortOrder" :min="0" controls-position="right" style="width:100%" />
        </el-form-item>
        <el-form-item label="备注">
          <el-input v-model="planForm.remark" type="textarea" rows="2" maxlength="500" />
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button size="small" @click="planOpen = false">取消</el-button>
        <el-button size="small" type="primary" :loading="planSubmitLoading" @click="submitPlan">确定</el-button>
      </div>
    </el-dialog>

    <!-- 方案参数 dialog -->
    <el-dialog :title="paramTitle" :visible.sync="paramOpen" width="480px" append-to-body @close="paramForm = {}">
      <el-form ref="paramFormRef" :model="paramForm" :rules="paramRules" label-width="90px" size="small">
        <el-form-item label="参数编码" prop="paramCode">
          <el-input v-model="paramForm.paramCode" maxlength="64" />
        </el-form-item>
        <el-form-item label="参数名称" prop="paramName">
          <el-input v-model="paramForm.paramName" maxlength="200" />
        </el-form-item>
        <el-form-item label="设定值">
          <el-input v-model="paramForm.targetValue" />
        </el-form-item>
        <el-form-item label="下限">
          <el-input v-model="paramForm.lowerLimit" />
        </el-form-item>
        <el-form-item label="上限">
          <el-input v-model="paramForm.upperLimit" />
        </el-form-item>
        <el-form-item label="单位">
          <el-input v-model="paramForm.unit" maxlength="32" />
        </el-form-item>
        <el-form-item label="备注">
          <el-input v-model="paramForm.remark" type="textarea" rows="2" maxlength="500" />
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button size="small" @click="paramOpen = false">取消</el-button>
        <el-button size="small" type="primary" :loading="paramSubmitLoading" @click="submitParam">确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { listProcessPlan, addProcessPlan, updateProcessPlan, delProcessPlan } from '@/api/wms/processPlan'
import { listProcessPlanParam, addProcessPlanParam, updateProcessPlanParam, delProcessPlanParam } from '@/api/wms/processPlanParam'

/** 表单内可选段类型（新建/编辑仍支持全部枚举） */
const SEGMENT_FORM_OPTIONS = [
  { label: '入口段', value: 'INLET' },
  { label: '工艺段', value: 'PROCESS' },
  { label: '出口段', value: 'OUTLET' }
]

export default {
  name: 'ProcessSpecPlanSpec',
  data() {
    return {
      pageLoading: false,
      versionId: undefined,
      versionCode: '',
      specId: undefined,
      configMode: 'configurable',
      /** 左侧：段类型；空=全部 */
      activeSegmentType: '',
      /** 工具栏下拉：当前段类型下的段名称；空字符串=该段类型下全部名称；__EMPTY__=未命名 */
      activeSegmentName: '',
      filterName: '',
      appliedFilterName: '',
      planList: [],
      planLoading: false,
      selectedPlan: null,
      paramList: [],
      paramLoading: false,
      planOpen: false,
      planTitle: '',
      planSubmitLoading: false,
      planForm: {},
      planRules: {
        segmentType: [{ required: true, message: '请选择段类型', trigger: 'change' }],
        pointName: [{ required: true, message: '点位名称不能为空', trigger: 'blur' }],
        pointCode: [{ required: true, message: '点位编码不能为空', trigger: 'blur' }]
      },
      paramOpen: false,
      paramTitle: '',
      paramSubmitLoading: false,
      paramForm: {},
      paramRules: {
        paramCode: [{ required: true, message: '参数编码不能为空', trigger: 'blur' }],
        paramName: [{ required: true, message: '参数名称不能为空', trigger: 'blur' }]
      }
    }
  },
  computed: {
    /**
     * 左侧 Tab：仅从点位数据汇总「段类型」，展示用语义名称（入口段/工艺段/出口段）
     */
    segmentTypeTabOptions() {
      const orderIdx = {}
      SEGMENT_FORM_OPTIONS.forEach((s, i) => { orderIdx[String(s.value)] = i })
      const seen = new Set()
      const list = []
      for (const plan of this.planList) {
        const t = plan.segmentType
        if (t === undefined || t === null || String(t).trim() === '') continue
        const key = String(t)
        if (seen.has(key)) continue
        seen.add(key)
        list.push({
          value: plan.segmentType,
          label: this.segmentTypeDisplayLabel(t)
        })
      }
      list.sort((a, b) => {
        const ia = orderIdx[String(a.value)]
        const ib = orderIdx[String(b.value)]
        const aKnown = ia !== undefined
        const bKnown = ib !== undefined
        if (aKnown && bKnown) return ia - ib
        if (aKnown) return -1
        if (bKnown) return 1
        return String(a.label).localeCompare(String(b.label), 'zh-CN')
      })
      return list
    },
    /** 当前选中段类型下，出现于数据中的段名称下拉项 */
    segmentNameFilterOptions() {
      const t = this.activeSegmentType
      if (t === '' || t === undefined || t === null) return [{ value: '', label: '全部' }]
      const names = new Set()
      let hasEmpty = false
      for (const p of this.planList) {
        if (String(p.segmentType) !== String(t)) continue
        const sn = p.segmentName != null ? String(p.segmentName).trim() : ''
        if (!sn) hasEmpty = true
        else names.add(sn)
      }
      const sorted = [...names].sort((a, b) => a.localeCompare(b, 'zh-CN'))
      const opts = [{ value: '', label: '全部' }]
      if (hasEmpty) opts.push({ value: '__EMPTY__', label: '（未命名）' })
      sorted.forEach(n => opts.push({ value: n, label: n }))
      return opts
    },
    /** 新建/编辑下拉：标准三项 + 当前方案中已出现的其它段类型 */
    segmentFormOptionsForDialog() {
      const seen = new Set(SEGMENT_FORM_OPTIONS.map(s => String(s.value)))
      const extra = []
      for (const plan of this.planList) {
        const v = plan.segmentType
        if (v === undefined || v === null || String(v).trim() === '') continue
        const key = String(v)
        if (seen.has(key)) continue
        seen.add(key)
        const name = plan.segmentName != null ? String(plan.segmentName).trim() : ''
        extra.push({
          value: plan.segmentType,
          label: name || this.segmentTypeDisplayLabel(v)
        })
      }
      extra.sort((a, b) => String(a.label).localeCompare(String(b.label), 'zh-CN'))
      return [...SEGMENT_FORM_OPTIONS, ...extra]
    },
    filteredPlans() {
      const type = this.activeSegmentType
      const sub = this.activeSegmentName
      return this.planList.filter(p => {
        const typeOk =
          type === '' || type === undefined || type === null
            ? true
            : String(p.segmentType) === String(type)
        let nameOkSeg = true
        if (typeOk && type !== '' && type !== undefined && type !== null) {
          if (sub === '' || sub === undefined || sub === null) {
            nameOkSeg = true
          } else if (sub === '__EMPTY__') {
            const sn = p.segmentName != null ? String(p.segmentName).trim() : ''
            nameOkSeg = !sn
          } else {
            const sn = p.segmentName != null ? String(p.segmentName).trim() : ''
            nameOkSeg = sn === String(sub).trim()
          }
        }
        const nameOk = !this.appliedFilterName || (p.pointName || '').includes(this.appliedFilterName)
        return typeOk && nameOkSeg && nameOk
      })
    }
  },
  watch: {
    $route: { immediate: true, handler() { this.syncFromRoute() } },
    segmentTypeTabOptions: {
      handler() {
        const a = this.activeSegmentType
        if (a === '' || a === undefined || a === null) return
        const still = this.segmentTypeTabOptions.some(s => String(s.value) === String(a))
        if (!still) {
          this.activeSegmentType = ''
          this.activeSegmentName = ''
        }
      }
    },
    planList: {
      handler() {
        this.$nextTick(() => {
          if (this.activeSegmentType === '' || this.activeSegmentType === undefined || this.activeSegmentType === null) return
          const allowed = this.segmentNameFilterOptions.map(o => o.value)
          const cur = this.activeSegmentName
          if (cur !== '' && cur !== undefined && cur !== null && !allowed.includes(cur)) {
            this.activeSegmentName = ''
          }
        })
      },
      deep: true
    }
  },
  methods: {
    syncFromRoute() {
      const q = this.$route.query
      this.versionId = q.versionId || undefined
      this.versionCode = q.versionCode || ''
      this.specId = q.specId || undefined
      if (this.versionId) this.loadPlans()
    },
    goBack() { this.$router.go(-1) },
    selectSegmentType(val) {
      this.activeSegmentType = val === undefined || val === null ? '' : val
      this.activeSegmentName = ''
    },
    onSegmentNameFilterChange() {
      const allowed = this.segmentNameFilterOptions.map(o => o.value)
      if (!allowed.includes(this.activeSegmentName)) {
        this.activeSegmentName = ''
      }
    },
    segmentTypeDisplayLabel(segmentType) {
      const hit = SEGMENT_FORM_OPTIONS.find(s => String(s.value) === String(segmentType))
      return hit ? hit.label : (segmentType != null ? String(segmentType) : '')
    },
    segLabel(val) {
      return this.segmentTypeDisplayLabel(val)
    },
    loadPlans() {
      this.planLoading = true
      this.selectedPlan = null
      this.paramList = []
      listProcessPlan({ versionId: this.versionId, pageNum: 1, pageSize: 500 }).then(res => {
        this.planList = res.rows || []
      }).catch(e => console.error(e)).finally(() => { this.planLoading = false })
    },
    loadParams(planId) {
      this.paramLoading = true
      listProcessPlanParam({ planId, pageNum: 1, pageSize: 500 }).then(res => {
        this.paramList = res.rows || []
      }).catch(e => console.error(e)).finally(() => { this.paramLoading = false })
    },
    onPlanSelect(row) {
      if (!row) return
      this.selectedPlan = row
      this.loadParams(row.planId)
    },
    applyFilter() { this.appliedFilterName = this.filterName },
    resetFilter() {
      this.filterName = ''
      this.appliedFilterName = ''
      this.activeSegmentName = ''
    },
    openPlanDialog(row) {
      this.planForm = row
        ? { ...row }
        : {
            versionId: this.versionId,
            segmentType: 'PROCESS',
            segmentName: undefined,
            pointName: undefined,
            pointCode: undefined,
            actualValueId: undefined,
            l1SetValueId: undefined,
            targetValue: undefined,
            lowerLimit: undefined,
            upperLimit: undefined,
            sortOrder: 0,
            remark: undefined
          }
      this.planTitle = row ? '编辑方案点位' : '新建方案点位'
      this.planOpen = true
      this.$nextTick(() => this.$refs.planFormRef && this.$refs.planFormRef.clearValidate())
    },
    submitPlan() {
      this.$refs.planFormRef.validate(ok => {
        if (!ok) return
        this.planSubmitLoading = true
        const req = this.planForm.planId ? updateProcessPlan(this.planForm) : addProcessPlan(this.planForm)
        req.then(() => {
          this.$modal.msgSuccess('保存成功')
          this.planOpen = false
          this.loadPlans()
        }).catch(e => console.error(e)).finally(() => { this.planSubmitLoading = false })
      })
    },
    removePlan(row) {
      this.$modal.confirm('确认删除该方案点位？').then(() => {
        return delProcessPlan(row.planId)
      }).then(() => {
        this.$modal.msgSuccess('删除成功')
        if (this.selectedPlan && this.selectedPlan.planId === row.planId) {
          this.selectedPlan = null
          this.paramList = []
        }
        this.loadPlans()
      }).catch(() => {})
    },
    openParamDialog(planRow, paramRow) {
      const targetPlan = planRow || this.selectedPlan
      if (!targetPlan) { this.$message.warning('请先选择一个方案点位'); return }
      if (!this.selectedPlan || this.selectedPlan.planId !== targetPlan.planId) {
        this.selectedPlan = targetPlan
        this.loadParams(targetPlan.planId)
      }
      this.paramForm = paramRow
        ? { ...paramRow }
        : {
            planId: targetPlan.planId,
            paramCode: undefined,
            paramName: undefined,
            targetValue: undefined,
            lowerLimit: undefined,
            upperLimit: undefined,
            unit: undefined,
            remark: undefined
          }
      this.paramTitle = paramRow ? '编辑方案参数' : '新建方案参数'
      this.paramOpen = true
      this.$nextTick(() => this.$refs.paramFormRef && this.$refs.paramFormRef.clearValidate())
    },
    submitParam() {
      this.$refs.paramFormRef.validate(ok => {
        if (!ok) return
        this.paramSubmitLoading = true
        const req = this.paramForm.paramId ? updateProcessPlanParam(this.paramForm) : addProcessPlanParam(this.paramForm)
        req.then(() => {
          this.$modal.msgSuccess('保存成功')
          this.paramOpen = false
          this.loadParams(this.selectedPlan.planId)
        }).catch(e => console.error(e)).finally(() => { this.paramSubmitLoading = false })
      })
    },
    removeParam(row) {
      this.$modal.confirm('确认删除该参数？').then(() => {
        return delProcessPlanParam(row.paramId)
      }).then(() => {
        this.$modal.msgSuccess('删除成功')
        this.loadParams(this.selectedPlan.planId)
      }).catch(() => {})
    }
  }
}
</script>

<style scoped>
.plan-spec-page {
  padding: 16px 20px;

  min-height: 100%;
}

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

.page-title {
  font-size: 15px;
  font-weight: 600;
  color: #303133;
}

.version-badge {
  font-size: 12px;
  color: #909399;
  background: #f0f2f5;
  padding: 2px 8px;
  border-radius: 10px;
}

.config-tabs {
  display: flex;
  gap: 0;
  margin-bottom: 14px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  overflow: hidden;
  width: fit-content;
}

.config-tab {
  padding: 5px 20px;
  font-size: 12px;
  cursor: pointer;
  color: #606266;
  background: #fff;
  border: none;
  border-right: 1px solid #dcdfe6;
  transition: color .15s, background .15s;
  user-select: none;
  line-height: 1;
}

.config-tab:last-child { border-right: none; }
.config-tab:hover { color: #5F7BA0; }

.config-tab.active {
  color: #fff;
  background: #5F7BA0;
}

.main-layout {
  display: flex;
  gap: 0;
  background: #fff;
  border-radius: 4px;
  border: 1px solid #ebeef5;
  overflow: hidden;
}

.left-tree {
  width: 120px;
  flex-shrink: 0;
  border-right: 1px solid #ebeef5;
  padding: 8px 0;
}

.tree-item {
  padding: 9px 16px;
  font-size: 13px;
  cursor: pointer;
  color: #606266;
  transition: all .15s;
  user-select: none;
}

.tree-item:hover { background: #f5f7fa; }

.tree-item.active {
  background: #5F7BA0;
  color: #fff;
  font-weight: 500;
}

.tree-item.active .tree-arrow { color: rgba(255,255,255,.6); }

.tree-arrow {
  margin-right: 4px;
  color: #c0c4cc;
}

.right-content {
  flex: 1;
  min-width: 0;
  padding: 12px;
}

.search-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}

.search-label {
  font-size: 13px;
  color: #606266;
  white-space: nowrap;
}

.param-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 0 8px;
  margin-top: 12px;
  border-top: 1px solid #ebeef5;
  font-size: 13px;
  font-weight: 600;
  color: #606266;
}

.el-table { border-radius: 0; }

::v-deep .el-button--primary {
  color: #fff !important;
  background: #5F7BA0 !important;
  border-color: #5F7BA0 !important;
}
::v-deep .el-button--primary:hover,
::v-deep .el-button--primary:focus { background: #4d6a8e !important; border-color: #4d6a8e !important; }
::v-deep .el-button--primary:active { background: #4a6585 !important; border-color: #4a6585 !important; }
::v-deep .el-button--primary.is-disabled { opacity: .5; }

::v-deep .el-button:not(.el-button--primary):not(.el-button--text):not(.el-button--danger) {
  color: #606266 !important;
  background: #fff !important;
  border-color: #dcdfe6 !important;
}
::v-deep .el-button:not(.el-button--primary):not(.el-button--text):not(.el-button--danger):hover {
  color: #5F7BA0 !important;
  border-color: #5F7BA0 !important;
}

::v-deep .el-button--text { background: transparent !important; border-color: transparent !important; }
::v-deep .el-button--text.btn-danger { color: #f56c6c !important; }

.btn-danger { color: #f56c6c; }
</style>
