<template>
  <div class="p-2 accident-page">
    <!-- 顶部数据卡片 -->
    <el-row :gutter="20" class="mb-2">
      <el-col :span="6">
        <el-card shadow="hover" class="stat-card">
          <div class="stat-card-content">
            <div class="stat-info">
              <div class="stat-title">本月上报事故</div>
              <div class="stat-value">{{ stats.monthTotal || 0 }}</div>
              <div class="stat-extra" :class="(stats.monthRate || 0) >= 0 ? 'stat-extra-up' : 'stat-extra-down'">
                <el-icon v-if="(stats.monthRate || 0) >= 0"><CaretTop /></el-icon>
                <el-icon v-else><CaretBottom /></el-icon>
                <span>{{ Math.abs(stats.monthRate || 0) }}% 较上月</span>
              </div>
            </div>
            <div class="stat-icon stat-icon-blue">
              <el-icon><Document /></el-icon>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover" class="stat-card">
          <div class="stat-card-content">
            <div class="stat-info">
              <div class="stat-title">待处理</div>
              <div class="stat-value">{{ stats.investigating || 0 }}</div>
              <div class="stat-extra" :class="(stats.investigatingRate || 0) >= 0 ? 'stat-extra-up' : 'stat-extra-down'">
                <el-icon v-if="(stats.investigatingRate || 0) >= 0"><CaretTop /></el-icon>
                <el-icon v-else><CaretBottom /></el-icon>
                <span>{{ Math.abs(stats.investigatingRate || 0) }}% 较上月</span>
              </div>
            </div>
            <div class="stat-icon stat-icon-orange">
              <el-icon><Search /></el-icon>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover" class="stat-card">
          <div class="stat-card-content">
            <div class="stat-info">
              <div class="stat-title">归档</div>
              <div class="stat-value">{{ stats.finished || 0 }}</div>
              <div class="stat-extra" :class="(stats.finishedRate || 0) >= 0 ? 'stat-extra-up' : 'stat-extra-down'">
                <el-icon v-if="(stats.finishedRate || 0) >= 0"><CaretTop /></el-icon>
                <el-icon v-else><CaretBottom /></el-icon>
                <span>{{ Math.abs(stats.finishedRate || 0) }}% 较上月</span>
              </div>
            </div>
            <div class="stat-icon stat-icon-green">
              <el-icon><CircleCheck /></el-icon>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover" class="stat-card">
          <div class="stat-card-content">
            <div class="stat-info">
              <div class="stat-title">待考核</div>
              <div class="stat-value">{{ stats.pendingAssess || 0 }}</div>
              <div class="stat-extra" :class="(stats.pendingAssessRate || 0) >= 0 ? 'stat-extra-up' : 'stat-extra-down'">
                <el-icon v-if="(stats.pendingAssessRate || 0) >= 0"><CaretTop /></el-icon>
                <el-icon v-else><CaretBottom /></el-icon>
                <span>{{ Math.abs(stats.pendingAssessRate || 0) }}% 较上月</span>
              </div>
            </div>
            <div class="stat-icon stat-icon-red">
              <el-icon><EditPen /></el-icon>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 搜索区域 -->
    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
      <div v-show="showSearch" class="mb-[10px]">
        <el-card shadow="hover">
          <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="80">
            <el-form-item label="关键词" prop="keyword">
              <el-input v-model="queryParams.keyword" placeholder="编号/名称" clearable style="width: 200px" @keyup.enter="handleQuery" />
            </el-form-item>
            <el-form-item label="状态" prop="handleStatus">
              <el-select v-model="queryParams.handleStatus" placeholder="所有状态" clearable style="width: 200px">
                <el-option v-for="dict in accident_status_dict" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
            <el-form-item label="等级" prop="accidentLevel">
              <el-select v-model="queryParams.accidentLevel" placeholder="事故等级" clearable style="width: 200px">
                <el-option v-for="dict in accident_level_dict" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
            <el-form-item label="类型" prop="accidentType">
              <el-select v-model="queryParams.accidentType" placeholder="事故类型" clearable style="width: 200px">
                <el-option v-for="dict in accident_type_dict" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
              <el-button icon="Refresh" @click="resetQuery">重置</el-button>
            </el-form-item>
          </el-form>
        </el-card>
      </div>
    </transition>

    <!-- 数据表格区域 -->
    <el-card shadow="hover" class="list-card">
      <div class="list-toolbar">
        <span class="list-total">共 {{ total }} 条记录</span>
        <div class="toolbar-actions">
          <el-button type="primary" plain icon="Plus" @click="handleAdd">新增上报</el-button>
          <right-toolbar v-model:show-search="showSearch" @query-table="getList" style="margin-left: 8px;" />
        </div>
      </div>

      <el-table v-loading="loading" :data="accidentList" border>
        <el-table-column label="事故编号" align="center" prop="accidentCode" width="220" :show-overflow-tooltip="true" />
        <el-table-column label="事故名称" align="center" prop="accidentTitle" :show-overflow-tooltip="true" />
        <el-table-column label="事故时间" align="center" prop="accidentTime" width="170" />
        <el-table-column label="事故地点" align="center" prop="accidentLocation" width="160" :show-overflow-tooltip="true" />
        <el-table-column label="等级" align="center" prop="accidentLevel" width="100">
          <template #default="scope">
            <el-tag :type="getLevelTag(scope.row.accidentLevel)">{{ scope.row.accidentLevel }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="类型" align="center" prop="accidentType" width="100" />
        <el-table-column label="状态" align="center" prop="handleStatus" width="100">
          <template #default="scope">
            <el-tag :type="getStatusTag(scope.row.handleStatus)">{{ scope.row.handleStatus }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" fixed="right" align="center" width="280" class-name="small-padding fixed-width">
          <template #default="scope">
            <el-button v-hasPermi="['risk:accident:query']" link type="primary" icon="View" @click="handleView(scope.row)">详情</el-button>
            <el-button v-if="scope.row.handleStatus === '待处理'" v-hasPermi="['risk:accident:handle']" link type="primary" icon="CircleCheck" @click="openHandleDialog(scope.row)">处理</el-button>
            <el-button v-hasPermi="['risk:accident:edit']" link type="primary" icon="Edit" @click="handleUpdate(scope.row)">编辑</el-button>
            <el-button v-hasPermi="['risk:accident:remove']" link type="danger" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

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

    <!-- 近12个月事故统计 -->
    <el-card shadow="hover" class="mt-2">
      <template #header>
        <span class="section-title">近12个月事故统计</span>
      </template>
      <div ref="trendChartRef" class="trend-chart"></div>
    </el-card>

    <!-- 新增/编辑对话框 -->
    <el-dialog v-model="dialog.visible" :title="dialog.title" width="780px" append-to-body @close="closeDialog">
      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="事故时间" prop="accidentTime">
              <el-date-picker v-model="form.accidentTime" type="datetime" placeholder="请选择事故时间" value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="事故地点" prop="accidentLocation">
              <el-input v-model="form.accidentLocation" placeholder="如:XX车间XX工位 / XX园区XX路段" maxlength="200" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="事故等级" prop="accidentLevel">
              <el-select v-model="form.accidentLevel" placeholder="请选择事故等级" style="width: 100%">
                <el-option v-for="dict in accident_level_dict" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="事故类型" prop="accidentType">
              <el-select v-model="form.accidentType" placeholder="请选择事故类型" style="width: 100%">
                <el-option v-for="dict in accident_type_dict" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="事故名称" prop="accidentTitle">
          <el-input v-model="form.accidentTitle" placeholder="如:XX工位机械夹伤事故" maxlength="200" />
        </el-form-item>
        <el-form-item label="涉及人员" prop="participants">
          <el-input v-model="form.participants" placeholder="如:张三(操作工)、李四(班组长)" maxlength="500" />
        </el-form-item>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="死亡人数" prop="deathCount">
              <el-input-number v-model="form.deathCount" :min="0" style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="受伤人数" prop="injuryCount">
              <el-input-number v-model="form.injuryCount" :min="0" style="width: 100%" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="事故经过" prop="accidentDesc">
          <el-input v-model="form.accidentDesc" type="textarea" :rows="4" placeholder="请详细描述事故发生经过(包含时间、地点、事件、后果)" maxlength="2000" show-word-limit />
        </el-form-item>
        <el-form-item label="初步原因" prop="accidentCause">
          <el-input v-model="form.accidentCause" type="textarea" :rows="3" placeholder="初步判断的事故原因,如操作违规、设备故障、环境因素" maxlength="1000" show-word-limit />
        </el-form-item>
        <el-form-item label="上报人" prop="reporterName">
          <el-input v-model="form.reporterName" placeholder="上报人姓名(默认当前登录用户)" maxlength="50" />
        </el-form-item>
        <el-form-item label="现场照片" prop="photoList">
          <el-upload v-model:file-list="photoFileList" :http-request="customUpload" list-type="picture-card" :limit="9" accept=".jpg,.png,.jpeg" :on-success="handleUploadSuccess" :on-error="handleUploadError" :on-exceed="handleExceed" :before-upload="beforeUpload">
            <el-icon><Plus /></el-icon>
          </el-upload>
          <div class="el-upload__tip">最多上传9张,支持 jpg/png/jpeg 格式</div>
        </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 v-model="viewDialog.visible" title="事故详情" width="800px" append-to-body>
      <el-descriptions :column="2" border>
        <el-descriptions-item label="事故编号">{{ viewForm.accidentCode }}</el-descriptions-item>
        <el-descriptions-item label="事故时间">{{ viewForm.accidentTime }}</el-descriptions-item>
        <el-descriptions-item label="事故名称" :span="2">{{ viewForm.accidentTitle }}</el-descriptions-item>
        <el-descriptions-item label="事故地点">{{ viewForm.accidentLocation }}</el-descriptions-item>
        <el-descriptions-item label="事故等级">
          <el-tag :type="getLevelTag(viewForm.accidentLevel)">{{ viewForm.accidentLevel }}</el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="事故类型">{{ viewForm.accidentType }}</el-descriptions-item>
        <el-descriptions-item label="处理状态">
          <el-tag :type="getStatusTag(viewForm.handleStatus)">{{ viewForm.handleStatus }}</el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="上报人">{{ viewForm.reporterName }}</el-descriptions-item>
        <el-descriptions-item label="上报时间">{{ viewForm.reportTime }}</el-descriptions-item>
        <el-descriptions-item label="涉及人员" :span="2">{{ viewForm.participants }}</el-descriptions-item>
        <el-descriptions-item label="死亡人数">{{ viewForm.deathCount }}</el-descriptions-item>
        <el-descriptions-item label="受伤人数">{{ viewForm.injuryCount }}</el-descriptions-item>
        <el-descriptions-item label="经济损失">{{ viewForm.lossAmount }}</el-descriptions-item>
        <el-descriptions-item label="处理人">{{ viewForm.handlerName }}</el-descriptions-item>
        <el-descriptions-item label="事故经过" :span="2">{{ viewForm.accidentDesc }}</el-descriptions-item>
        <el-descriptions-item label="初步原因" :span="2">{{ viewForm.accidentCause }}</el-descriptions-item>
        <el-descriptions-item label="处理措施" :span="2">{{ viewForm.handleMeasures }}</el-descriptions-item>
        <el-descriptions-item label="调查结果" :span="2">{{ viewForm.investigationResult }}</el-descriptions-item>
        <el-descriptions-item label="改进措施" :span="2">{{ viewForm.improvementMeasures }}</el-descriptions-item>
        <el-descriptions-item v-if="viewPhotoList.length > 0" label="现场照片" :span="2">
          <el-image v-for="(img, idx) in viewPhotoList" :key="idx" :src="img" :preview-src-list="viewPhotoList" :initial-index="idx" fit="cover" style="width: 80px; height: 80px; margin-right: 8px; border-radius: 4px" />
        </el-descriptions-item>
        <el-descriptions-item label="备注" :span="2">{{ viewForm.remark }}</el-descriptions-item>
      </el-descriptions>
      <template #footer>
        <el-button @click="viewDialog.visible = false">关 闭</el-button>
      </template>
    </el-dialog>

    <!-- 事故处理弹窗(独立,字段:处理方式/处理意见/责任人/处理期限/附件) -->
    <el-dialog
      v-model="handleDialog.visible"
      :title="handleDialog.title"
      width="640px"
      append-to-body
      :close-on-click-modal="false"
      @close="cancelHandle"
    >
      <el-form ref="handleFormRef" :model="handleForm" :rules="handleRules" label-width="100px">
        <el-form-item label="事故编号">
          <span class="readonly-text">{{ handleForm.accidentCode }}</span>
        </el-form-item>
        <el-form-item label="处理方式" prop="handleResult">
          <el-select v-model="handleForm.handleResult" placeholder="请选择处理方式" style="width: 100%" clearable>
            <el-option v-for="dict in accident_handle_way_dict" :key="dict.value" :label="dict.label" :value="dict.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="处理意见" prop="handleMeasures">
          <el-input
            v-model="handleForm.handleMeasures"
            type="textarea"
            :rows="5"
            placeholder="请详细填写本次事故处理过程、措施与结论..."
            maxlength="2000"
            show-word-limit
          />
        </el-form-item>
        <el-form-item label="责任人" prop="handlerName">
          <el-input v-model="handleForm.handlerName" placeholder="请输入责任人姓名(默认当前登录用户)" maxlength="50" />
        </el-form-item>
        <el-form-item label="处理期限" prop="handleDeadline">
          <el-date-picker
            v-model="handleForm.handleDeadline"
            type="date"
            placeholder="请选择处理期限"
            value-format="YYYY-MM-DD"
            style="width: 100%"
          />
        </el-form-item>
        <el-form-item label="附件上传">
          <el-upload
            v-model:file-list="handleAttachmentFileList"
            :http-request="customHandleAttachmentUpload"
            list-type="text"
            :limit="1"
            :on-success="onHandleAttachmentSuccess"
            :on-error="onHandleAttachmentError"
            :on-exceed="onHandleAttachmentExceed"
            :on-remove="onHandleAttachmentRemove"
            :before-upload="beforeHandleAttachmentUpload"
          >
            <el-button type="primary" plain icon="Upload">点击上传</el-button>
            <template #tip>
              <div class="el-upload__tip">支持任意格式文件,大小不超过 20MB</div>
            </template>
          </el-upload>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="cancelHandle">取 消</el-button>
          <el-button
            v-hasPermi="['risk:accident:handle']"
            type="primary"
            :loading="handleSubmitting"
            @click="submitHandle"
          >提交处理</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup name="Accident" lang="ts">
import { ref, reactive, toRefs, onMounted, onBeforeUnmount, nextTick, getCurrentInstance } from 'vue';
import * as echarts from 'echarts';
import {
  listAccident,
  getAccident,
  addAccident,
  updateAccident,
  delAccident,
  getAccidentStats,
  getAccidentTrend,
  handleAccident
} from '@/api/risk/accident';
import type { RiskAccidentBo, RiskAccidentVo, AccidentStatsVo, AccidentTrendVo } from '@/api/risk/types';
import { FormInstance, UploadFile, UploadRawFile, UploadUserFile } from 'element-plus';
import { UPLOAD_ACTION_URL, getMinioFileUrl, splitFileUrls } from '@/utils/minio';
import { uploadFile } from '@/api/risk/file';
import type { ComponentInternalInstance } from 'vue';
import { CaretTop, CaretBottom, Document, Search, CircleCheck, EditPen } from '@element-plus/icons-vue';

const { proxy } = getCurrentInstance() as ComponentInternalInstance;

interface AccidentForm extends RiskAccidentBo {
  photoList?: string[];
}

const accidentList = ref<RiskAccidentVo[]>([]);
const loading = ref(true);
const showSearch = ref(true);
const total = ref(0);
const queryFormRef = ref<FormInstance>();
const formRef = ref<FormInstance>();
const photoFileList = ref<UploadUserFile[]>([]);
const viewPhotoList = ref<string[]>([]);

// 字典
const {
  risk_accident_level: accident_level_dict,
  risk_accident_type: accident_type_dict,
  risk_accident_status: accident_status_dict,
  risk_accident_handle_way: accident_handle_way_dict
} = toRefs<any>(
  proxy?.useDict(
    'risk_accident_level',
    'risk_accident_type',
    'risk_accident_status',
    'risk_accident_handle_way'
  )
);

// 统计
const stats = ref<AccidentStatsVo>({
  monthTotal: 0,
  lastMonthTotal: 0,
  monthRate: 0,
  investigating: 0,
  lastMonthInvestigating: 0,
  investigatingRate: 0,
  finished: 0,
  lastMonthFinished: 0,
  finishedRate: 0,
  pendingAssess: 0,
  lastMonthPendingAssess: 0,
  pendingAssessRate: 0
});

// 趋势
const trendList = ref<AccidentTrendVo[]>([]);
const trendChartRef = ref<HTMLElement>();
let trendChart: echarts.ECharts | null = null;

const data = reactive<any>({
  form: {
    id: undefined,
    accidentCode: '',
    accidentTitle: '',
    accidentType: '',
    accidentLevel: '',
    accidentLocation: '',
    accidentTime: '',
    accidentCause: '',
    accidentDesc: '',
    deathCount: 0,
    injuryCount: 0,
    lossAmount: 0,
    reporterName: '',
    reportTime: '',
    handleStatus: '待处理' as any,
    participants: '',
    photoList: [] as string[]
  } as any,
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    keyword: '',
    handleStatus: '',
    accidentLevel: '',
    accidentType: ''
  },
  rules: {
    accidentTitle: [{ required: true, message: '事故名称不能为空', trigger: 'blur' }],
    accidentTime: [{ required: true, message: '请选择事故时间', trigger: 'change' }],
    accidentLocation: [{ required: true, message: '请输入事故地点', trigger: 'blur' }],
    accidentLevel: [{ required: true, message: '请选择事故等级', trigger: 'change' }],
    accidentType: [{ required: true, message: '请选择事故类型', trigger: 'change' }],
    accidentDesc: [{ required: true, message: '请输入事故经过', trigger: 'blur' }],
    participants: [{ required: true, message: '请输入涉及人员', trigger: 'blur' }],
    deathCount: [{ required: true, message: '请填写死亡人数', trigger: 'change' }],
    injuryCount: [{ required: true, message: '请填写受伤人数', trigger: 'change' }],
    reporterName: [{ required: true, message: '请输入上报人', trigger: 'blur' }]
  }
});

const { queryParams, form, rules } = toRefs(data);

const dialog = reactive<DialogOption>({ visible: false, title: '' });
const viewDialog = reactive({ visible: false });
const viewForm = ref<any>({});

// 事故处理弹窗(独立,不与新增/编辑表单混用)
const handleDialog = reactive({ visible: false, title: '事故处理' });
const handleSubmitting = ref(false);
const handleForm = ref<any>({
  id: undefined,
  accidentCode: '',
  handleResult: '',
  handleMeasures: '',
  handlerName: '',
  handleDeadline: '',
  handleAttachmentUrl: '',
  handleAttachmentName: ''
});
const handleFormRef = ref<FormInstance>();
const handleAttachmentFileList = ref<UploadUserFile[]>([]);
const handleRules = {
  handleResult: [{ required: true, message: '请选择处理方式', trigger: 'change' }],
  handleMeasures: [{ required: true, message: '请输入处理意见文案', trigger: 'blur' }],
  handlerName: [{ required: true, message: '请输入责任人', trigger: 'blur' }],
  handleDeadline: [{ required: true, message: '请选择处理期限', trigger: 'change' }]
};

const getList = async () => {
  loading.value = true;
  try {
    const res = await listAccident(queryParams.value);
    accidentList.value = res.rows || [];
    total.value = res.total || 0;
  } finally {
    loading.value = false;
  }
};

const loadStats = async () => {
  const res = await getAccidentStats();
  if (res.data) {
    stats.value = res.data;
  }
};

const loadTrend = async () => {
  const res = await getAccidentTrend();
  trendList.value = res.data || [];
  await nextTick();
  renderTrendChart();
};

const renderTrendChart = () => {
  if (!trendChartRef.value) return;
  if (!trendChart) {
    trendChart = echarts.init(trendChartRef.value);
  }
  const months = trendList.value.map((it) => it.month?.slice(2) || '');
  const reportArr = trendList.value.map((it) => it.reportCount || 0);
  const finishedArr = trendList.value.map((it) => it.finishedCount || 0);

  trendChart.setOption({
    tooltip: { trigger: 'axis' },
    legend: {
      data: ['上报表数', '已结束'],
      top: 0,
      icon: 'circle'
    },
    grid: { left: 40, right: 30, top: 40, bottom: 30 },
    xAxis: {
      type: 'category',
      data: months,
      axisLine: { lineStyle: { color: '#e0e0e0' } },
      axisLabel: { color: '#666' }
    },
    yAxis: {
      type: 'value',
      minInterval: 1,
      splitLine: { lineStyle: { type: 'dashed', color: '#eee' } },
      axisLabel: { color: '#666' }
    },
    series: [
      {
        name: '上报表数',
        type: 'bar',
        barWidth: '32%',
        data: reportArr,
        itemStyle: { color: '#409EFF' }
      },
      {
        name: '已结束',
        type: 'bar',
        barWidth: '32%',
        data: finishedArr,
        itemStyle: { color: '#67C23A' }
      }
    ]
  });
};

const handleResize = () => {
  trendChart?.resize();
};

const loadAll = async () => {
  await Promise.all([getList(), loadStats(), loadTrend()]);
};

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

const resetQuery = () => {
  queryFormRef.value?.resetFields();
  queryParams.value.pageNum = 1;
  queryParams.value.keyword = '';
  queryParams.value.handleStatus = '';
  queryParams.value.accidentLevel = '';
  queryParams.value.accidentType = '';
  handleQuery();
};

const handleAdd = () => {
  reset();
  dialog.visible = true;
  dialog.title = '事故上报';
};

const handleUpdate = async (row: RiskAccidentVo) => {
  reset();
  const res = await getAccident(row.id);
  Object.assign(form.value, res.data);
  const photoArr = parsePhotoList(form.value.photoList as any);
  if (photoArr.length > 0) {
    photoFileList.value = photoArr.map((url, idx) => ({
      uid: idx,
      name: `photo-${idx}`,
      status: 'success',
      url
    }));
  }
  dialog.visible = true;
  dialog.title = '编辑事故';
};

const handleView = async (row: RiskAccidentVo) => {
  const res = await getAccident(row.id);
  viewForm.value = res.data;
  const photoArr = parsePhotoList(viewForm.value.photoList as any);
  viewPhotoList.value = photoArr;
  viewDialog.visible = true;
};

// ============ 事故处理(独立弹窗) ============
// 打开处理弹窗:重置表单 → 加载事故详情到只读字段 → 显示弹窗
const openHandleDialog = async (row: RiskAccidentVo) => {
  if (!row || row.handleStatus !== '待处理') {
    proxy?.$modal.msgWarning('只有"待处理"状态的事故才能处理');
    return;
  }
  resetHandleForm();
  const res = await getAccident(row.id);
  const data: any = res.data || {};
  handleForm.value.id = data.id;
  handleForm.value.accidentCode = data.accidentCode || '';
  // 责任人默认当前登录用户名(由后端 LoginHelper.getUsername() 兜底,前端可空)
  handleForm.value.handlerName = data.handlerName || '';
  handleDialog.visible = true;
};

// 提交处理(后端强制将状态置为"归档")
const submitHandle = () => {
  handleFormRef.value?.validate(async (valid: boolean) => {
    if (!valid) return;
    handleSubmitting.value = true;
    try {
      await handleAccident(handleForm.value.id, handleForm.value as RiskAccidentBo);
      proxy?.$modal.msgSuccess('处理成功,事故已归档');
      handleDialog.visible = false;
      await loadAll();
    } finally {
      handleSubmitting.value = false;
    }
  });
};

const cancelHandle = () => {
  handleDialog.visible = false;
  resetHandleForm();
};

const resetHandleForm = () => {
  handleForm.value = {
    id: undefined,
    accidentCode: '',
    handleResult: '',
    handleMeasures: '',
    handlerName: '',
    handleDeadline: '',
    handleAttachmentUrl: '',
    handleAttachmentName: ''
  };
  handleAttachmentFileList.value = [];
  handleFormRef.value?.resetFields();
};

// ============ 处理弹窗附件上传(走 axios baseURL,避免依赖 :action) ============
const customHandleAttachmentUpload = async (options: any) => {
  try {
    const res: any = await uploadFile(options.file);
    if (res && res.code === 200 && res.data) {
      options.onSuccess(res, options.file);
    } else {
      options.onError(new Error(res?.msg || '上传失败'));
    }
  } catch (err: any) {
    options.onError(err);
  }
};

const beforeHandleAttachmentUpload = (file: UploadRawFile) => {
  const isLt20M = file.size / 1024 / 1024 < 20;
  if (!isLt20M) {
    proxy?.$modal.msgError('附件大小不能超过 20MB!');
    return false;
  }
  return true;
};

const onHandleAttachmentSuccess = (response: any, uploadFile: UploadFile) => {
  const url = response?.fileName || response?.data?.fileName || response?.url || response?.data?.url || '';
  uploadFile.url = getMinioFileUrl(url);
  handleForm.value.handleAttachmentUrl = uploadFile.url;
  handleForm.value.handleAttachmentName = uploadFile.name;
  proxy?.$modal.msgSuccess('上传成功');
};

const onHandleAttachmentError = () => {
  proxy?.$modal.msgError('附件上传失败,请重试');
};

const onHandleAttachmentExceed = () => {
  proxy?.$modal.msgWarning('最多只能上传 1 个附件');
};

const onHandleAttachmentRemove = () => {
  handleForm.value.handleAttachmentUrl = '';
  handleForm.value.handleAttachmentName = '';
};

const parsePhotoList = (val: any): string[] => {
  if (!val) return [];
  if (Array.isArray(val)) return val as string[];
  if (typeof val === 'string') {
    const trimmed = val.trim();
    if (!trimmed) return [];
    if (trimmed.startsWith('[')) {
      try {
        const parsed = JSON.parse(trimmed);
        return Array.isArray(parsed) ? parsed : [];
      } catch {
        return splitFileUrls(trimmed);
      }
    }
    return splitFileUrls(trimmed);
  }
  return [];
};

const handleDelete = async (row: RiskAccidentVo) => {
  await proxy?.$modal.confirm('是否确认删除事故编号为 "' + row.accidentCode + '" 的数据项?');
  await delAccident(row.id);
  proxy?.$modal.msgSuccess('删除成功');
  await getList();
};

const submitForm = () => {
  formRef.value?.validate(async (valid: boolean) => {
    if (valid) {
      const uploadedUrls = photoFileList.value
        .filter((f: any) => f.status === 'success')
        .map((f: any) => f.url || getMinioFileUrl(f.response?.fileName || f.response?.data?.fileName));
      form.value.photoList = uploadedUrls.length > 0 ? JSON.stringify(uploadedUrls) : '';

      if (form.value.id) {
        await updateAccident(form.value as RiskAccidentBo);
        proxy?.$modal.msgSuccess('修改成功');
      } else {
        await addAccident(form.value as RiskAccidentBo);
        proxy?.$modal.msgSuccess('上报成功');
      }
      dialog.visible = false;
      await loadAll();
    }
  });
};

const cancel = () => {
  dialog.visible = false;
  reset();
};

const reset = () => {
  form.value = {
    id: undefined,
    accidentCode: '',
    accidentTitle: '',
    accidentType: '',
    accidentLevel: '',
    accidentLocation: '',
    accidentTime: '',
    accidentCause: '',
    accidentDesc: '',
    deathCount: 0,
    injuryCount: 0,
    lossAmount: 0,
    reporterName: '',
    reportTime: '',
    handleStatus: '待处理',
    participants: '',
    photoList: []
  } as any;
  photoFileList.value = [];
  formRef.value?.resetFields();
};

const closeDialog = () => {
  dialog.visible = false;
  reset();
};

const handleUploadSuccess = (response: any, uploadFile: UploadFile) => {
  uploadFile.url = getMinioFileUrl(response.fileName || response.data?.fileName);
  proxy?.$modal.msgSuccess('上传成功');
};

const handleUploadError = () => {
  proxy?.$modal.msgError('上传失败,请重试');
};

const customUpload = async (options: any) => {
  try {
    const res: any = await uploadFile(options.file);
    if (res && res.code === 200 && res.data) {
      options.onSuccess(res, options.file);
    } else {
      options.onError(new Error(res?.msg || '上传失败'));
    }
  } catch (err: any) {
    options.onError(err);
  }
};

const beforeUpload = (file: UploadRawFile) => {
  const isValidType = ['image/jpeg', 'image/png', 'image/jpg'].includes(file.type);
  const isLt10M = file.size / 1024 / 1024 < 10;
  if (!isValidType) {
    proxy?.$modal.msgError('只能上传 jpg/png/jpeg 格式的图片!');
    return false;
  }
  if (!isLt10M) {
    proxy?.$modal.msgError('单张图片大小不能超过 10MB!');
    return false;
  }
  return true;
};

const handleExceed = () => {
  proxy?.$modal.msgWarning('最多只能上传9张图片');
};

const getLevelTag = (level: string): 'primary' | 'success' | 'warning' | 'info' | 'danger' => {
  const map: Record<string, 'primary' | 'success' | 'warning' | 'info' | 'danger'> = {
    特别重大: 'danger',
    重大: 'danger',
    较大: 'warning',
    一般: 'primary'
  };
  return (map[level] || 'info') as any;
};

const getStatusTag = (status: string): 'primary' | 'success' | 'warning' | 'info' | 'danger' => {
  const map: Record<string, 'primary' | 'success' | 'warning' | 'info' | 'danger'> = {
    待处理: 'danger',
    归档: 'success'
  };
  return (map[status] || 'info') as any;
};

onMounted(async () => {
  await loadAll();
  window.addEventListener('resize', handleResize);
});

onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize);
  trendChart?.dispose();
  trendChart = null;
});
</script>

