<template>
  <div class="page ctms-page-shell page--flush">
    <template v-if="study.currentStudy">
      <div class="main-content-flat unified-shell">
        <div class="filter-container unified-action-bar bar--flush">
          <div class="filter-left">
            <el-form :inline="true" :model="filters" class="filter-form">
              <div class="filter-item filter-field">
                <span class="filter-label">问题分类</span>
                <el-select v-model="filters.category" clearable placeholder="请选择" class="filter-select">
                  <el-option label="全部" value="" />
                  <el-option v-for="item in categoryOptions" :key="item" :label="item" :value="item" />
                </el-select>
              </div>
              <div class="filter-item filter-field">
                <span class="filter-label">状态</span>
                <el-select v-model="filters.status" clearable placeholder="请选择" class="filter-select">
                  <el-option label="全部" value="" />
                  <el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
              </div>
              <div class="filter-item filter-field">
                <span class="filter-label">是否超期</span>
                <el-select v-model="filters.overdue" clearable placeholder="请选择" class="filter-select">
                  <el-option label="全部" value="" />
                  <el-option label="是" value="YES" />
                  <el-option label="否" value="NO" />
                </el-select>
              </div>
              <div class="filter-actions">
                <el-button type="primary" @click="handleSearch">{{ TEXT.common.actions.search }}</el-button>
                <el-button link type="info" @click="handleReset">{{ TEXT.common.actions.reset }}</el-button>
              </div>
            </el-form>
          </div>

          <div class="toolbar-right">
            <el-button type="primary" @click="openCreateDialog">新建</el-button>
            <el-upload
              ref="importUploadRef"
              :auto-upload="false"
              :show-file-list="false"
              accept=".xlsx,.csv"
              :on-change="onImportChange"
              :disabled="importing"
            >
              <el-button :loading="importing">导入</el-button>
            </el-upload>
            <el-button :loading="exporting" @click="handleExportExcel">导出Excel</el-button>
          </div>
        </div>

        <div class="unified-section table-section section--flush">
          <el-table
            class="issue-table"
            :data="tableRows"
            style="width: 100%"
            v-loading="loading"
            :fit="true"
            :span-method="tableSpanMethod"
            :row-class-name="tableRowClassName"
          >
            <el-table-column label="问题编号" min-width="130">
              <template #default="{ row }">
                <div v-if="isDescRow(row)" class="issue-desc">问题描述：{{ row.description || TEXT.common.fallback }}</div>
                <div v-else class="issue-no">{{ row.issue_no }}</div>
              </template>
            </el-table-column>
            <el-table-column prop="open_duration" label="开放时长" min-width="130">
              <template #default="{ row }">{{ isDescRow(row) ? "" : row.open_duration }}</template>
            </el-table-column>
            <el-table-column prop="category" label="问题分类" min-width="130">
              <template #default="{ row }">{{ isDescRow(row) ? "" : row.category }}</template>
            </el-table-column>
            <el-table-column prop="subject_code" label="受试者" min-width="120">
              <template #default="{ row }">{{ isDescRow(row) ? "" : row.subject_code || TEXT.common.fallback }}</template>
            </el-table-column>
            <el-table-column prop="monitor_item" label="监查项" min-width="130" show-overflow-tooltip>
              <template #default="{ row }">{{ isDescRow(row) ? "" : row.monitor_item || TEXT.common.fallback }}</template>
            </el-table-column>
            <el-table-column prop="monitor_type" label="监查类型" min-width="130">
              <template #default="{ row }">{{ isDescRow(row) ? "" : row.monitor_type || TEXT.common.fallback }}</template>
            </el-table-column>
            <el-table-column label="进度" min-width="120">
              <template #default="{ row }">
                <div v-if="!isDescRow(row)" class="progress-cell">
                  <span class="progress-dot" :class="`dot-${String(row.status).toLowerCase()}`"></span>
                  <span>{{ row.progress }}</span>
                </div>
              </template>
            </el-table-column>
            <el-table-column label="操作" min-width="150" align="center">
              <template #default="{ row }">
                <template v-if="!isDescRow(row)">
                  <div class="action-cell">
                    <el-button class="action-btn" link type="primary" size="small" @click="openViewDialog(row)">查看</el-button>
                    <el-button class="action-btn" link type="primary" size="small" @click="openEditDialog(row)">编辑</el-button>
                    <el-button class="action-btn" link type="danger" size="small" @click="removeIssue(row)">删除</el-button>
                  </div>
                </template>
              </template>
            </el-table-column>
            <template #empty>
              <div v-if="!loading" class="issue-table-empty">暂无监查访视问题</div>
            </template>
          </el-table>

          <div class="pagination-wrap" v-if="filteredItems.length > 0">
            <el-pagination
              v-model:current-page="pagination.page"
              v-model:page-size="pagination.pageSize"
              :page-sizes="[5, 10, 20]"
              :total="filteredItems.length"
              layout="prev, pager, next, sizes, total"
              small
            />
          </div>
        </div>
      </div>

      <el-drawer
        v-if="formDialogVisible"
        v-model="formDialogVisible"
        direction="rtl"
        size="580px"
        :close-on-click-modal="false"
        :show-close="false"
        class="issue-editor-drawer"
      >
        <template #header>
          <div class="editor-header">
            <div class="editor-title">{{ formMode === "create" ? "新建监查访视问题" : "编辑监查访视问题" }}</div>
            <div class="editor-subtitle">
              {{ formMode === "create" ? "记录监查发现问题与后续处理计划" : "更新问题状态、处理措施与时间节点" }}
            </div>
          </div>
        </template>

        <el-form ref="createFormRef" :model="createForm" :rules="createRules" label-position="top" class="issue-editor-form">
          <div class="editor-group">
            <div class="editor-group-title">
              <span class="group-dot group-dot-basic"></span>
              基础信息
            </div>
            <el-row :gutter="14">
              <el-col :span="12">
                <el-form-item label="问题编号">
                  <el-input v-model="createForm.issue_no" :placeholder="formMode === 'create' ? '可选，不填自动生成' : '请输入问题编号'" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="问题来源" prop="source">
                  <el-select v-model="createForm.source" class="dialog-select" placeholder="请选择">
                    <el-option v-for="item in sourceOptions" :key="item" :label="item" :value="item" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="监查类型">
                  <el-select v-model="createForm.monitor_type" class="dialog-select" placeholder="请选择">
                    <el-option v-for="item in monitorTypeOptions" :key="item" :label="item" :value="item" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="监查项">
                  <el-input v-model="createForm.monitor_item" placeholder="请输入" />
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="问题分类" prop="category">
                  <el-input v-model="createForm.category" placeholder="请输入" />
                </el-form-item>
              </el-col>
            </el-row>
          </div>

          <div class="editor-group">
            <div class="editor-group-title">
              <span class="group-dot group-dot-issue"></span>
              问题信息
            </div>
            <el-row :gutter="14">
              <el-col :span="24">
                <el-form-item label="建议措施">
                  <el-input v-model="createForm.recommendation" type="textarea" :rows="2" placeholder="请输入" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="受试者">
                  <el-input v-model="createForm.subject_name" placeholder="请输入" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="受试者缩写号">
                  <el-input v-model="createForm.subject_code" placeholder="请输入" />
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="问题描述" prop="description">
                  <el-input v-model="createForm.description" type="textarea" :rows="3" placeholder="请输入" />
                </el-form-item>
              </el-col>
            </el-row>
          </div>

          <div class="editor-group">
            <div class="editor-group-title">
              <span class="group-dot group-dot-action"></span>
              处理进展
            </div>
            <el-row :gutter="14">
              <el-col :span="24">
                <el-form-item label="采取措施">
                  <el-input v-model="createForm.action_taken" type="textarea" :rows="2" placeholder="请输入" />
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="跟进计划及进展">
                  <el-input v-model="createForm.follow_up_progress" type="textarea" :rows="2" placeholder="请输入" />
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="责任人">
                  <el-input v-model="createForm.responsible_name" placeholder="请输入" />
                </el-form-item>
              </el-col>
            </el-row>
          </div>

          <div class="editor-group">
            <div class="editor-group-title">
              <span class="group-dot group-dot-time"></span>
              时间节点
            </div>
            <el-row :gutter="14">
              <el-col :span="12">
                <el-form-item label="发现时间" prop="found_date">
                  <el-date-picker
                    v-model="createForm.found_date"
                    type="date"
                    format="YYYY-MM-DD"
                    value-format="YYYY-MM-DD"
                    placeholder="请选择日期"
                    class="dialog-select"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="预计解决日期">
                  <el-date-picker
                    v-model="createForm.expected_resolve_date"
                    type="date"
                    format="YYYY-MM-DD"
                    value-format="YYYY-MM-DD"
                    placeholder="请选择日期"
                    class="dialog-select"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="实际解决日期">
                  <el-date-picker
                    v-model="createForm.actual_resolve_date"
                    type="date"
                    format="YYYY-MM-DD"
                    value-format="YYYY-MM-DD"
                    placeholder="请选择日期"
                    class="dialog-select"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="关闭日期">
                  <el-date-picker
                    v-model="createForm.closed_date"
                    type="date"
                    format="YYYY-MM-DD"
                    value-format="YYYY-MM-DD"
                    placeholder="请选择日期"
                    class="dialog-select"
                  />
                </el-form-item>
              </el-col>
            </el-row>
          </div>
        </el-form>
        <template #footer>
          <div class="editor-footer">
            <el-button @click="formDialogVisible = false">{{ TEXT.common.actions.cancel }}</el-button>
            <el-button type="primary" :loading="saving" @click="submitForm">{{ TEXT.common.actions.save }}</el-button>
          </div>
        </template>
      </el-drawer>

      <el-dialog v-if="viewDialogVisible" v-model="viewDialogVisible" title="监查访视问题详情" width="680px">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="问题编号">{{ viewIssue?.issue_no || TEXT.common.fallback }}</el-descriptions-item>
          <el-descriptions-item label="问题来源">{{ viewIssue?.source || TEXT.common.fallback }}</el-descriptions-item>
          <el-descriptions-item label="监查类型">{{ viewIssue?.monitor_type || TEXT.common.fallback }}</el-descriptions-item>
          <el-descriptions-item label="监查项">{{ viewIssue?.monitor_item || TEXT.common.fallback }}</el-descriptions-item>
          <el-descriptions-item label="问题分类">{{ viewIssue?.category || TEXT.common.fallback }}</el-descriptions-item>
          <el-descriptions-item label="建议措施">{{ viewIssue?.recommendation || TEXT.common.fallback }}</el-descriptions-item>
          <el-descriptions-item label="受试者">{{ viewIssue?.subject_name || TEXT.common.fallback }}</el-descriptions-item>
          <el-descriptions-item label="受试者缩写号">{{ viewIssue?.subject_code || TEXT.common.fallback }}</el-descriptions-item>
          <el-descriptions-item label="进度">{{ viewIssue?.progress || TEXT.common.fallback }}</el-descriptions-item>
          <el-descriptions-item label="创建者">{{ viewIssue?.creator_name || TEXT.common.fallback }}</el-descriptions-item>
          <el-descriptions-item label="责任人">{{ viewIssue?.responsible_name || TEXT.common.fallback }}</el-descriptions-item>
          <el-descriptions-item label="创建时间">{{ displayDateTime(viewIssue?.created_at) }}</el-descriptions-item>
          <el-descriptions-item label="发现时间">{{ viewIssue?.found_date || TEXT.common.fallback }}</el-descriptions-item>
          <el-descriptions-item label="开放时长">{{ viewIssue?.open_duration || TEXT.common.fallback }}</el-descriptions-item>
          <el-descriptions-item label="预计解决日期">{{ displayDateTime(viewIssue?.due_at) }}</el-descriptions-item>
          <el-descriptions-item label="实际解决日期">{{ viewIssue?.actual_resolve_date || TEXT.common.fallback }}</el-descriptions-item>
          <el-descriptions-item label="关闭日期">{{ displayDateTime(viewIssue?.closed_at) }}</el-descriptions-item>
          <el-descriptions-item label="问题描述" :span="2">{{ viewIssue?.description || TEXT.common.fallback }}</el-descriptions-item>
          <el-descriptions-item label="采取措施" :span="2">{{ viewIssue?.action_taken || TEXT.common.fallback }}</el-descriptions-item>
          <el-descriptions-item label="跟进计划及进展" :span="2">{{ viewIssue?.follow_up_progress || TEXT.common.fallback }}</el-descriptions-item>
        </el-descriptions>
      </el-dialog>
    </template>

    <StateEmpty v-else :description="TEXT.common.empty.selectProject" />
  </div>
