<template>
  <div class="app-container page-shell">
    <section class="page-hero">
      <div class="hero-copy">
        <span class="hero-eyebrow">ALARM RULE STUDIO</span>
        <h2 class="hero-title">异常告警规则与处置措施工作台</h2>
        <p class="hero-desc">把触发阈值、恢复区间和处置步骤聚合在一个界面中，帮助运维团队更快定位规则、编排措施并完成闭环维护。</p>
      </div>
      <div class="hero-stats">
        <article v-for="item in overviewStats" :key="item.label" class="stat-card">
          <span class="stat-label">{{ item.label }}</span>
          <strong class="stat-value">{{ item.value }}</strong>
          <span class="stat-hint">{{ item.hint }}</span>
        </article>
      </div>
    </section>

    <section v-show="showSearch" class="panel-shell search-shell">
      <div class="panel-head">
        <div>
          <h3>规则筛选</h3>
          <p>按规则名称、触发逻辑和启用状态快速定位目标告警规则。</p>
        </div>
        <span class="panel-badge">规则检索</span>
      </div>
      <el-form :model="queryParams" ref="queryFormRef" size="small" :inline="true" label-width="100px" class="query-form">
        <el-form-item label="规则名称" prop="ruleName">
          <el-input v-model="queryParams.ruleName" placeholder="请输入规则名称" clearable @keyup.enter="handleQuery" />
        </el-form-item>
        <el-form-item label="触发规则" prop="triggerRule">
          <el-select v-model="queryParams.triggerRule" placeholder="请选择触发规则" clearable>
            <el-option v-for="dict in dict.type.trigger_rule" :key="dict.value" :label="dict.label" :value="dict.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="启用状态" prop="isEnable">
          <el-select v-model="queryParams.isEnable" placeholder="请选择启用状态" clearable>
            <el-option v-for="dict in dict.type.is_flag" :key="dict.value" :label="dict.label" :value="dict.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="通知组" prop="notifyGroupId">
          <el-select v-model="queryParams.notifyGroupId" placeholder="请选择通知组" clearable filterable style="width: 220px">
            <el-option v-for="group in groupOptions" :key="group.id" :label="group.groupName" :value="group.id" />
          </el-select>
        </el-form-item>
        <el-form-item class="query-actions">
          <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
          <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>
    </section>

    <section class="panel-shell table-shell">
      <div class="panel-head">
        <div>
          <h3>规则列表</h3>
          <p>保持原有批量操作与导出能力，同时通过更清晰的层次强化巡检效率。</p>
        </div>
        <span class="panel-badge warm">措施联动</span>
      </div>

      <div class="notify-entry-bar">
        <div class="notify-entry-text">通知组与通知成员的配置入口已经接回规则页，保存时会同步回填通知对象摘要，避免规则挂空通知链。</div>
        <div class="notify-entry-actions">
          <el-button link type="primary" @click="openNotifyGroupPage">配置通知组</el-button>
          <el-button link type="primary" @click="openNotifyUserPage">配置通知成员</el-button>
        </div>
      </div>

      <el-row :gutter="10" class="toolbar-row">
        <el-col :span="1.5">
          <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['ems/record:recordAlarmRule:add']"
            >新增
          </el-button>
        </el-col>
        <el-col :span="1.5">
          <el-button
            type="success"
            plain
            icon="el-icon-edit"
            size="mini"
            :disabled="single"
            @click="handleUpdate"
            v-hasPermi="['ems/record:recordAlarmRule:edit']"
            >修改
          </el-button>
        </el-col>
        <el-col :span="1.5">
          <el-button
            type="danger"
            plain
            icon="el-icon-delete"
            size="mini"
            :disabled="multiple"
            @click="handleDelete"
            v-hasPermi="['ems/record:recordAlarmRule:remove']"
            >删除
          </el-button>
        </el-col>
        <el-col :span="1.5">
          <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['ems/record:recordAlarmRule:export']"
            >导出
          </el-button>
        </el-col>
        <right-toolbar v-model:show-search="showSearch" @query-table="getList" :columns="columns"></right-toolbar>
      </el-row>

      <el-table v-loading="loading" :data="recordAlarmRuleList" @selection-change="handleSelectionChange" class="data-table">
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column label="序号" type="index" width="60" align="center" v-if="columns[0].visible" />
        <el-table-column label="规则名称" align="center" prop="ruleName" v-if="columns[1].visible" />
        <el-table-column label="计量设备" align="center" prop="monitorName" v-if="columns[2].visible" />
        <el-table-column label="触发规则" align="center" prop="triggerRule" v-if="columns[3].visible">
          <template #default="scope">
            <dict-tag :options="dict.type.trigger_rule" :value="scope.row.triggerRule" />
          </template>
        </el-table-column>
        <el-table-column label="监测字段" align="center" prop="monitorField" v-if="columns[4].visible">
          <template #default="scope">
            <dict-tag :options="dict.type.monitor_field" :value="scope.row.monitorField" />
          </template>
        </el-table-column>
        <el-table-column label="告警上限" align="center" prop="alarmUpper" v-if="columns[5].visible" />
        <el-table-column label="告警下限" align="center" prop="alarmLower" v-if="columns[6].visible" />
        <el-table-column label="恢复上限" align="center" prop="recoverUpper" v-if="columns[7].visible" />
        <el-table-column label="恢复下限" align="center" prop="recoverLower" v-if="columns[8].visible" />
        <el-table-column label="回差" align="center" prop="hysteresis" v-if="columns[9].visible" />
        <el-table-column label="持续秒数" align="center" prop="durationSec" v-if="columns[10].visible" />
        <el-table-column label="告警级别" align="center" prop="alarmLevel" v-if="columns[11].visible" />
        <el-table-column label="启用状态" align="center" prop="isEnable" v-if="columns[12].visible">
          <template #default="scope">
            <dict-tag :options="dict.type.is_flag" :value="scope.row.isEnable" />
          </template>
        </el-table-column>
        <el-table-column label="备注" align="center" prop="cause" v-if="columns[13].visible" />
        <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="150">
          <template #default="scope">
            <el-button
              size="mini"
              type="text"
              icon="el-icon-setting"
              @click="handleActionSteps(scope.row)"
              v-hasPermi="['ems/record:recordAlarmRule:edit']"
              >措施
            </el-button>
            <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['ems/record:recordAlarmRule:edit']"
              >修改
            </el-button>
            <el-button
              size="mini"
              type="text"
              icon="el-icon-delete"
              @click="handleDelete(scope.row)"
              v-hasPermi="['ems/record:recordAlarmRule:remove']"
              >删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
    </section>

    <!-- 添加或修改异常告警规则对话框 -->
    <el-dialog :title="title" v-model="open" width="500px" append-to-body class="themed-dialog">
      <div class="dialog-tip">
        <span class="tip-dot"></span>
        规则页继续沿用现有字段提交逻辑，只在视觉上突出阈值、恢复区间和设备绑定关系，避免误改业务能力。
      </div>
      <el-form ref="formRef" :model="form" :rules="rules" label-width="150px" class="dialog-form">
        <!-- <el-form-item label="规则编号" prop="ruleId">
          <el-input v-model="form.ruleId" placeholder="请输入规则编号" disabled/>
        </el-form-item> -->
        <el-form-item label="规则名称" prop="ruleName">
          <el-input v-model="form.ruleName" placeholder="请输入规则名称" />
        </el-form-item>
        <el-form-item label="计量设备编号" prop="monitorId">
          <!--          <el-input v-model="form.monitorId" placeholder="请输入计量设备编号"/>-->
          <el-select v-model="form.monitorId" placeholder="请选择计量设备" @change="handleMonitorChange">
            <el-option v-for="item in monitorList" :key="item.monitorCode" :label="item.monitorName" :value="item.monitorCode" />
          </el-select>
        </el-form-item>
        <!--        <el-form-item label="记录时间" prop="collectTime">-->
        <!--          <el-date-picker clearable-->
        <!--                          v-model="form.collectTime"-->
        <!--                          type="date"-->
        <!--                          value-format="yyyy-MM-dd"-->
        <!--                          placeholder="请选择记录时间"-->
        <!--          >-->
        <!--          </el-date-picker>-->
        <!--        </el-form-item>-->
        <!--        <el-form-item label="能源类型" prop="energyType">-->
        <!--          <el-input v-model="form.energyType" placeholder="请输入能源类型" disabled/>-->
        <!--        </el-form-item>-->
        <el-form-item label="触发规则" prop="triggerRule">
          <el-radio-group v-model="form.triggerRule">
            <el-radio v-for="dict in dict.type.trigger_rule" :key="dict.value" :label="parseInt(dict.value)">{{ dict.label }} </el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="监测字段" prop="monitorField">
          <el-select v-model="form.monitorField" placeholder="请选择监测字段">
            <el-option v-for="dict in dict.type.monitor_field" :key="dict.value" :label="dict.label" :value="dict.value" />
          </el-select>
        </el-form-item>
        <!--        <el-form-item label="时间范围(分)" prop="timeRange">-->
        <!--          <el-input v-model="form.timeRange" placeholder="请输入时间范围(分)"/>-->
        <!--        </el-form-item>-->
        <el-form-item label="告警上限" prop="alarmUpper">
          <el-input-number v-model="form.alarmUpper" placeholder="请输入告警上限" :precision="4" />
        </el-form-item>
        <el-form-item label="告警下限" prop="alarmLower">
          <el-input-number v-model="form.alarmLower" placeholder="请输入告警下限" :precision="4" />
        </el-form-item>
        <el-form-item label="恢复上限" prop="recoverUpper">
          <el-input-number v-model="form.recoverUpper" placeholder="请输入恢复上限" :precision="4" />
        </el-form-item>
        <el-form-item label="恢复下限" prop="recoverLower">
          <el-input-number v-model="form.recoverLower" placeholder="请输入恢复下限" :precision="4" />
        </el-form-item>
        <el-form-item label="回差" prop="hysteresis">
          <el-input-number v-model="form.hysteresis" placeholder="请输入回差" :precision="4" />
        </el-form-item>
        <el-form-item label="持续秒数" prop="durationSec">
          <el-input-number v-model="form.durationSec" placeholder="请输入持续秒数" :precision="0" />
        </el-form-item>
        <el-form-item label="告警级别" prop="alarmLevel">
          <el-input v-model="form.alarmLevel" placeholder="请输入告警级别" />
        </el-form-item>
        <el-form-item label="通知组" prop="notifyGroupId">
          <el-select v-model="form.notifyGroupId" placeholder="请选择通知组" clearable filterable style="width: 100%" @change="handleNotifyGroupChange">
            <el-option v-for="group in groupOptions" :key="group.id" :label="group.groupName" :value="group.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="通知对象摘要" prop="notifyUser">
          <el-input v-model="form.notifyUser" type="textarea" :rows="2" placeholder="可手工补充通知对象；选择通知组后会自动回填成员摘要" />
          <div class="field-tip">这里保留 notifyUser 摘要字段，是为了兼容旧台账展示；后端会以 notifyGroupId 作为通知配置的主校验入口。</div>
        </el-form-item>
        <el-form-item label="启用状态" prop="isEnable">
          <el-radio-group v-model="form.isEnable">
            <el-radio v-for="dict in dict.type.is_flag" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="备注" prop="cause">
          <el-input v-model="form.cause" placeholder="请输入备注" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 措施管理对话框 -->
    <el-dialog :title="actionStepsTitle" v-model="actionStepsOpen" width="1200px" append-to-body class="themed-dialog action-dialog">
      <div class="action-steps-container">
        <div class="dialog-tip soft">
          <span class="tip-dot"></span>
          处置步骤支持顺序编排、图片补充和批量保存，适合沉淀标准化应急 SOP。
        </div>
        <!-- 步骤列表 -->
        <div class="steps-section">
          <div class="section-header">
            <span class="section-title">处置措施步骤</span>
            <el-button type="primary" size="mini" icon="el-icon-plus" @click="addActionStep"> 添加步骤 </el-button>
          </div>

          <div v-if="actionStepsList.length === 0" class="empty-steps">
            <el-empty description="暂无处置措施，请点击添加步骤"></el-empty>
          </div>

          <div v-else class="steps-list">
            <div v-for="(step, index) in actionStepsList" :key="step.tempId || step.objId" class="step-item" :data-index="index">
              <div class="step-header">
                <span class="step-number">步骤 {{ step.stepSequence }}</span>
                <div class="step-controls">
                  <el-button v-if="index > 0" type="text" size="mini" icon="el-icon-top" @click="moveStepUp(index)" title="上移"></el-button>
                  <el-button
                    v-if="index < actionStepsList.length - 1"
                    type="text"
                    size="mini"
                    icon="el-icon-bottom"
                    @click="moveStepDown(index)"
                    title="下移"
                  ></el-button>
                  <el-button type="danger" size="mini" icon="el-icon-delete" @click="removeActionStep(index)" circle></el-button>
                </div>
              </div>

              <div class="step-content">
                <el-form :model="step" label-width="100px" size="small">
                  <el-form-item label="步骤描述">
                    <el-input v-model="step.description" type="textarea" :rows="3" placeholder="请输入步骤描述"></el-input>
                  </el-form-item>

                  <el-form-item label="备注">
                    <el-input v-model="step.remark" placeholder="请输入备注信息"></el-input>
                  </el-form-item>

                  <el-form-item label="参考图片">
                    <div class="image-upload-section">
                      <!-- 图片上传 -->
                      <el-upload
                        :action="uploadAction"
                        :headers="uploadHeaders"
                        :on-success="(res, file, fileList) => handleImageUploadSuccess(res, file, fileList, index)"
                        :before-upload="beforeImageUpload"
                        :show-file-list="false"
                        accept="image/*"
                        drag
                        multiple
                      >
                        <i class="el-icon-upload"></i>
                        <div class="el-upload__text">将图片拖到此处，或<em>点击上传</em></div>
                        <template v-slot:tip>
                          <div class="el-upload__tip">只能上传jpg/png文件，且不超过2MB</div>
                        </template>
                      </el-upload>

                      <!-- 图片列表 -->
                      <div v-if="step.stepImages && step.stepImages.length > 0" class="image-list">
                        <div v-for="(image, imgIndex) in step.stepImages" :key="image.tempId || image.objId" class="image-item">
                          <div class="image-preview" @click="previewImage(getFullImageUrl(image.imageUrl))">
                            <img :src="getFullImageUrl(image.imageUrl)" alt="预览图" />
                          </div>
                          <div class="image-info">
                            <el-input v-model="image.description" placeholder="图片描述" size="mini"></el-input>
                            <el-button type="danger" size="mini" icon="el-icon-delete" @click="removeStepImage(index, imgIndex)" circle></el-button>
                          </div>
                        </div>
                      </div>
                    </div>
                  </el-form-item>
                </el-form>
              </div>
            </div>
          </div>
        </div>
      </div>

      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="saveActionSteps" :loading="actionStepsSaving"> 保存措施 </el-button>
          <el-button @click="cancelActionSteps">取消</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 图片预览对话框 -->
    <el-dialog title="图片预览" v-model="imagePreviewVisible" width="80%" append-to-body center class="themed-dialog preview-dialog">
      <div class="image-preview-container">
        <img :src="previewImageUrl" style="max-width: 100%; max-height: 70vh" />
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ElMessage, ElMessageBox } from 'element-plus';
import { useDict } from '@/utils/dict';
import { listAlarmNotifyGroupAll } from '@/api/ems/base/alarmNotifyGroup';
import { listAlarmNotifyGroupUser } from '@/api/ems/base/alarmNotifyGroupUser';
import {
  listRecordAlarmRule,
  getRecordAlarmRule,
  delRecordAlarmRule,
  addRecordAlarmRule,
  updateRecordAlarmRule
} from '@/api/ems/record/recordAlarmRule';
import { listBaseMonitorInfo } from '@/api/ems/base/baseMonitorInfo';
import { getEmsAlarmActionStepsByRuleId, batchSaveActionSteps } from '@/api/ems/base/emsAlarmActionStep';
import type { AlarmNotifyGroupVO } from '@/api/ems/base/alarmNotifyGroup/types';
import type { AlarmNotifyGroupUserVO } from '@/api/ems/base/alarmNotifyGroupUser/types';
import { getToken } from '@/utils/auth';