<style scoped lang="scss">
.accident-page {
  padding: 16px;
  height: 100%;
  overflow-y: auto;
  box-sizing: border-box;
}
.stat-card {
  border-radius: 8px;
  :deep(.el-card__body) { padding: 20px; }
}
.stat-card-content {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.stat-info { flex: 1; }
.stat-title {
  font-size: 13px;
  color: #909399;
  margin-bottom: 8px;
  white-space: nowrap;
}
.stat-value {
  font-size: 28px;
  font-weight: 700;
  color: #303133;
  line-height: 1.2;
  margin-bottom: 8px;
}
.stat-extra {
  font-size: 12px;
  color: #909399;
  display: flex;
  align-items: center;
  gap: 2px;
}
.stat-extra-up { color: #f56c6c; }
.stat-extra-down { color: #67c23a; }
.stat-icon {
  width: 48px;
  height: 48px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  color: #fff;
}
.stat-icon-blue { background: #ecf5ff; color: #409EFF; }
.stat-icon-orange { background: #fdf6ec; color: #E6A23C; }
.stat-icon-green { background: #f0f9eb; color: #67C23A; }
.stat-icon-red { background: #fef0f0; color: #F56C6C; }
.section-title { font-size: 16px; font-weight: 600; color: #303133; }
.mb-2 { margin-bottom: 8px; }
.mt-2 { margin-top: 8px; }
.trend-chart { width: 100%; height: 360px; }
.el-upload__tip { font-size: 12px; color: #909399; line-height: 1.5; margin-top: 4px; }
.list-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}
.list-total {
  font-size: 13px;
  color: #606266;
}
.toolbar-actions {
  display: flex;
  align-items: center;
}
/* ============ 事故处理弹窗专用样式 ============ */
.readonly-text {
  display: inline-block;
  width: 100%;
  padding: 0 12px;
  line-height: 32px;
  background: #f5f7fa;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  color: #606266;
  font-size: 14px;
}
.upload-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 4px;
}
.upload-tip {
  font-size: 12px;
  color: #909399;
  line-height: 1.5;
}
</style>