</template>

<script setup lang="ts">
import { computed, reactive, ref, watch } from "vue";
import { ElMessage, ElMessageBox, type FormInstance, type FormRules, type UploadFile, type UploadInstance } from "element-plus";
import {
  createMonitoringVisitIssue,
  deleteMonitoringVisitIssue,
  exportMonitoringVisitIssues,
  getMonitoringVisitIssue,
  importMonitoringVisitIssues,
  listMonitoringVisitIssues,
  updateMonitoringVisitIssue,
} from "../../api/monitoringVisitIssues";
import StateEmpty from "../../components/StateEmpty.vue";
import { TEXT } from "../../locales";
import { useStudyStore } from "../../store/study";
import { displayDateTime } from "../../utils/display";

interface MonitoringIssueRow {
  id: string;
  issue_no: string;
  open_duration: string;
  category: string;
  subject_name?: string | null;
  subject_code: string | null;
  monitor_item: string | null;
  monitor_type: string | null;
  progress: string;
  status: "OPEN" | "CLOSED";
  source: string | null;
  creator_name: string | null;
  recommendation?: string | null;
  created_at: string;
  description: string | null;
  action_taken?: string | null;
  follow_up_progress?: string | null;
  found_date?: string | null;
  actual_resolve_date?: string | null;
  closed_at?: string | null;
  responsible_name?: string | null;
  overdue: boolean;
  due_at?: string | null;
}
type MonitoringIssueTableRow = MonitoringIssueRow & { __rowType: "data" | "desc" };