defineOptions({
  name: 'RecordAlarmRule',
  dicts: ['trigger_rule', 'monitor_field', 'is_flag']
});

const { proxy } = getCurrentInstance() as ComponentInternalInstance;

const dict = reactive({
  type: useDict('trigger_rule', 'monitor_field', 'is_flag')
});

const formRef = ref<ElFormInstance>();
const queryFormRef = ref<ElFormInstance>();

const createQueryParams = () => ({
  pageNum: 1,
  pageSize: 10,
  ruleId: null,
  ruleName: null,
  monitorId: null,
  monitorCode: null,
  monitorName: null,
  collectTime: null,
  energyType: null,
  triggerRule: null,
  monitorField: null,
  timeRange: null,
  triggerValue: null,
  metricCode: null,
  alarmUpper: null,
  alarmLower: null,
  recoverUpper: null,
  recoverLower: null,
  hysteresis: null,
  durationSec: null,
  alarmLevel: null,
  isEnable: null,
  notifyGroupId: null,
  notifyUser: null,
  nickName: null,
  cause: null
});

// 这里统一通过工厂函数重建表单，避免弹窗在新增/编辑切换时残留上一条业务数据。
const createFormData = () => ({
  objId: null,
  ruleId: null,
  ruleName: null,
  monitorId: null,
  monitorCode: null,
  monitorName: null,
  collectTime: null,
  energyType: null,
  triggerRule: null,
  monitorField: null,
  timeRange: null,
  triggerValue: null,
  tenantId: null,
  metricCode: null,
  alarmUpper: null,
  alarmLower: null,
  recoverUpper: null,
  recoverLower: null,
  hysteresis: null,
  durationSec: null,
  alarmLevel: null,
  notifyGroupId: null,
  isEnable: '0',
  notifyUser: null,
  nickName: null,
  cause: null,
  createBy: null,
  createTime: null,
  updateBy: null,
  updateTime: null
});

