<!-- 预警报告上传 -->
<template>
  <div class="app-container warning-report-page" v-loading="pageLoading">
    <el-card shadow="never" class="page-card header-card">
      <div class="page-header">
        <div>
          <div class="page-title">预警报告上传</div>
          <div class="page-subtitle">提供预警报告附件上传功能，结合设备报警曲线、预警位置和周边要素分析，描述预警发生的具体内容</div>
        </div>
      </div>
    </el-card>

    <el-card shadow="never" class="page-card">
      <el-form :model="queryParams" :inline="true">
        <el-form-item label="预警名称">
          <el-input
            v-model="queryParams.warningName"
            placeholder="请输入预警名称"
            clearable
            style="width: 220px"
            @keyup.enter="loadWarningOptions"
          />
        </el-form-item>
        <el-form-item label="预警类型">
          <el-select v-model="queryParams.warningType" clearable placeholder="请选择预警类型" style="width: 180px">
            <el-option
              v-for="item in warningTypeOptions"
              :key="item.dictValue"
              :label="item.dictLabel"
              :value="item.dictValue"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="预警级别">
          <el-select v-model="queryParams.warningLevel" clearable placeholder="请选择预警级别" style="width: 180px">
            <el-option
              v-for="item in warningLevelOptions"
              :key="item.dictValue"
              :label="item.dictLabel"
              :value="item.dictValue"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="选择预警">
          <el-select
            v-model="selectedWarningId"
            filterable
            clearable
            placeholder="请选择一条预警"
            style="width: 360px"
            @change="handleWarningChange"
          >
            <el-option
              v-for="item in warningOptions"
              :key="item.warningId"
              :label="item.warningName"
              :value="item.warningId"
            >
              <div class="warning-option">
                <span>{{ item.warningName }}</span>
                <el-tag :type="getLevelTagType(item.warningLevel)">{{ item.warningLevelText }}</el-tag>
              </div>
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="Search" @click="loadWarningOptions">查询</el-button>
          <el-button icon="Refresh" @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <div class="report-container">
      <div class="left-panel">
        <el-card shadow="never" class="section-card">
          <template #header>
            <div class="section-title">报告上传</div>
          </template>

          <div
            class="upload-area"
            :class="{ 'drag-over': isDragOver }"
            @dragover.prevent="isDragOver = true"
            @dragleave.prevent="isDragOver = false"
            @drop.prevent="handleDrop"
          >
            <el-icon class="upload-icon"><UploadFilled /></el-icon>
            <div class="upload-text">
              <div class="primary-text">点击或拖拽文件至此区域</div>
              <div class="support-text">支持 `.pdf .doc .docx .zip`，单个文件不超过 20MB</div>
            </div>
            <el-upload
              ref="uploadRef"
              class="inline-upload"
              action="#"
              :auto-upload="false"
              :show-file-list="false"
              :on-change="handleFileChange"
              :limit="1"
              accept=".pdf,.doc,.docx,.zip"
            >
              <el-button type="primary">选择文件</el-button>
            </el-upload>
          </div>

          <div v-if="uploadedFile" class="file-info">
            <div class="file-item">
              <el-icon><Document /></el-icon>
              <span class="file-name">{{ uploadedFile.name }}</span>
              <span class="file-size">{{ formatFileSize(uploadedFile.size) }}</span>
              <el-icon class="remove-file" @click="removeFile"><CircleCloseFilled /></el-icon>
            </div>
          </div>

          <div class="report-description">
            <div class="field-title">报告摘要</div>
            <el-input
              v-model="reportSummary"
              type="textarea"
              :rows="5"
              maxlength="500"
              show-word-limit
              placeholder="请输入报告摘要、诊断结论或补充说明"
            />
          </div>

          <el-button
            type="success"
            class="submit-btn"
            :disabled="!selectedWarningId || !uploadedFile"
            :loading="submitLoading"
            @click="submitReport"
          >
            <el-icon><Upload /></el-icon>
            提交预警报告
          </el-button>
        </el-card>

        <el-card shadow="never" class="section-card">
          <template #header>
            <div class="section-title">预警基础信息</div>
          </template>
          <el-empty v-if="!warningDetail.basicInfo" description="请先选择预警" />
          <el-descriptions v-else :column="1" border size="small">
            <el-descriptions-item label="预警编号">{{ currentBasicInfo.warningNo || "-" }}</el-descriptions-item>
            <el-descriptions-item label="预警名称">{{ currentBasicInfo.warningName || "-" }}</el-descriptions-item>
            <el-descriptions-item label="预警类型">{{ currentBasicInfo.warningTypeText || "-" }}</el-descriptions-item>
            <el-descriptions-item label="预警级别">{{ currentBasicInfo.warningLevelText || "-" }}</el-descriptions-item>
            <el-descriptions-item label="预警位置">{{ currentBasicInfo.location || "-" }}</el-descriptions-item>
            <el-descriptions-item label="发布人">{{ currentBasicInfo.publisher || "-" }}</el-descriptions-item>
            <el-descriptions-item label="发布时间">{{ currentBasicInfo.publishTime || "-" }}</el-descriptions-item>
            <el-descriptions-item label="权属单位">{{ currentBasicInfo.ownershipUnit || "-" }}</el-descriptions-item>
            <el-descriptions-item label="状态">
              <el-tag :type="getStatusTagType(currentBasicInfo.status)">
                {{ getStatusText(currentBasicInfo.status) }}
              </el-tag>
            </el-descriptions-item>
          </el-descriptions>
        </el-card>

        <el-card shadow="never" class="section-card">
          <template #header>
            <div class="section-title">已有附件</div>
          </template>
          <el-empty v-if="!attachmentList.length" description="暂无已上传附件" />
          <div v-else class="attachment-list">
            <div v-for="(item, index) in attachmentList" :key="index" class="attachment-item">
              <el-icon><Document /></el-icon>
              <el-link :href="buildAttachmentUrl(item.attachmentUrl)" target="_blank" type="primary" class="attachment-name">
                {{ item.fileName || item.originalName || item.attachmentName || "附件" }}
              </el-link>
              <span class="attachment-size">{{ item.attachmentSize ? formatFileSize(item.attachmentSize) : "" }}</span>
              <span class="attachment-time">{{ item.createTime || item.uploadTime || "-" }}</span>
            </div>
          </div>
        </el-card>
      </div>

      <div class="right-panel">
        <el-card shadow="never" class="section-card">
          <el-tabs v-model="activeTab" class="analysis-tabs">
            <el-tab-pane label="设备报警曲线" name="curve">
              <div ref="curveChartRef" class="curve-chart"></div>
              <el-alert
                :title="curveSummary.title"
                :description="curveSummary.description"
                type="warning"
                :closable="false"
              />
            </el-tab-pane>

            <el-tab-pane label="预警位置情况" name="location">
              <div class="location-pane">
                <div class="gis-card">
                  <div class="gis-title">GIS定位信息</div>
                  <div class="gis-point">
                    <div class="point-badge">预警点</div>
                    <div class="point-coord">
                      经度：{{ gisInfo.longitude || "-" }} / 纬度：{{ gisInfo.latitude || "-" }}
                    </div>
                  </div>
                </div>
                <el-descriptions :column="1" border size="small">
                  <el-descriptions-item label="位置描述">{{ currentBasicInfo.location || "-" }}</el-descriptions-item>
                  <el-descriptions-item label="权属单位">{{ currentBasicInfo.ownershipUnit || "-" }}</el-descriptions-item>
                  <el-descriptions-item label="处置人">{{ currentBasicInfo.handler || "-" }}</el-descriptions-item>
                  <el-descriptions-item label="状态">{{ currentBasicInfo.statusText || currentBasicInfo.status || "-" }}</el-descriptions-item>
                </el-descriptions>
              </div>
            </el-tab-pane>

            <el-tab-pane label="周边要素分析" name="environment">
              <div class="factors-grid">
                <div class="factor-card">
                  <div class="factor-label">关联报警</div>
                  <div class="factor-value">{{ alarmList.length }}</div>
                  <div class="factor-desc">报警曲线分析样本数</div>
                </div>
                <div class="factor-card">
                  <div class="factor-label">处置记录</div>
                  <div class="factor-value">{{ disposalHistory.length }}</div>
                  <div class="factor-desc">流程处置和跟踪情况</div>
                </div>
                <div class="factor-card">
                  <div class="factor-label">历史附件</div>
                  <div class="factor-value">{{ attachmentList.length }}</div>
                  <div class="factor-desc">已上传的资料与报告数量</div>
                </div>
                <div class="factor-card">
                  <div class="factor-label">电子存档</div>
                  <div class="factor-value">{{ hasArchive ? "已生成" : "未生成" }}</div>
                  <div class="factor-desc">预警归档与存档状态</div>
                </div>
              </div>
              <el-card shadow="never" class="analysis-text-card">
                <template #header>
                  <span>综合周边要素结论</span>
                </template>
                <p>{{ environmentConclusion }}</p>
              </el-card>
            </el-tab-pane>
          </el-tabs>

          <div class="warning-description">
            <div class="desc-header">
              <el-icon><InfoFilled /></el-icon>
              <h4>预警具体内容描述</h4>
            </div>
            <div class="desc-content">
              <p>{{ currentBasicInfo.warningContent || "暂无预警内容描述" }}</p>
              <p v-if="reportSummary"><strong>报告补充摘要：</strong>{{ reportSummary }}</p>
            </div>
          </div>
        </el-card>
      </div>
    </div>
  </div>