const study = useStudyStore();
const loading = ref(false);
const saving = ref(false);
const importing = ref(false);
const exporting = ref(false);
const formDialogVisible = ref(false);
const viewDialogVisible = ref(false);
const formMode = ref<"create" | "edit">("create");
const editingIssueId = ref("");
const createFormRef = ref<FormInstance>();
const importUploadRef = ref<UploadInstance>();
const allItems = ref<MonitoringIssueRow[]>([]);
const viewIssue = ref<MonitoringIssueRow | null>(null);

const filters = reactive({
  category: "",
  status: "",
  overdue: "",
});

const appliedFilters = reactive({
  category: "",
  status: "",
  overdue: "",
});

const pagination = reactive({
  page: 1,
  pageSize: 10,
});

const createForm = reactive({
  issue_no: "",
  source: "监查",
  monitor_type: "监查访视",
  monitor_item: "",
  category: "",
  recommendation: "",
  subject_name: "",
  subject_code: "",
  description: "",
  action_taken: "",
  follow_up_progress: "",
  found_date: "",
  expected_resolve_date: "",
  actual_resolve_date: "",
  closed_date: "",
  responsible_name: "",
});

const createRules: FormRules = {
  source: [{ required: true, message: "请选择问题来源", trigger: "change" }],
  category: [{ required: true, message: "请输入问题分类", trigger: "blur" }],
  description: [{ required: true, message: "请输入问题描述", trigger: "blur" }],
  found_date: [{ required: true, message: "请选择发现时间", trigger: "change" }],
};