// 这里保留原页面字段结构，优先保证 EMS 业务行为与接口入参不发生漂移。
const state = reactive({
  // 遮罩层
  loading: true,
  // 选中数组
  ids: [],
  // 非单个禁用
  single: true,
  // 非多个禁用
  multiple: true,
  // 显示搜索条件
  showSearch: true,
  // 总条数
  total: 0,
  // 异常告警规则表格数据
  recordAlarmRuleList: [],
  // 弹出层标题
  title: '',
  // 是否显示弹出层
  open: false,
  // 设备列表
  monitorList: [],
  groupOptions: [] as AlarmNotifyGroupVO[],
  groupUserMap: {} as Record<string, AlarmNotifyGroupUserVO[]>,
  selectedMonitorType: null,
  // 新增：用于存储选中设备的 monitorType
  // 查询参数
  // 查询对象补齐隐藏字段，避免导出和详情回填时出现“前端没带字段”的假缺失。
  queryParams: createQueryParams(),
  // 表单参数
  form: createFormData(),
  // 表单校验
  rules: {
    ruleName: [{ required: true, message: '规则名称不能为空', trigger: 'blur' }],
    monitorId: [{ required: true, message: '计量设备不能为空', trigger: 'change' }],
    triggerRule: [{ required: true, message: '触发规则不能为空', trigger: 'change' }],
    monitorField: [{ required: true, message: '监测字段不能为空', trigger: 'change' }]
  },
  columns: [
    {
      key: 0,
      label: `序号`,
      visible: true
    },
    {
      key: 1,
      label: `规则名称`,
      visible: true
    },
    {
      key: 2,
      label: `计量设备`,
      visible: true
    },
    {
      key: 3,
      label: `触发规则`,
      visible: true
    },
    {
      key: 4,
      label: `监测字段`,
      visible: true
    },
    {
      key: 5,
      label: `告警上限`,
      visible: true
    },
    {
      key: 6,
      label: `告警下限`,
      visible: true
    },
    {
      key: 7,
      label: `恢复上限`,
      visible: true
    },
    {
      key: 8,
      label: `恢复下限`,
      visible: true
    },
    {
      key: 9,
      label: `回差`,
      visible: true
    },
    {
      key: 10,
      label: `持续秒数`,
      visible: true
    },
    {
      key: 11,
      label: `告警级别`,
      visible: true
    },
    {
      key: 12,
      label: `启用状态`,
      visible: true
    },
    {
      key: 13,
      label: `备注`,
      visible: true
    }
    // { key: 12, label: `创建人`, visible: false },
    // { key: 13, label: `创建时间`, visible: true },
    // { key: 14, label: `更新人`, visible: false },
    // { key: 15, label: `更新时间`, visible: false }
  ],
  actionStepsTitle: '',
  actionStepsOpen: false,
  actionStepsList: [],
  actionStepsSaving: false,
  currentRuleObjId: '',
  uploadAction: import.meta.env.VITE_APP_BASE_API + '/common/upload',
  uploadHeaders: {
    Authorization: 'Bearer ' + getToken()
  },
  previewImageUrl: '',
  imagePreviewVisible: false
} as any);