</template>

<script setup>
import { computed, nextTick, onBeforeUnmount, onMounted, ref } from "vue";
import { ElMessage } from "element-plus";
import { CircleCloseFilled, Document, InfoFilled, Upload, UploadFilled } from "@element-plus/icons-vue";
import * as echarts from "echarts";
import {
  getAlertTypeDictionaryData,
  getLinkedAlarmListData,
  getWarningDetailData,
  getdbyjlistData,
  updateYjxxData
} from "@/api/smxyjldczxt/yjxxfb/yjfb.js";

const pageLoading = ref(false);
const submitLoading = ref(false);
const isDragOver = ref(false);
const uploadedFile = ref(null);
const reportSummary = ref("");
const activeTab = ref("curve");
const uploadRef = ref();
const curveChartRef = ref(null);
let curveChart = null;

const warningTypeOptions = ref([]);
const warningLevelOptions = ref([]);
const warningStatusOptions = ref([]);
const warningOptions = ref([]);
const selectedWarningId = ref("");
const warningDetail = ref({});
const minioBaseUrl = (import.meta.env.VITE_APP_MINIO_BASE_URL || "").trim();

const queryParams = ref({
  warningName: "",
  warningType: "",
  warningLevel: "",
  status: ""
});

const warningTypeLabelMap = computed(() => {
  return warningTypeOptions.value.reduce((acc, item) => {
    acc[item.dictValue] = item.dictLabel;
    return acc;
  }, {});
});

