<template>
  <div class="safety-platform-container">
    <header class="safety-platform-container__header">
      <div class="breadcrumb-title"> 隐患台账管理 </div>
    </header>
    <main class="safety-platform-container__main">
      <div class="search-table-container">
        <header>
          <div style="position: relative">
            <el-button type="primary" class="search-table-container--button" @click="handleCreate">
              新增隐患
            </el-button>
            <el-button plain class="search-table-container--button" @click="handleImport">
              导入
            </el-button>
            <el-button plain class="search-table-container--button" @click="handleDownload">
              导出
            </el-button>
          </div>

          <div class="act-search">
            <section class="select-box">
              <div class="select-box--item">
                <span>关键词：</span>
                <el-input
                  v-model="tableQuery.queryParam.keyword"
                  placeholder="隐患问题/整改要求等"
                  class="act-search-input"
                />
              </div>
              <div class="select-box--item">
                <span>状态：</span>
                <el-select
                  v-model="tableQuery.queryParam.status"
                  placeholder="请选择状态"
                  clearable
                >
                  <el-option label="全部" :value="0" />
                  <el-option label="待下发" :value="1" />
                  <el-option label="待整改" :value="2" />
                  <el-option label="待复查" :value="3" />
                  <el-option label="已完成" :value="4" />
                  <el-option label="待入账" :value="5" />
                </el-select>
              </div>
              <div class="select-box--item">
                <span>任务来源：</span>
                <el-input
                  v-model="tableQuery.queryParam.taskSource"
                  placeholder="如：上级检查、院内自查"
                  class="act-search-input"
                  clearable
                />
              </div>
            </section>
            <section class="search-btn">
              <el-button type="primary" @click="handleSearch">查询</el-button>
              <el-button @click="handleReset">重置</el-button>
            </section>
          </div>
        </header>

        <div class="batch-table">
          <BasicTable
            ref="basicTableRef"
            :tableData="tableData"
            :tableConfig="tableConfig"
            @update:pageSize="handleSizeChange"
            @update:pageNumber="handleCurrentChange"
          >
            <template #currentNode="scope">
              <span>{{ scope.row.currentNode  }}</span>
            </template>
            <template #status="scope">
              <span>{{ scope.row.statusName || '-' }}</span>
            </template>
            <template #action="scope">
              <div class="action-container--div" style="justify-content: left">
                <!-- 待下发 statusId=1：编辑、删除、查看、下发、扣分 -->
                <template v-if="scope.row.statusId === 1">
                  <ActionButton text="编辑" @click="handleEdit(scope.row.id)" />
                  <ActionButton
                    text="删除"
                    :popconfirm="{ title: '确定要删除?' }"
                    @confirm="handleDelete(scope.row.id)"
                  />
                  <ActionButton text="查看" @click="handleView(scope.row.id)" />
                  <ActionButton text="下发" @click="handleOpenIssue(scope.row.id)" />
                  <ActionButton text="扣分" @click="handleOpenDeduct(scope.row.id)" />
                </template>
                <!-- 待整改 statusId=2：查看、整改、扣分 -->
                <template v-else-if="scope.row.statusId === 2">
                  <ActionButton text="查看" @click="handleView(scope.row.id)" />
                  <ActionButton text="整改" @click="handleRectify(scope.row.id)" />
                  <ActionButton text="扣分" @click="handleOpenDeduct(scope.row.id)" />
                </template>
                <!-- 待复查 statusId=3：查看、复查、扣分 -->
                <template v-else-if="scope.row.statusId === 3">
                  <ActionButton text="查看" @click="handleView(scope.row.id)" />
                  <ActionButton text="复查" @click="handleReview(scope.row.id)" />
                  <ActionButton text="扣分" @click="handleOpenDeduct(scope.row.id)" />
                </template>
                <!-- 已完成 statusId=4：查看、扣分 -->
                <template v-else-if="scope.row.statusId === 4">
                  <ActionButton text="查看" @click="handleView(scope.row.id)" />
                  <ActionButton text="扣分" @click="handleOpenDeduct(scope.row.id)" />
                </template>
                <!-- 待入账 statusId=5：编辑、删除、查看、下发、扣分（与待下发一致） -->
                <template v-else-if="scope.row.statusId === 5">
                  <ActionButton text="编辑" @click="handleEdit(scope.row.id)" />
                  <ActionButton
                    text="删除"
                    :popconfirm="{ title: '确定要删除?' }"
                    @confirm="handleDelete(scope.row.id)"
                  />
                  <ActionButton text="查看" @click="handleView(scope.row.id)" />
                  <ActionButton text="下发" @click="handleOpenIssue(scope.row.id)" />
                  <ActionButton text="扣分" @click="handleOpenDeduct(scope.row.id)" />
                </template>
                <!-- 其他状态：无操作 -->
              </div>
            </template>
          </BasicTable>
        </div>
      </div>
    </main>
    <BatchImport
      v-if="batchImportVisible"
      :visible="batchImportVisible"
      :import-api-url="importApiUrl"
      :template-url="templateUrl"
      template-name="下载模板"
      :show-template="false"
      @close="batchImportVisible = false"
      @update="handleUpdate"
    />

    <!-- 隐患台账下发弹窗 -->
    <el-dialog
      v-model="showIssueDialog"
      title="隐患台账下发"
      width="500px"
      destroy-on-close
      @open="onIssueDialogOpen"
    >
      <el-form ref="issueFormRef" :model="issueForm" :rules="issueRules" label-width="140px">
        <el-form-item label="整改责任部门" prop="rectificationDepartmentId">
          <el-cascader
            v-model="issueForm.rectificationDepartmentId"
            :options="issueDeptTree"
            :props="cascaderDeptProp"
            :show-all-levels="false"
            placeholder="请选择整改责任部门"
            filterable
            clearable
            style="width: 100%"
            @change="onIssueDeptChange"
          />
        </el-form-item>
        <el-form-item label="整改负责人" prop="rectificationResponsibleUserId">
          <el-select
            v-model="issueForm.rectificationResponsibleUserId"
            placeholder="选择整改负责人"
            filterable
            clearable
            style="width: 100%"
          >
            <el-option
              v-for="user in issueUserList"
              :key="user.id"
              :label="user.realname ?? user.username"
              :value="user.id"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showIssueDialog = false">取消</el-button>
        <el-button type="primary" @click="handleIssueSave">保存</el-button>
      </template>
    </el-dialog>

    <!-- 扣分弹窗 -->
    <el-dialog v-model="showDeductDialog" title="扣分记录" width="400px" destroy-on-close @open="onDeductDialogOpen">
      <el-form ref="deductFormRef" :model="deductForm" :rules="deductRules" label-width="100px">
        <el-form-item label="扣分值" prop="deductionScore">
          <el-input-number
            v-model="deductForm.deductionScore"
            :min="0"
            :max="9999"
            :precision="0"
            placeholder="请输入扣分值（0-9999整数）"
            style="width: 100%"
          />
        </el-form-item>
        <el-form-item label="扣分部门">
          <el-select
            v-model="deductDeptIdsArray"
            placeholder="请选择扣分部门，可多选（复用复查人员所属部门）"
            clearable
            filterable
            multiple
            collapse-tags
            collapse-tags-tooltip
            style="width: 100%"
          >
            <el-option
              v-for="d in deductDeptOptions"
              :key="d.id"
              :label="d.deptName"
              :value="d.id"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showDeductDialog = false">取消</el-button>
        <el-button type="primary" @click="handleDeductSubmit">确认扣分</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
  import { onMounted, reactive, ref } from 'vue';
  import { ElMessage } from 'element-plus';
  import BasicTable from '@/components/BasicTable.vue';
  import useTableConfig from '@/hooks/useTableConfigHook';
  import ActionButton from '@/components/ActionButton.vue';
  import { TABLE_OPTIONS, HIDDEN_DANGER_TABLE_COLUMNS } from './configs/tables';
  import { useRouter } from 'vue-router';
  import type { QueryPageRequest } from '@/types/basic-query';
  import {
    queryHiddenDangerPage,
    deleteHiddenDanger,
    exportHiddenDanger,
    issueHiddenDanger,
    deductHiddenDangerPoints,
    type HiddenDangerQueryParam,
    type HiddenDangerDeductPointsRequest,
  } from '@/api/hiddenDanger';
  import { getAllDepartments } from '@/api/auth/dept';
  import type { DeptTree } from '@/types/dept/type';
  import { queryAvailableUserList } from '@/api/production-safety/responsibility-implementation';
  import { downloadByData } from '@/utils/file/download';
  import BatchImport from '@/components/batch-import/BatchImport.vue';
  import { useGlobSetting } from '@/hooks/setting';
  import urlJoin from 'url-join';

  const router = useRouter();

  // 表格
  const basicTableRef = ref<InstanceType<typeof BasicTable>>();

  const { tableConfig, pagination } = useTableConfig(HIDDEN_DANGER_TABLE_COLUMNS, TABLE_OPTIONS);

  const tableData = ref<any[]>([]);

  const tableQuery = reactive<QueryPageRequest<HiddenDangerQueryParam>>({
    pageNumber: pagination.pageNumber,
    pageSize: pagination.pageSize,
    queryParam: {
      keyword: '',
      status: undefined,
      taskSource: '',
    },
  });

  const handleSizeChange = (value: number) => {
    pagination.pageSize = value;
    tableQuery.pageSize = value;
    getTableData();
  };

  const handleCurrentChange = (value: number) => {
    pagination.pageNumber = value;
    tableQuery.pageNumber = value;
    getTableData();
  };


  async function getTableData() {
    tableConfig.loading = true;
    try {
      const res = await queryHiddenDangerPage(tableQuery);
      if (res?.records?.length) {
        // 映射返回数据字段到表格字段
        tableData.value = res.records.map((item) => ({
          id: item.id,
          dangerProblem: item.dangerProblem,
          reasonName: item.reasonName,
          createdAt: item.createdAt,
          taskSource: item.taskSource,
          rectificationRequirement: item.rectificationRequirement,
          typeName: item.typeName,
          currentNode: item.currentNode,
          statusName: item.statusName,
          statusId: item.statusId,
        }));
        pagination.total = (res as any).totalRow ?? (res as any).total ?? 0;
      } else {
        tableData.value = [];
        pagination.total = 0;
      }
    } catch (e) {
      console.error('获取隐患台账列表失败:', e);
      tableData.value = [];
      pagination.total = 0;
    } finally {
      tableConfig.loading = false;
    }
  }

  const handleSearch = () => {
    pagination.pageNumber = 1;
    tableQuery.pageNumber = 1;
    getTableData();
  };

  const handleReset = () => {
    tableQuery.queryParam.keyword = '';
    tableQuery.queryParam.status = undefined;
    tableQuery.queryParam.taskSource = '';
    handleSearch();
  };

  // 批量导入
  const batchImportVisible = ref(false);
  const { urlPrefix } = useGlobSetting();
  const importApiUrl = ref(urlJoin(urlPrefix, '/productionHiddenDanger/importHiddenDanger'));
  const templateUrl = ref('./skyeye-file-upload/sfysecurity/TEMPLATE/import-hidden-danger-template.xlsx');

  const handleImport = () => {
    batchImportVisible.value = true;
  };

  const handleUpdate = () => {
    batchImportVisible.value = false;
    getTableData();
  };

  const handleDownload = async () => {
    try {
      const exportParams: HiddenDangerQueryParam = {
        keyword: tableQuery.queryParam.keyword || undefined,
        status: tableQuery.queryParam.status,
        taskSource: tableQuery.queryParam.taskSource || undefined,
      };
      const response = await exportHiddenDanger(exportParams);
      if (response) {
        const fileName = `隐患台账_${new Date().toISOString().split('T')[0]}.xlsx`;
        downloadByData(response, fileName);
        ElMessage.success('导出成功');
      }
    } catch (e) {
      console.error('导出隐患台账失败:', e);
      ElMessage.error(e?.message || e?.data || '导出失败，请重试');
    }
  };

  /** 隐患台账详情页路径（与路由配置一致，避免 name 解析失败） */
  const HIDDEN_ACCOUNT_ITEM_PATH = '/work-safety/hidden-trouble-investigation-and-governance/hidden-trouble-account-management-item';

  const handleCreate = () => {
    router.push({
      path: HIDDEN_ACCOUNT_ITEM_PATH,
      query: {
        operate: 'hidden-trouble-account-create',
      },
    });
  };

  const handleEdit = (id: number) => {
    router.push({
      path: HIDDEN_ACCOUNT_ITEM_PATH,
      query: {
        id: String(id),
        operate: 'hidden-trouble-account-edit',
      },
    });
  };

  const handleDelete = async (id: number) => {
    try {
      await deleteHiddenDanger(id);
      ElMessage.success('删除成功');
      getTableData();
    } catch (e) {
      console.error('删除隐患台账失败:', e);
      ElMessage.error(e?.message || e?.data || '删除失败，请重试');
    }
  };

  /** 下发弹窗：点击下发打开弹窗，弹窗内部门用 queryAllDeptTree、负责人用 queryAvailableUserList，点击保存才触发下发接口 */
  const showIssueDialog = ref(false);
  const issueDangerId = ref<number>(0);
  const issueFormRef = ref();
  const issueForm = ref({
    rectificationDepartmentId: undefined as number | undefined,
    rectificationResponsibleUserId: undefined as number | undefined,
    rectificationResponsiblePersonName: '' as string,
  });
  const issueRules = {
    rectificationDepartmentId: [{ required: true, message: '请选择整改责任部门', trigger: 'change' }],
    rectificationResponsibleUserId: [{ required: true, message: '请选择整改负责人', trigger: 'change' }],
  };
  /** 下发弹窗部门树，与新增隐患台账复查人员所属部门一致（getAllDepartments 取第一级 children） */
  const cascaderDeptProp = {
    checkStrictly: true,
    expandTrigger: 'hover' as const,
    value: 'id',
    label: 'deptName',
    emitPath: false,
  };
  const issueDeptTree = ref<DeptTree[]>([]);
  const issueUserList = ref<Array<{ id: number; realname?: string; username?: string }>>([]);

  const onIssueDialogOpen = async () => {
    try {
      const [deptRes, userRes] = await Promise.all([
        getAllDepartments(),
        queryAvailableUserList({ pageNumber: 1, pageSize: 9999, queryParam: {} }),
      ]);
      const fullTree = (deptRes as DeptTree[]) ?? [];
      issueDeptTree.value = Array.isArray(fullTree) && fullTree[0]?.children ? fullTree[0].children : [];
      issueUserList.value = (userRes as any)?.records ?? [];
    } catch (e) {
      console.error('获取部门/用户列表失败:', e);
      ElMessage.error(e?.message || e?.data || '加载部门或负责人列表失败');
      issueDeptTree.value = [];
      issueUserList.value = [];
    }
  };

  const onIssueDeptChange = () => {
    issueForm.value.rectificationResponsibleUserId = undefined;
    issueForm.value.rectificationResponsiblePersonName = '';
  };

  /** 从部门树中根据 id 查找部门名称 */
  function findDeptNameById(nodes: DeptTree[] | undefined, id: number): string {
    if (!nodes?.length) return '';
    for (const n of nodes) {
      if (n.id === id) return n.deptName ?? '';
      if (n.children?.length) {
        const found = findDeptNameById(n.children, id);
        if (found) return found;
      }
    }
    return '';
  }

  const handleOpenIssue = (id: number) => {
    issueDangerId.value = id;
    issueForm.value = {
      rectificationDepartmentId: undefined,
      rectificationResponsibleUserId: undefined,
      rectificationResponsiblePersonName: '',
    };
    showIssueDialog.value = true;
  };

  const handleIssueSave = async () => {
    await issueFormRef.value?.validate?.().catch(() => {});
    const { rectificationDepartmentId, rectificationResponsibleUserId } = issueForm.value;
    if (rectificationDepartmentId == null || rectificationResponsibleUserId == null) {
      ElMessage.warning('请选择整改责任部门和整改负责人');
      return;
    }
    const selectedUser = issueUserList.value.find((u) => u.id === rectificationResponsibleUserId);
    const personName = selectedUser?.realname ?? selectedUser?.username ?? '';
    const deptName = findDeptNameById(issueDeptTree.value, rectificationDepartmentId);
    try {
      await issueHiddenDanger({
        danger_id: issueDangerId.value,
        rectification_department_ids: String(rectificationDepartmentId),
        rectification_responsible_person: personName,
        dept_name: deptName,
        rectification_responsible_ids: String(rectificationResponsibleUserId),
      });
      ElMessage.success('下发成功');
      showIssueDialog.value = false;
      getTableData();
    } catch (e) {
      console.error('下发失败:', e);
      ElMessage.error(e?.message || e?.data || '下发失败，请重试');
    }
  };

  /** 整改：跳转详情页进行整改 */
  const handleRectify = (id: number) => {
    router.push({
      path: HIDDEN_ACCOUNT_ITEM_PATH,
      query: { id: String(id), operate: 'hidden-trouble-account-rectify', action: 'rectify' },
    });
  };

  /** 复查：跳转复查详情页 */
  const handleReview = (id: number) => {
    router.push({
      path: HIDDEN_ACCOUNT_ITEM_PATH,
      query: { id: String(id), operate: 'hidden-trouble-account-review' },
    });
  };

  /** 扣分弹窗（扣分部门复用复查人员所属部门数据源） */
  function flattenDeptTreeForDeduct(nodes: DeptTree[] | undefined): Array<{ id: number; deptName: string }> {
    if (!nodes?.length) return [];
    const list: Array<{ id: number; deptName: string }> = [];
    const walk = (items: DeptTree[]) => {
      items.forEach((n) => {
        if (n.id != null) list.push({ id: n.id, deptName: n.deptName });
        if (n.children?.length) walk(n.children);
      });
    };
    walk(nodes);
    return list;
  }
  const showDeductDialog = ref(false);
  const deductDangerId = ref<number>(0);
  const deductDeptOptions = ref<Array<{ id: number; deptName: string }>>([]);
  const deductDeptIdsArray = ref<number[]>([]);
  const deductForm = ref<HiddenDangerDeductPointsRequest>({
    dangerId: 0,
    deductionScore: 0,
  });
  const deductFormRef = ref();
  const deductRules = {
    deductionScore: [
      { required: true, message: '请输入扣分值', trigger: 'blur' },
      { type: 'number', min: 0, max: 9999, message: '扣分值须为0-9999的整数', trigger: 'blur' },
    ],
  };
  const onDeductDialogOpen = async () => {
    try {
      const deptRes = await getAllDepartments();
      const fullTree = (deptRes as DeptTree[]) ?? [];
      const tree = Array.isArray(fullTree) && fullTree[0]?.children ? fullTree[0].children : [];
      deductDeptOptions.value = flattenDeptTreeForDeduct(tree);
    } catch (e) {
      console.error('获取部门列表失败:', e);
      deductDeptOptions.value = [];
    }
  };
  const handleOpenDeduct = (id: number) => {
    deductDangerId.value = id;
    deductDeptIdsArray.value = [];
    deductForm.value = {
      dangerId: id,
      deductionScore: 0,
    };
    showDeductDialog.value = true;
  };
  const handleDeductSubmit = async () => {
    await deductFormRef.value?.validate?.().catch(() => {});
    const score = Number(deductForm.value.deductionScore);
    if (score < 0 || score > 9999 || !Number.isInteger(score)) {
      ElMessage.warning('扣分值须为0-9999的整数');
      return;
    }
    try {
      deductForm.value.dangerId = deductDangerId.value;
      deductForm.value.departmentIds =
        deductDeptIdsArray.value.length > 0 ? deductDeptIdsArray.value.join(',') : undefined;
      await deductHiddenDangerPoints(deductForm.value);
      ElMessage.success('扣分记录成功');
      showDeductDialog.value = false;
      getTableData();
    } catch (e) {
      console.error('扣分失败:', e);
      ElMessage.error(e?.message || e?.data || '扣分失败，请重试');
    }
  };

  const handleView = (id: number) => {
    router.push({
      path: HIDDEN_ACCOUNT_ITEM_PATH,
      query: {
        id: String(id),
        operate: 'hidden-trouble-account-view',
      },
    });
  };

  onMounted(() => {
    getTableData();
  });
</script>

<style scoped lang="scss">
  @use '@/styles/page-details-layout.scss' as *;
  @use '@/styles/page-main-layout.scss' as *;
  @use '@/styles/basic-table-action.scss' as *;
  @use '@/views/traffic/violation/style/act-search-table.scss' as *;
</style>