const {
  actionStepsList,
  actionStepsOpen,
  actionStepsSaving,
  actionStepsTitle,
  columns,
  currentRuleObjId,
  form,
  groupOptions,
  ids,
  imagePreviewVisible,
  loading,
  monitorList,
  multiple,
  open,
  previewImageUrl,
  queryParams,
  recordAlarmRuleList,
  rules,
  selectedMonitorType,
  showSearch,
  single,
  title,
  total,
  uploadAction,
  uploadHeaders
} = toRefs(state);

const resolveNotifyUsers = (groupId?: string | number | null) => {
  if (groupId === null || groupId === undefined || groupId === '') {
    return '';
  }
  const users = state.groupUserMap[String(groupId)] || [];
  return users
    .map((item) => item.nickName || item.userName || item.phone || item.email)
    .filter(Boolean)
    .join('、');
};

// 这里补充展示型统计卡，帮助运维先看到规则覆盖面，不改变任何列表查询和保存逻辑。
const overviewStats = computed(() => {
  const rules = recordAlarmRuleList.value;
  const relatedDevices = new Set(rules.filter((item) => item.monitorId).map((item) => item.monitorId)).size;
  const dualThresholdRules = rules.filter((item) => item.alarmUpper != null && item.alarmLower != null).length;
  const recoveryRules = rules.filter((item) => item.recoverUpper != null || item.recoverLower != null).length;

  return [
    {
      label: '规则总数',
      value: total.value || rules.length,
      hint: '当前列表分页总量'
    },
    {
      label: '关联设备',
      value: relatedDevices,
      hint: '已绑定计量设备'
    },
    {
      label: '双阈值规则',
      value: dualThresholdRules,
      hint: '同时配置上下限'
    },
    {
      label: '含恢复区间',
      value: recoveryRules,
      hint: '带恢复阈值约束'
    }
  ];
});