const warningLevelLabelMap = computed(() => {
  return warningLevelOptions.value.reduce((acc, item) => {
    acc[item.dictValue] = item.dictLabel;
    return acc;
  }, {});
});

const warningStatusLabelMap = computed(() => {
  return warningStatusOptions.value.reduce((acc, item) => {
    acc[item.dictValue] = item.dictLabel;
    return acc;
  }, {});
});

const currentBasicInfo = computed(() => {
  const basic = warningDetail.value.basicInfo || {};
  return {
    warningId: basic.warningId || basic.warning_id || "",
    warningNo: basic.warningNo || basic.warning_no || "",
    warningName: basic.warningName || basic.warning_name || "",
    warningType: basic.warningType || basic.warning_type || "",
    warningTypeText: warningTypeLabelMap.value[basic.warningType || basic.warning_type] || basic.warningType || basic.warning_type || "-",
    warningLevel: basic.warningLevel || basic.warning_level || "",
    warningLevelText: warningLevelLabelMap.value[basic.warningLevel || basic.warning_level] || basic.warningLevel || basic.warning_level || "-",
    location: basic.location || "",
    ownershipUnit: basic.ownershipUnit || basic.ownership_unit || "",
    publisher: basic.publisher || "",
    publishTime: basic.publishTime || basic.publish_time || "",
    handler: basic.handler || "",
    status: basic.status || "",
    statusText: warningStatusLabelMap.value[basic.status] || basic.statusText || basic.status || "",
    longitude: basic.longitude || "",
    latitude: basic.latitude || "",
    warningContent: basic.warningContent || basic.warning_content || "",
    warningSpecial: basic.warningSpecial || basic.warning_special || "",
    remark: basic.remark || ""
  };
});