const sourceOptions = ["监查", "稽查", "其他"];
const monitorTypeOptions = ["监查访视", "远程监查", "现场核查", "稽查", "其他"];
const statusOptions = [
  { label: "开放中", value: "OPEN" },
  { label: "已关闭", value: "CLOSED" },
];

const categoryOptions = computed(() =>
  Array.from(new Set(allItems.value.map((item) => item.category))).sort((a, b) => a.localeCompare(b, "zh-CN"))
);

const filteredItems = computed(() =>
  allItems.value.filter((item) => {
    if (appliedFilters.category && item.category !== appliedFilters.category) return false;
    if (appliedFilters.status && item.status !== appliedFilters.status) return false;
    if (appliedFilters.overdue === "YES" && !item.overdue) return false;
    if (appliedFilters.overdue === "NO" && item.overdue) return false;
    return true;
  })
);

const pagedItems = computed(() => {
  const start = (pagination.page - 1) * pagination.pageSize;
  return filteredItems.value.slice(start, start + pagination.pageSize);
});
const tableRows = computed<MonitoringIssueTableRow[]>(() =>
  pagedItems.value.flatMap((item) => [
    { ...item, __rowType: "data" as const },
    { ...item, __rowType: "desc" as const },
  ])
);

const isDescRow = (row: MonitoringIssueTableRow | MonitoringIssueRow) => (row as MonitoringIssueTableRow).__rowType === "desc";
const tableRowClassName = ({ row }: { row: MonitoringIssueTableRow }) => (isDescRow(row) ? "issue-desc-table-row" : "");
const tableSpanMethod = ({ row, columnIndex }: { row: MonitoringIssueTableRow; columnIndex: number }) => {
  if (!isDescRow(row)) return { rowspan: 1, colspan: 1 };
  if (columnIndex === 0) return { rowspan: 1, colspan: 8 };
  return { rowspan: 0, colspan: 0 };
};