const getList = () => {
  loading.value = true;
  listRecordAlarmRule(queryParams.value).then((response) => {
    recordAlarmRuleList.value = response.rows ?? response.data ?? [];
    total.value = response.total ?? 0;
    loading.value = false;
  });
};

const cancel = () => {
  open.value = false;
  reset();
};

const reset = () => {
  form.value = createFormData();
  selectedMonitorType.value = null; // 重置时清空
  formRef.value?.resetFields();
};

const handleQuery = () => {
  queryParams.value.pageNum = 1;
  getList();
};

const resetQuery = () => {
  queryFormRef.value?.resetFields();
  handleQuery();
};

const handleSelectionChange = (selection) => {
  ids.value = selection.map((item) => item.objId);
  single.value = selection.length !== 1;
  multiple.value = !selection.length;
};

const handleAdd = () => {
  reset();
  open.value = true;
  title.value = '添加异常告警规则';
};

const handleUpdate = (row) => {
  reset();
  const objId = row.objId || ids.value;
  getRecordAlarmRule(objId).then((response) => {
    // 详情回填时保留默认字段，防止后端已补齐的新字段被旧页面覆盖掉。
    form.value = {
      ...createFormData(),
      ...(response.data ?? {})
    };
    form.value.isEnable = form.value.isEnable ?? '0';
    // 当修改时，需要根据 form.monitorId（实际是monitorCode）初始化 selectedMonitorType
    const selectedMonitor = monitorList.value.find((m) => m.monitorCode === form.value.monitorId);
    if (selectedMonitor) {
      selectedMonitorType.value = selectedMonitor.monitorType;
    }
    if (form.value.notifyGroupId) {
      handleNotifyGroupChange(form.value.notifyGroupId);
    }
    open.value = true;
    title.value = '修改异常告警规则';
  });
};

const submitForm = () => {
  formRef.value?.validate((valid) => {
    if (valid) {
      // 规则页不直接展示 metricCode/energyType，但提交时要跟随点位一并透传，避免后端链路缺字段。
      const selectedMonitor = monitorList.value.find((m) => m.monitorCode === form.value.monitorId);
      if (selectedMonitor) {
        form.value.monitorName = selectedMonitor.monitorName;
        form.value.tenantId = selectedMonitor.tenantId ?? form.value.tenantId;
        form.value.metricCode = selectedMonitor.metricCode ?? form.value.metricCode;
        form.value.energyType = selectedMonitor.monitorType ?? form.value.energyType;
      }
      if (form.value.triggerRule === 0 && form.value.alarmUpper != null) {
        form.value.triggerValue = form.value.alarmUpper;
      }
      if (form.value.triggerRule === 1 && form.value.alarmLower != null) {
        form.value.triggerValue = form.value.alarmLower;
      }
      form.value.isEnable = form.value.isEnable ?? '0';
      if (form.value.notifyGroupId) {
        const notifySummary = resolveNotifyUsers(form.value.notifyGroupId);
        if (!notifySummary && !form.value.notifyUser) {
          ElMessage.warning('当前通知组没有可用成员，请先补充通知成员后再保存规则');
          return;
        }
        form.value.notifyUser = form.value.notifyUser || notifySummary;
      }
      if (form.value.objId != null) {
        updateRecordAlarmRule(form.value).then((response) => {
          proxy?.$modal.msgSuccess('修改成功');
          open.value = false;
          getList();
        });
      } else {
        addRecordAlarmRule(form.value).then((response) => {
          proxy?.$modal.msgSuccess('新增成功');
          open.value = false;
          getList();
        });
      }
    }
  });
};

const handleDelete = (row) => {
  const objIds = row.objId || ids.value;
  proxy?.$modal
    .confirm('是否确认删除异常告警规则编号为"' + objIds + '"的数据项？')
    .then(function () {
      return delRecordAlarmRule(objIds);
    })
    .then(() => {
      getList();
      proxy?.$modal.msgSuccess('删除成功');
    })
    .catch(() => {});
};

const handleExport = () => {
  proxy?.download(
    'ems/record/recordAlarmRule/export',
    {
      ...queryParams.value
    },
    `recordAlarmRule_${new Date().getTime()}.xlsx`
  );
};

const getMonitorList = () => {
  listBaseMonitorInfo().then((response) => {
    monitorList.value = response.rows ?? response.data ?? [];
  });
};

const loadNotifyGroupOptions = async () => {
  const response = await listAlarmNotifyGroupAll();
  groupOptions.value = (((response as any).data ?? (response as any).rows ?? []) || []) as AlarmNotifyGroupVO[];
};

const loadNotifyGroupUsers = async () => {
  const response = await listAlarmNotifyGroupUser({
    pageNum: 1,
    pageSize: 1000
  } as any);
  const users = (((response as any).rows ?? (response as any).data ?? []) || []) as AlarmNotifyGroupUserVO[];
  const nextMap: Record<string, AlarmNotifyGroupUserVO[]> = {};
  users.forEach((item) => {
    const groupId = item.groupId;
    if (groupId === null || groupId === undefined || groupId === '') {
      return;
    }
    const key = String(groupId);
    if (!nextMap[key]) {
      nextMap[key] = [];
    }
    nextMap[key].push(item);
  });
  state.groupUserMap = nextMap;
};