const alarmList = computed(() => warningDetail.value.alarmList || []);
const attachmentList = computed(() => warningDetail.value.attachmentList || []);
const disposalHistory = computed(() => warningDetail.value.disposalHistory || []);
const gisInfo = computed(() => warningDetail.value.gisLocation || {});
const hasArchive = computed(() => !!warningDetail.value.electronicArchive);

const curveSummary = computed(() => {
  if (!alarmList.value.length) {
    return {
      title: "曲线分析",
      description: "当前预警暂无关联报警数据，无法生成设备报警曲线分析。"
    };
  }
  const maxAlarm = [...alarmList.value].sort((a, b) => Number(b.actual_value || b.actualValue || 0) - Number(a.actual_value || a.actualValue || 0))[0];
  return {
    title: "曲线分析",
    description: `当前共关联 ${alarmList.value.length} 条报警记录，峰值实际值为 ${maxAlarm?.actual_value || maxAlarm?.actualValue || "-"}，建议结合预警附件与现场情况形成完整书面报告。`
  };
});

const environmentConclusion = computed(() => {
  if (!warningDetail.value.basicInfo) {
    return "请选择预警后查看周边要素分析结论。";
  }
  return `本次预警“${currentBasicInfo.value.warningName || "-"}”当前包含 ${alarmList.value.length} 条关联报警、${disposalHistory.value.length} 条处置记录、${attachmentList.value.length} 份附件资料。结合预警位置“${currentBasicInfo.value.location || "-"}”与电子存档情况，建议在上传报告时补充现场核查结论、报警峰值说明和后续处置建议。`;
});

function getLevelTagType(level) {
  return {
    "0": "danger",
    "1": "danger",
    "2": "warning",
    "3": "success",
    "4": "info"
  }[level] || "info";
}

function getStatusText(status) {
  return warningStatusLabelMap.value[status] || status || "-";
}

function getStatusTagType(status) {
  return {
    DRAFT: "info",
    PENDING: "warning",
    PROCESSING: "warning",
    RELEASED: "success",
    HANDLED: "success",
    CLOSED: "info"
  }[status] || "info";
}

function validateFile(file) {
  const allowExt = [".pdf", ".doc", ".docx", ".zip"];
  const lowerName = file.name.toLowerCase();
  const extOk = allowExt.some((ext) => lowerName.endsWith(ext));
  if (!extOk) {
    ElMessage.error("仅支持 .pdf、.doc、.docx、.zip 格式");
    return false;
  }
  if (file.size > 20 * 1024 * 1024) {
    ElMessage.error("文件大小不能超过20MB");
    return false;
  }
  return true;
}

function handleFileChange(file) {
  if (!file?.raw || !validateFile(file.raw)) {
    return;
  }
  uploadedFile.value = file.raw;
}