const resetCreateForm = () => {
  createForm.issue_no = "";
  createForm.source = "监查";
  createForm.monitor_type = "监查访视";
  createForm.monitor_item = "";
  createForm.category = "";
  createForm.recommendation = "";
  createForm.subject_name = "";
  createForm.subject_code = "";
  createForm.description = "";
  createForm.action_taken = "";
  createForm.follow_up_progress = "";
  createForm.found_date = "";
  createForm.expected_resolve_date = "";
  createForm.actual_resolve_date = "";
  createForm.closed_date = "";
  createForm.responsible_name = "";
  createFormRef.value?.clearValidate();
};

const fillFormFromIssue = (issue: MonitoringIssueRow) => {
  createForm.issue_no = issue.issue_no || "";
  createForm.source = issue.source || "监查";
  createForm.monitor_type = issue.monitor_type || "监查访视";
  createForm.monitor_item = issue.monitor_item || "";
  createForm.category = issue.category || "";
  createForm.recommendation = issue.recommendation || "";
  createForm.subject_name = issue.subject_name || "";
  createForm.subject_code = issue.subject_code || "";
  createForm.description = issue.description || "";
  createForm.action_taken = issue.action_taken || "";
  createForm.follow_up_progress = issue.follow_up_progress || "";
  createForm.found_date = issue.found_date ? String(issue.found_date).slice(0, 10) : "";
  createForm.expected_resolve_date = issue.due_at ? String(issue.due_at).slice(0, 10) : "";
  createForm.actual_resolve_date = issue.actual_resolve_date ? String(issue.actual_resolve_date).slice(0, 10) : "";
  createForm.closed_date = issue.closed_at ? String(issue.closed_at).slice(0, 10) : "";
  createForm.responsible_name = issue.responsible_name || "";
  createFormRef.value?.clearValidate();
};

const loadIssues = async () => {
  const studyId = study.currentStudy?.id;
  if (!studyId) {
    allItems.value = [];
    return;
  }
  loading.value = true;
  try {
    const { data } = await listMonitoringVisitIssues(studyId, { limit: 2000 });
    allItems.value = Array.isArray(data) ? data : [];
  } catch (e: any) {
    allItems.value = [];
    ElMessage.error(e?.response?.data?.detail || TEXT.common.messages.loadFailed);
  } finally {
    loading.value = false;
  }
};

const handleSearch = () => {
  appliedFilters.category = filters.category;
  appliedFilters.status = filters.status;
  appliedFilters.overdue = filters.overdue;
  pagination.page = 1;
};

const handleReset = () => {
  filters.category = "";
  filters.status = "";
  filters.overdue = "";
  handleSearch();
};

const openCreateDialog = () => {
  resetCreateForm();
  formMode.value = "create";
  editingIssueId.value = "";
  formDialogVisible.value = true;
};

const openEditDialog = async (row: MonitoringIssueRow) => {
  const studyId = study.currentStudy?.id;
  if (!studyId || !row?.id) return;
  try {
    const { data } = await getMonitoringVisitIssue(studyId, row.id);
    const issue = (data || row) as MonitoringIssueRow;
    formMode.value = "edit";
    editingIssueId.value = row.id;
    fillFormFromIssue(issue);
    formDialogVisible.value = true;
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.detail || TEXT.common.messages.loadFailed);
  }
};

const openViewDialog = async (row: MonitoringIssueRow) => {
  const studyId = study.currentStudy?.id;
  if (!studyId || !row?.id) return;
  try {
    const { data } = await getMonitoringVisitIssue(studyId, row.id);
    viewIssue.value = (data || row) as MonitoringIssueRow;
    viewDialogVisible.value = true;
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.detail || TEXT.common.messages.loadFailed);
  }
};