const handleNotifyGroupChange = (groupId?: string | number | null) => {
  if (!groupId) {
    form.value.notifyUser = null;
    return;
  }
  const notifySummary = resolveNotifyUsers(groupId);
  form.value.notifyUser = notifySummary || form.value.notifyUser;
};

const openNotifyGroupPage = () => {
  proxy?.$tab.openPage('/ems/base/alarmNotifyGroup', '通知组配置');
};

const openNotifyUserPage = () => {
  proxy?.$tab.openPage('/ems/base/alarmNotifyGroupUser', '通知成员配置');
};

const handleMonitorChange = (monitorId) => {
  // monitorId这里实际传入的是monitorCode值
  const selectedMonitor = monitorList.value.find((m) => m.monitorCode === monitorId);
  if (selectedMonitor) {
    selectedMonitorType.value = selectedMonitor.monitorType;
    // 设备名称仅作为辅助展示字段回填，不直接渲染技术主键列。
    form.value.monitorName = selectedMonitor.monitorName;
    form.value.tenantId = selectedMonitor.tenantId ?? null;
    form.value.metricCode = selectedMonitor.metricCode ?? null;
    form.value.energyType = selectedMonitor.monitorType ?? null;
    // 如果设备类型不是6或10，则清空已选的监测字段
    if (selectedMonitorType.value !== 6 && selectedMonitorType.value !== 10) {
      form.value.monitorField = null;
    }
  } else {
    selectedMonitorType.value = null;
    form.value.monitorName = null;
    form.value.tenantId = null;
    form.value.metricCode = null;
    form.value.energyType = null;
    form.value.monitorField = null; // 如果找不到设备，也清空
  }
};

const handleActionSteps = (row) => {
  actionStepsTitle.value = '措施管理 - ' + row.ruleName;
  currentRuleObjId.value = row.objId;
  actionStepsOpen.value = true;
  getActionSteps(row.objId);
};

const getActionSteps = (ruleObjId) => {
  getEmsAlarmActionStepsByRuleId(ruleObjId)
    .then((response) => {
      actionStepsList.value = response.data || [];
      // 确保每个步骤都有stepImages数组
      actionStepsList.value.forEach((step) => {
        if (!step.stepImages) {
          step.stepImages = [];
        }
      });
    })
    .catch(() => {
      actionStepsList.value = [];
    });
};

const addActionStep = () => {
  const newSequence = actionStepsList.value.length > 0 ? Math.max(...actionStepsList.value.map((s) => s.stepSequence || 0)) + 1 : 1;
  const newStep = {
    tempId: Date.now() + Math.random(),
    // 临时ID
    ruleObjId: currentRuleObjId.value,
    stepSequence: newSequence,
    description: '',
    remark: '',
    stepImages: []
  };
  actionStepsList.value.push(newStep);
};