function handleDrop(event) {
  isDragOver.value = false;
  const file = event.dataTransfer.files[0];
  if (file && validateFile(file)) {
    uploadedFile.value = file;
  }
}

function removeFile() {
  uploadedFile.value = null;
  uploadRef.value?.clearFiles?.();
}

function formatFileSize(bytes) {
  if (!bytes) return "0 B";
  const units = ["B", "KB", "MB", "GB"];
  const index = Math.floor(Math.log(bytes) / Math.log(1024));
  return `${(bytes / 1024 ** index).toFixed(2)} ${units[index]}`;
}

function buildAttachmentUrl(path) {
  if (!path) return "";
  if (/^https?:\/\//i.test(path)) {
    return path;
  }
  const base = minioBaseUrl.endsWith("/") ? minioBaseUrl : `${minioBaseUrl}/`;
  return `${base}${String(path).replace(/^\/+/, "")}`;
}

function normalizeWarningRow(item) {
  const warningId = item.warningId || item.warning_id;
  const warningLevel = item.warningLevel || item.warning_level;
  return {
    warningId,
    warningName: item.warningName || item.warning_name,
    warningType: item.warningType || item.warning_type,
    warningLevel,
    warningLevelText: warningLevelLabelMap.value[warningLevel] || warningLevel
  };
}

async function loadDicts() {
  const [typeRes, levelRes, statusRes] = await Promise.all([
    getAlertTypeDictionaryData({ dictType: "alert_type" }),
    getAlertTypeDictionaryData({ dictType: "alert_level" }),
    getAlertTypeDictionaryData({ dictType: "pre_alarm_status" })
  ]);
  warningTypeOptions.value = typeRes.rows || [];
  warningLevelOptions.value = levelRes.rows || [];
  warningStatusOptions.value = statusRes.rows || [];
}

async function loadWarningOptions() {
  pageLoading.value = true;
  try {
    const res = await getdbyjlistData({
      pageNum: 1,
      pageSize: 200,
      warningName: queryParams.value.warningName || undefined,
      warningType: queryParams.value.warningType || undefined,
      warningLevel: queryParams.value.warningLevel || undefined,
      status: queryParams.value.status || undefined
    });
    warningOptions.value = (res.data?.records || []).map(normalizeWarningRow);
    if (!selectedWarningId.value && warningOptions.value.length) {
      selectedWarningId.value = warningOptions.value[0].warningId;
      await loadWarningDetail(selectedWarningId.value);
    } else if (selectedWarningId.value && !warningOptions.value.some((item) => item.warningId === selectedWarningId.value)) {
      selectedWarningId.value = "";
      warningDetail.value = {};
      renderCurveChart();
    }
  } finally {
    pageLoading.value = false;
  }
}

async function loadWarningDetail(warningId) {
  if (!warningId) {
    warningDetail.value = {};
    renderCurveChart();
    return;
  }
  pageLoading.value = true;
  try {
    const res = await getWarningDetailData(warningId);
    warningDetail.value = res.data || {};
    await nextTick();
    renderCurveChart();
  } finally {
    pageLoading.value = false;
  }
}

async function handleWarningChange(value) {
  await loadWarningDetail(value);
}

function buildChartData() {
  const alarms = [...alarmList.value].sort((a, b) => String(a.alarm_time || a.alarmTime || "").localeCompare(String(b.alarm_time || b.alarmTime || "")));
  return {
    xData: alarms.map((item) => String(item.alarm_time || item.alarmTime || "").slice(5, 16) || "-"),
    actualData: alarms.map((item) => Number(item.actual_value || item.actualValue || 0)),
    thresholdData: alarms.map((item) => {
      const raw = item.warning_value || item.warningValue || "";
      const numeric = String(raw).match(/-?\d+(\.\d+)?/);
      return numeric ? Number(numeric[0]) : null;
    })
  };
}