const submitForm = async () => {
  const studyId = study.currentStudy?.id;
  if (!studyId) return;
  const ok = await createFormRef.value?.validate().catch(() => false);
  if (!ok) return;

  saving.value = true;
  try {
    const resolvedStatus = createForm.closed_date ? "CLOSED" : "OPEN";
    const payload = {
      issue_no: createForm.issue_no || undefined,
      source: createForm.source || undefined,
      monitor_type: createForm.monitor_type || undefined,
      monitor_item: createForm.monitor_item || undefined,
      category: createForm.category,
      recommendation: createForm.recommendation || undefined,
      subject_name: createForm.subject_name || undefined,
      subject_code: createForm.subject_code || undefined,
      description: createForm.description || undefined,
      action_taken: createForm.action_taken || undefined,
      follow_up_progress: createForm.follow_up_progress || undefined,
      found_date: createForm.found_date || undefined,
      due_at: createForm.expected_resolve_date ? `${createForm.expected_resolve_date}T00:00:00` : undefined,
      actual_resolve_date: createForm.actual_resolve_date || undefined,
      closed_at: createForm.closed_date ? `${createForm.closed_date}T00:00:00` : undefined,
      responsible_name: createForm.responsible_name || undefined,
      status: resolvedStatus,
    };
    if (formMode.value === "create") {
      await createMonitoringVisitIssue(studyId, payload);
      ElMessage.success(TEXT.common.messages.createSuccess);
    } else if (editingIssueId.value) {
      await updateMonitoringVisitIssue(studyId, editingIssueId.value, payload);
      ElMessage.success(TEXT.common.messages.updateSuccess);
    }
    formDialogVisible.value = false;
    await loadIssues();
    handleSearch();
  } catch (e: any) {
    ElMessage.error(
      e?.response?.data?.detail || (formMode.value === "create" ? TEXT.common.messages.createFailed : TEXT.common.messages.updateFailed)
    );
  } finally {
    saving.value = false;
  }
};

const removeIssue = async (row: MonitoringIssueRow) => {
  const studyId = study.currentStudy?.id;
  if (!studyId || !row?.id) return;
  const confirmed = await ElMessageBox.confirm(`确认删除问题「${row.issue_no}」？`, TEXT.common.labels.tips).catch(() => null);
  if (!confirmed) return;

  try {
    await deleteMonitoringVisitIssue(studyId, row.id);
    ElMessage.success(TEXT.common.messages.deleteSuccess);
    await loadIssues();
    handleSearch();
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.detail || TEXT.common.messages.deleteFailed);
  }
};

const getFilename = (header?: string | null) => {
  if (!header) return null;
  const match = /filename\*=UTF-8''([^;]+)|filename="?([^\";]+)"?/i.exec(header);
  if (!match) return null;
  return decodeURIComponent(match[1] || match[2] || "");
};

const handleExportExcel = async () => {
  const studyId = study.currentStudy?.id;
  if (!studyId) return;
  if (filteredItems.value.length === 0) {
    ElMessage.warning("暂无可导出数据");
    return;
  }

  exporting.value = true;
  try {
    const params: Record<string, any> = {};
    if (appliedFilters.category) params.category = appliedFilters.category;
    if (appliedFilters.status) params.status = appliedFilters.status;
    if (appliedFilters.overdue === "YES") params.overdue = true;
    if (appliedFilters.overdue === "NO") params.overdue = false;

    const response = await exportMonitoringVisitIssues(studyId, params);
    const contentType = response.headers?.["content-type"] || "application/octet-stream";
    const filename = getFilename(response.headers?.["content-disposition"]) || "监查访视问题.xlsx";
    const blob = new Blob([response.data], { type: contentType });
    const url = window.URL.createObjectURL(blob);
    const link = document.createElement("a");
    link.href = url;
    link.download = filename;
    document.body.appendChild(link);
    link.click();
    link.remove();
    window.URL.revokeObjectURL(url);
    ElMessage.success("导出成功");
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.detail || TEXT.common.messages.downloadFailed);
  } finally {
    exporting.value = false;
  }
};