const removeActionStep = async (index: number) => {
  try {
    await ElMessageBox.confirm('确定要删除这个步骤吗？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    });
    actionStepsList.value.splice(index, 1);
    // 重新排序步骤序号
    actionStepsList.value.forEach((step, idx) => {
      step.stepSequence = idx + 1;
    });
  } catch {
    return;
  }
};

const handleImageUploadSuccess = (
  res: { code?: number; url?: string; msg?: string },
  _file: UploadFile,
  _fileList: UploadFile[],
  stepIndex: number
) => {
  if (res.code === 200) {
    const step = actionStepsList.value[stepIndex];
    if (!step.stepImages) {
      step.stepImages = [];
    }

    // 从完整URL中提取相对路径，只保存相对路径到数据库
    let relativePath = res.url;
    if (res.url.startsWith('http')) {
      // 如果是完整URL，提取相对路径部分
      const urlObj = new URL(res.url);
      relativePath = urlObj.pathname;
    }
    const newImage = {
      tempId: Date.now() + Math.random(),
      imageUrl: relativePath,
      // 只存储相对路径
      imageSequence: step.stepImages.length + 1,
      description: ''
    };
    step.stepImages.push(newImage);
    ElMessage.success('图片上传成功');
  } else {
    ElMessage.error('图片上传失败：' + res.msg);
  }
};

const beforeImageUpload = (file: UploadFile) => {
  const isImage = file.type.indexOf('image') !== -1;
  const isLt2M = file.size / 1024 / 1024 < 2;
  if (!isImage) {
    ElMessage.error('只能上传图片文件!');
    return false;
  }
  if (!isLt2M) {
    ElMessage.error('上传文件大小不能超过 2MB!');
    return false;
  }
  return true;
};

const removeStepImage = async (stepIndex: number, imgIndex: number) => {
  try {
    await ElMessageBox.confirm('确定要删除这张图片吗？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    });
    actionStepsList.value[stepIndex].stepImages.splice(imgIndex, 1);
    // 重新排序图片序号
    actionStepsList.value[stepIndex].stepImages.forEach((img, idx) => {
      img.imageSequence = idx + 1;
    });
  } catch {
    return;
  }
};

const saveActionSteps = () => {
  // 验证数据
  for (let i = 0; i < actionStepsList.value.length; i++) {
    const step = actionStepsList.value[i];
    if (!step.description || step.description.trim() === '') {
      ElMessage.warning(`步骤 ${step.stepSequence} 的描述不能为空`);
      return;
    }
  }
  actionStepsSaving.value = true;

  // 处理数据，移除临时ID
  const stepsToSave = actionStepsList.value.map((step) => {
    const stepData = {
      ...step
    };
    delete stepData.tempId;
    if (stepData.stepImages && stepData.stepImages.length > 0) {
      stepData.stepImages = stepData.stepImages.map((img) => {
        const imgData = {
          ...img
        };
        delete imgData.tempId;
        return imgData;
      });
    }
    return stepData;
  });
  batchSaveActionSteps(currentRuleObjId.value, stepsToSave)
    .then((response) => {
      ElMessage.success('措施步骤保存成功');
      actionStepsOpen.value = false;
      actionStepsSaving.value = false;
    })
    .catch(() => {
      actionStepsSaving.value = false;
    });
};

const cancelActionSteps = () => {
  actionStepsOpen.value = false;
  actionStepsList.value = [];
  currentRuleObjId.value = '';
};

const previewImage = (url) => {
  previewImageUrl.value = url;
  imagePreviewVisible.value = true;
};

const moveStepUp = (index) => {
  if (index > 0) {
    const temp = actionStepsList.value[index];
    actionStepsList.value[index] = actionStepsList.value[index - 1];
    actionStepsList.value[index - 1] = temp;
    // 重新排序步骤序号
    actionStepsList.value.forEach((step, idx) => {
      step.stepSequence = idx + 1;
    });
  }
};

const moveStepDown = (index) => {
  if (index < actionStepsList.value.length - 1) {
    const temp = actionStepsList.value[index];
    actionStepsList.value[index] = actionStepsList.value[index + 1];
    actionStepsList.value[index + 1] = temp;
    // 重新排序步骤序号
    actionStepsList.value.forEach((step, idx) => {
      step.stepSequence = idx + 1;
    });
  }
};

const getFullImageUrl = (relativePath) => {
  if (!relativePath) return '';

  // 如果已经是完整URL，直接返回（兼容历史数据）
  if (relativePath.startsWith('http')) {
    return relativePath;
  }

  // 动态拼接当前环境的baseURL
  const baseURL = import.meta.env.VITE_APP_BASE_API || '';
  return baseURL + relativePath;
};

onMounted(() => {
  getList();
  getMonitorList();
  loadNotifyGroupOptions();
  loadNotifyGroupUsers();
});
</script>

<style lang="scss" scoped>
.page-shell {
  min-height: 100%;
  padding: 20px;
  background:
    radial-gradient(circle at top left, rgba(59, 130, 246, 0.16), transparent 30%),
    radial-gradient(circle at right center, rgba(244, 114, 182, 0.12), transparent 24%),
    linear-gradient(180deg, #f6f8ff 0%, #eef3fb 45%, #f8fafc 100%);
}

.page-hero {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(320px, 1fr);
  gap: 18px;
  margin-bottom: 18px;
  padding: 30px;
  border-radius: 28px;
  background: linear-gradient(135deg, rgba(43, 52, 126, 0.96) 0%, rgba(30, 64, 175, 0.92) 45%, rgba(219, 39, 119, 0.82) 100%);
  box-shadow: 0 28px 54px rgba(46, 63, 140, 0.2);
  color: #fff;
  position: relative;
  overflow: hidden;
}

.page-hero::before {
  content: '';
  position: absolute;
  inset: -40px auto auto -70px;
  width: 220px;
  height: 220px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
}

.hero-copy,
.hero-stats {
  position: relative;
  z-index: 1;
}

.hero-eyebrow {
  display: inline-flex;
  align-items: center;
  padding: 6px 12px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.14);
  font-size: 12px;
  letter-spacing: 0.16em;
}

.hero-title {
  margin: 18px 0 12px;
  font-size: 30px;
  line-height: 1.2;
}

.hero-desc {
  margin: 0;
  max-width: 680px;
  line-height: 1.75;
  color: rgba(255, 255, 255, 0.82);
}

.hero-stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

.stat-card {
  padding: 18px;
  border-radius: 22px;
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.16);
  backdrop-filter: blur(10px);
}

.stat-label,
.stat-hint {
  display: block;
}

.stat-label {
  color: rgba(255, 255, 255, 0.72);
  font-size: 13px;
}

.stat-value {
  display: block;
  margin: 10px 0 8px;
  font-size: 30px;
  font-weight: 700;
  line-height: 1;
}

.stat-hint {
  color: rgba(255, 255, 255, 0.72);
  font-size: 12px;
}

.panel-shell {
  margin-bottom: 18px;
  padding: 20px 22px;
  border-radius: 24px;
  border: 1px solid rgba(208, 216, 237, 0.75);
  background: rgba(255, 255, 255, 0.88);
  box-shadow: 0 18px 38px rgba(49, 62, 124, 0.08);
  backdrop-filter: blur(14px);
}

.panel-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  margin-bottom: 18px;
}

.panel-head h3 {
  margin: 0 0 6px;
  font-size: 20px;
  color: #1f2a5f;
}

.panel-head p {
  margin: 0;
  color: #6c7598;
  line-height: 1.6;
}