function renderCurveChart() {
  if (!curveChartRef.value) return;
  if (!curveChart) {
    curveChart = echarts.init(curveChartRef.value);
    window.addEventListener("resize", resizeChart);
  }
  const chartData = buildChartData();
  curveChart.setOption({
    tooltip: { trigger: "axis" },
    legend: { top: 0, data: ["实际值", "预警阈值"] },
    grid: { left: 40, right: 20, top: 36, bottom: 30, containLabel: true },
    xAxis: {
      type: "category",
      data: chartData.xData.length ? chartData.xData : ["暂无数据"]
    },
    yAxis: {
      type: "value",
      name: "数值"
    },
    series: [
      {
        name: "实际值",
        type: "line",
        smooth: true,
        data: chartData.actualData.length ? chartData.actualData : [0],
        lineStyle: { color: "#e6a23c", width: 2 },
        areaStyle: { color: "rgba(230,162,60,0.12)" }
      },
      {
        name: "预警阈值",
        type: "line",
        smooth: true,
        data: chartData.thresholdData.length ? chartData.thresholdData : [0],
        lineStyle: { color: "#f56c6c", type: "dashed", width: 2 }
      }
    ]
  });
}

function resizeChart() {
  curveChart?.resize();
}

async function submitReport() {
  if (!selectedWarningId.value) {
    ElMessage.warning("请先选择预警");
    return;
  }
  if (!uploadedFile.value) {
    ElMessage.warning("请先选择报告文件");
    return;
  }

  submitLoading.value = true;
  try {
    const linkedRes = await getLinkedAlarmListData(selectedWarningId.value);
    const alarmIds = (linkedRes.data || []).map((item) => item.alarmId || item.alarm_id).filter(Boolean);
    const payload = {
      warning: {
        warningId: currentBasicInfo.value.warningId,
        warningNo: currentBasicInfo.value.warningNo,
        warningName: currentBasicInfo.value.warningName,
        warningType: currentBasicInfo.value.warningType,
        warningLevel: currentBasicInfo.value.warningLevel,
        warningSpecial: currentBasicInfo.value.warningSpecial,
        location: currentBasicInfo.value.location,
        longitude: currentBasicInfo.value.longitude,
        latitude: currentBasicInfo.value.latitude,
        ownershipUnit: currentBasicInfo.value.ownershipUnit,
        publisher: currentBasicInfo.value.publisher,
        publishTime: currentBasicInfo.value.publishTime,
        handler: currentBasicInfo.value.handler,
        status: currentBasicInfo.value.status,
        warningContent: currentBasicInfo.value.warningContent,
        remark: reportSummary.value
          ? [currentBasicInfo.value.remark, `报告摘要：${reportSummary.value}`].filter(Boolean).join("\n")
          : currentBasicInfo.value.remark
      },
      alarmIds,
      files: [uploadedFile.value]
    };
    const res = await updateYjxxData(payload);
    if (res.code !== 200) {
      ElMessage.error(res.msg || "报告上传失败");
      return;
    }
    ElMessage.success("预警报告上传成功");
    removeFile();
    reportSummary.value = "";
    await loadWarningDetail(selectedWarningId.value);
  } finally {
    submitLoading.value = false;
  }
}

function resetQuery() {
  queryParams.value = {
    warningName: "",
    warningType: "",
    warningLevel: "",
    status: ""
  };
  selectedWarningId.value = "";
  warningDetail.value = {};
  loadWarningOptions();
}

onMounted(async () => {
  await loadDicts();
  await loadWarningOptions();
});

onBeforeUnmount(() => {
  window.removeEventListener("resize", resizeChart);
  curveChart?.dispose();
  curveChart = null;
});
</script>

<style scoped>
.warning-report-page {
  background: #f5f7fb;
}

.page-card {
  border-radius: 16px;
  margin-bottom: 16px;
}