const onImportChange = async (uploadFile: UploadFile) => {
  const studyId = study.currentStudy?.id;
  if (!studyId) return;
  const file = uploadFile.raw;
  if (!file) return;

  importing.value = true;
  try {
    const { data } = await importMonitoringVisitIssues(studyId, file);
    const summary = data || {};
    const skippedTip = summary.skipped_count ? `，跳过 ${summary.skipped_count} 条` : "";
    ElMessage.success(`导入完成：新增 ${summary.created_count || 0} 条，更新 ${summary.updated_count || 0} 条${skippedTip}`);
    if (Array.isArray(summary.skipped_rows) && summary.skipped_rows.length > 0) {
      ElMessage.warning(`部分行未导入：${summary.skipped_rows.slice(0, 3).join("；")}`);
    }
    await loadIssues();
    handleSearch();
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.detail || TEXT.common.messages.uploadFailed);
  } finally {
    importing.value = false;
    importUploadRef.value?.clearFiles();
  }
};

watch(
  () => study.currentStudy?.id,
  () => {
    handleReset();
    loadIssues();
  },
  { immediate: true }
);
</script>

<style scoped>
.page {
  display: flex;
  flex-direction: column;
}

.main-content-card :deep(.el-card__body) {
  padding: 0;
}

.filter-container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.filter-left {
  flex: 1;
  min-width: 580px;
}

.filter-form {
  display: flex;
  width: 100%;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}

.filter-item {
  display: flex;
  align-items: center;
  margin-bottom: 0 !important;
  margin-right: 0 !important;
}

.filter-field {
  gap: 10px;
}

.filter-label {
  color: #6b7a90;
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
}

.filter-select {
  width: 150px;
}

.filter-actions {
  display: flex;
  align-items: center;
  margin-bottom: 0 !important;
  margin-right: 0 !important;
}

.toolbar-right {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

.issue-no {
  font-weight: 600;
  color: #24324a;
}

.issue-desc {
  margin: 0;
  color: #71839f;
  font-size: 12px;
}

:deep(.issue-desc-table-row .el-table__cell) {
  background: #fbfdff;
}

.progress-cell {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

.progress-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  display: inline-block;
}

.action-cell {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  white-space: nowrap;
}

.action-btn {
  padding: 0;
  min-width: auto;
}

:deep(.action-cell .el-button + .el-button) {
  margin-left: 0;
}

.dot-open {
  background: #409eff;
}

.dot-closed {
  background: #67c23a;
}

.pagination-wrap {
  margin: 10px 0 0;
  display: flex;
  justify-content: flex-end;
}

.issue-table-empty {
  min-height: 220px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #8a97ab;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.02em;
}

.issue-table :deep(.el-table__inner-wrapper::before) {
  display: none;
}

.dialog-select {
  width: 100%;
}

:deep(.issue-editor-drawer > .el-drawer__header) {
  margin-bottom: 0;
  padding: 16px 18px 10px;
  border-bottom: 1px solid #edf2f8;
}

:deep(.issue-editor-drawer > .el-drawer__body) {
  padding: 14px 18px 4px;
  background: #f8fbff;
}

:deep(.issue-editor-drawer > .el-drawer__footer) {
  padding: 12px 18px;
  border-top: 1px solid #edf2f8;
  background: #ffffff;
}

.editor-header {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.editor-title {
  font-size: 18px;
  font-weight: 700;
  color: #15315b;
}

.editor-subtitle {
  font-size: 12px;
  color: #7a8aa5;
}

.issue-editor-form {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 560px;
  margin: 0 auto;
  width: 100%;
}

.editor-group {
  border: 1px solid #e6edf7;
  border-radius: 12px;
  background: #ffffff;
  padding: 12px 12px 2px;
}

.editor-group-title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  font-size: 14px;
  font-weight: 700;
  color: #203a63;
}

.group-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: inline-block;
}

.group-dot-basic {
  background: #409eff;
}

.group-dot-issue {
  background: #e6a23c;
}

.group-dot-action {
  background: #67c23a;
}

.group-dot-time {
  background: #909399;
}

.editor-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

@media (max-width: 768px) {
  :deep(.issue-editor-drawer) {
    width: 100% !important;
  }
}

@media (max-width: 1200px) {
  .filter-left {
    min-width: 100%;
  }
}
</style>