.panel-badge {
  display: inline-flex;
  align-items: center;
  padding: 8px 14px;
  border-radius: 999px;
  background: linear-gradient(135deg, #dbeafe, #ede9fe);
  color: #3344a1;
  font-size: 12px;
  font-weight: 600;
}

.panel-badge.warm {
  background: linear-gradient(135deg, #fee2e2, #fce7f3);
  color: #b42367;
}

.query-form {
  padding: 18px;
  border-radius: 20px;
  background: linear-gradient(180deg, rgba(248, 250, 255, 0.96) 0%, rgba(255, 255, 255, 0.92) 100%);
}

.query-actions {
  :deep(.el-form-item__content) {
    gap: 10px;
  }
}

.toolbar-row {
  margin-bottom: 14px;
  padding: 14px 16px;
  border-radius: 18px;
  background: linear-gradient(90deg, rgba(59, 130, 246, 0.08), rgba(236, 72, 153, 0.08));
}

.notify-entry-bar {
  align-items: center;
  background: rgba(249, 239, 225, 0.7);
  border: 1px solid rgba(190, 141, 103, 0.18);
  border-radius: 18px;
  display: flex;
  gap: 12px;
  justify-content: space-between;
  margin-bottom: 12px;
  padding: 12px 16px;
}

.notify-entry-text {
  color: #6f5b51;
  font-size: 13px;
  line-height: 1.7;
}

.notify-entry-actions {
  display: flex;
  gap: 10px;
}

.data-table {
  :deep(.el-table__header-wrapper th) {
    background: #f5f7ff;
    color: #24336f;
    font-weight: 700;
  }

  :deep(.el-table__body tr:hover > td) {
    background: rgba(79, 70, 229, 0.06) !important;
  }
}

.dialog-tip {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 18px;
  padding: 12px 14px;
  border-radius: 16px;
  background: linear-gradient(90deg, rgba(79, 70, 229, 0.08), rgba(236, 72, 153, 0.08));
  color: #42507f;
  line-height: 1.65;
}

.dialog-tip.soft {
  margin-bottom: 20px;
  background: linear-gradient(90deg, rgba(59, 130, 246, 0.08), rgba(16, 185, 129, 0.08));
}

.tip-dot {
  width: 10px;
  height: 10px;
  flex-shrink: 0;
  border-radius: 50%;
  background: linear-gradient(135deg, #6366f1, #ec4899);
  box-shadow: 0 0 0 5px rgba(99, 102, 241, 0.12);
}

.dialog-form {
  padding: 18px;
  border-radius: 18px;
  background: #fafbff;
}

.field-tip {
  color: var(--el-text-color-secondary);
  font-size: 12px;
  line-height: 1.6;
  margin-top: 6px;
}

.action-steps-container {
  padding: 6px 0 0;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding: 0 0 14px;
  border-bottom: 1px solid rgba(189, 199, 226, 0.72);
}

.section-title {
  font-size: 18px;
  font-weight: bold;
  color: #31439f;
}

.empty-steps {
  text-align: center;
  padding: 60px 0;
}

.steps-list {
  .step-item {
    margin-bottom: 30px;
    border: 1px solid rgba(208, 216, 237, 0.85);
    border-radius: 22px;
    background: linear-gradient(180deg, #ffffff 0%, #f9fbff 100%);
    box-shadow: 0 16px 30px rgba(49, 62, 124, 0.08);

    .step-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 15px 20px;
      background: linear-gradient(90deg, rgba(99, 102, 241, 0.1), rgba(236, 72, 153, 0.08));
      border-bottom: 1px solid rgba(208, 216, 237, 0.7);
      border-radius: 22px 22px 0 0;

      .step-number {
        font-size: 16px;
        font-weight: bold;
        color: #31439f;
      }

      .step-controls {
        display: flex;
        align-items: center;
        gap: 5px;

        .el-button--text {
          color: #606266;
          font-size: 16px;

          &:hover {
            color: #31439f;
          }
        }
      }
    }

    .step-content {
      padding: 20px;
    }
  }
}

.image-upload-section {
  .el-upload-dragger {
    width: 100%;
    height: 120px;
    margin-bottom: 20px;
    border-radius: 18px;
    background: linear-gradient(180deg, #f9fbff 0%, #ffffff 100%);
  }

  .image-list {
    display: flex;
    flex-wrap: wrap;
    gap: 15px;
    margin-top: 15px;

    .image-item {
      width: 200px;
      border: 1px solid rgba(208, 216, 237, 0.85);
      border-radius: 18px;
      overflow: hidden;
      background: white;
      box-shadow: 0 12px 24px rgba(49, 62, 124, 0.08);

      .image-preview {
        height: 150px;
        cursor: pointer;
        position: relative;
        overflow: hidden;

        img {
          width: 100%;
          height: 100%;
          object-fit: cover;
          transition: transform 0.3s;
        }

        &:hover img {
          transform: scale(1.05);
        }
      }

      .image-info {
        padding: 10px;
        display: flex;
        align-items: center;
        gap: 8px;

        .el-input {
          flex: 1;
        }
      }
    }
  }
}

.image-preview-container {
  text-align: center;

  img {
    border-radius: 18px;
    box-shadow: 0 20px 40px rgba(15, 23, 42, 0.18);
  }
}

.dialog-footer {
  text-align: right;
}

:deep(.themed-dialog .el-dialog) {
  border-radius: 26px;
  overflow: hidden;
  box-shadow: 0 28px 60px rgba(28, 37, 94, 0.22);
}

:deep(.themed-dialog .el-dialog__header) {
  padding: 22px 24px 14px;
  background: linear-gradient(135deg, rgba(49, 65, 163, 0.96), rgba(190, 24, 93, 0.88));
}

:deep(.themed-dialog .el-dialog__title),
:deep(.themed-dialog .el-dialog__headerbtn .el-dialog__close) {
  color: #fff;
}

:deep(.themed-dialog .el-dialog__body) {
  padding: 22px 24px;
  background: linear-gradient(180deg, #f8faff 0%, #ffffff 100%);
}

:deep(.themed-dialog .el-dialog__footer) {
  padding: 0 24px 24px;
  background: linear-gradient(180deg, #ffffff 0%, #f8faff 100%);
}

@media (max-width: 992px) {
  .page-hero {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 768px) {
  .page-shell {
    padding: 12px;
  }

  .page-hero,
  .panel-shell {
    padding: 18px;
    border-radius: 20px;
  }

  .hero-stats {
    grid-template-columns: 1fr;
  }

  .panel-head {
    flex-direction: column;
    align-items: flex-start;
  }

  .notify-entry-bar {
    align-items: flex-start;
    flex-direction: column;
  }
}
</style>