.header-card {
  background: linear-gradient(135deg, #eff6ff, #f8fbff);
  border: 1px solid #dbeafe;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
}

.page-title {
  font-size: 22px;
  font-weight: 700;
  color: #1e3a8a;
}

.page-subtitle {
  margin-top: 8px;
  font-size: 13px;
  color: #64748b;
}

.warning-option {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.report-container {
  display: grid;
  grid-template-columns: 360px minmax(0, 1fr);
  gap: 16px;
}

.section-card {
  border-radius: 16px;
  margin-bottom: 16px;
}

.section-title {
  font-size: 16px;
  font-weight: 600;
  color: #1f2937;
}

.upload-area {
  border: 2px dashed #dcdfe6;
  border-radius: 12px;
  padding: 28px 16px;
  text-align: center;
  transition: all 0.2s ease;
  background: #fafafa;
}

.upload-area.drag-over {
  border-color: #409eff;
  background: #ecf5ff;
}

.upload-icon {
  font-size: 46px;
  color: #909399;
  margin-bottom: 10px;
}

.upload-text {
  margin-bottom: 14px;
}

.primary-text {
  font-size: 14px;
  color: #374151;
}

.support-text {
  margin-top: 6px;
  font-size: 12px;
  color: #9ca3af;
}

.file-info,
.attachment-list {
  margin-top: 16px;
}

.file-item,
.attachment-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-radius: 10px;
  background: #f8fafc;
  border: 1px solid #edf2f7;
}

.attachment-item + .attachment-item {
  margin-top: 8px;
}

.file-name,
.attachment-name {
  flex: 1;
  font-size: 13px;
  color: #303133;
}

.file-size,
.attachment-time {
  font-size: 12px;
  color: #909399;
}

.remove-file {
  color: #f56c6c;
  cursor: pointer;
  font-size: 16px;
}

.report-description {
  margin-top: 20px;
}

.field-title {
  margin-bottom: 10px;
  font-size: 14px;
  font-weight: 600;
  color: #374151;
}

.submit-btn {
  width: 100%;
  margin-top: 16px;
}

.curve-chart {
  width: 100%;
  height: 280px;
  margin-bottom: 16px;
}

.location-pane {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}

.gis-card {
  min-height: 180px;
  padding: 18px;
  border-radius: 14px;
  background: linear-gradient(135deg, #eef6ff, #f8fbff);
  border: 1px solid #dbeafe;
}

.gis-title {
  font-size: 15px;
  font-weight: 600;
  color: #1d4ed8;
}

.gis-point {
  margin-top: 28px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.point-badge {
  width: 76px;
  text-align: center;
  padding: 6px 0;
  border-radius: 999px;
  background: #ef4444;
  color: #fff;
  font-size: 12px;
}

.point-coord {
  font-size: 14px;
  color: #374151;
}

.factors-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
  margin-bottom: 16px;
}

.factor-card {
  padding: 16px;
  border-radius: 14px;
  background: #f8fafc;
  border: 1px solid #edf2f7;
}

.factor-label {
  font-size: 13px;
  color: #64748b;
}

.factor-value {
  margin: 10px 0 6px;
  font-size: 24px;
  font-weight: 700;
  color: #111827;
}

.factor-desc {
  font-size: 12px;
  color: #94a3b8;
}

.analysis-text-card {
  margin-top: 8px;
}

.warning-description {
  margin-top: 20px;
  background: #fef9e6;
  border-left: 4px solid #e6a23c;
  border-radius: 12px;
  padding: 16px 20px;
}

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

.desc-header h4 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #e6a23c;
}

.desc-content {
  font-size: 14px;
  color: #303133;
  line-height: 1.8;
}

.desc-content p {
  margin: 0 0 8px;
}

@media (max-width: 1200px) {
  .report-container {
    grid-template-columns: 1fr;
  }

  .factors-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 768px) {
  .location-pane,
  .factors-grid {
    grid-template-columns: 1fr;
  }
}
</style>
