<template>
  <div class="hrm-page">
    <section class="panel-grid">
      <el-card class="metal-panel" shadow="hover">
        <div slot="header" class="panel-header">
          <span>组织树</span>
          <div class="actions-inline">
            <el-button size="mini" type="primary" icon="el-icon-plus" @click="openOrgDialog()">新增组织</el-button>
            <el-button size="mini" icon="el-icon-refresh" @click="loadOrg">刷新</el-button>
          </div>
        </div>
        <el-tree
          v-loading="orgLoading"
          :data="orgTree"
          node-key="orgId"
          :props="{ label: 'orgName', children: 'children' }"
          accordion
          highlight-current
          @node-click="handleOrgClick"
        >
          <span slot-scope="{ data }" class="custom-tree-node">
            <span>{{ data.orgName }}</span>
            <el-tag size="mini" effect="plain" type="info" class="tree-tag">{{ data.orgType || '组织' }}</el-tag>
          </span>
        </el-tree>
      </el-card>

      <el-card class="metal-panel" shadow="hover">
        <div slot="header" class="panel-header">
          <span>员工档案</span>
          <div class="actions-inline">
            <el-input
              v-model="empQuery.empName"
              placeholder="姓名/工号"
              size="mini"
              clearable
              @keyup.enter.native="loadEmployee"
              style="width: 180px"
            />
            <el-select
              v-model="empQuery.status"
              size="mini"
              placeholder="状态"
              clearable
              style="width: 140px"
              @change="loadEmployee"
            >
              <el-option label="在职" value="active" />
              <el-option label="离职" value="inactive" />
            </el-select>
            <el-button size="mini" type="primary" icon="el-icon-search" @click="loadEmployee">查询</el-button>
            <el-button size="mini" type="primary" icon="el-icon-plus" @click="openEmpDialog">新增员工</el-button>
          </div>
        </div>
        <el-table :data="employeeList" v-loading="empLoading" height="700" stripe @row-click="openDetail">
          <el-table-column label="工号" prop="empNo" min-width="110" />
          <el-table-column label="姓名" prop="empName" min-width="120" />
          <el-table-column label="性别" prop="gender" min-width="80" />
          <el-table-column label="手机" prop="mobile" min-width="130" />
          <el-table-column label="雇佣类型" prop="employmentType" min-width="120" />
          <el-table-column label="状态" prop="status" min-width="100">
            <template slot-scope="scope">
              <el-tag :type="statusType(scope.row.status)">{{ scope.row.status || '-' }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column label="入职日期" prop="hireDate" min-width="140">
            <template slot-scope="scope">{{ formatDate(scope.row.hireDate) }}</template>
          </el-table-column>
          <el-table-column label="备注" prop="remark" min-width="160" show-overflow-tooltip />
        </el-table>
      </el-card>
    </section>

    <el-drawer
      title="员工档案"
      :visible.sync="detailVisible"
      size="60%"
      append-to-body
    >
      <div v-if="detailEmp" class="detail-wrap">
        <div class="basic-grid">
          <el-card shadow="hover" class="metal-panel">
            <div slot="header" class="panel-header">基础信息</div>
            <el-descriptions :column="2" size="small" border>
              <el-descriptions-item label="工号">{{ detailEmp.empNo }}</el-descriptions-item>
              <el-descriptions-item label="姓名">{{ detailEmp.empName }}</el-descriptions-item>
              <el-descriptions-item label="性别">{{ detailEmp.gender }}</el-descriptions-item>
              <el-descriptions-item label="手机">{{ detailEmp.mobile }}</el-descriptions-item>
              <el-descriptions-item label="雇佣类型">{{ detailEmp.employmentType }}</el-descriptions-item>
              <el-descriptions-item label="状态">
                <el-tag :type="statusType(detailEmp.status)">{{ detailEmp.status }}</el-tag>
              </el-descriptions-item>
              <el-descriptions-item label="入职日期">{{ formatDate(detailEmp.hireDate) }}</el-descriptions-item>
              <el-descriptions-item label="备注">{{ detailEmp.remark || '-' }}</el-descriptions-item>
            </el-descriptions>
          </el-card>
        </div>

        <el-card shadow="hover" class="metal-panel" style="margin-top:12px">
          <div slot="header" class="panel-header">
            <span>组织/岗位关系</span>
            <el-button size="mini" type="primary" icon="el-icon-plus" @click="openRelDialog()">新增</el-button>
          </div>
          <el-table :data="relList" v-loading="relLoading" size="mini">
            <el-table-column label="组织" prop="orgId" min-width="160">
              <template slot-scope="scope">
                {{ renderOrg(scope.row.orgId) }}
              </template>
            </el-table-column>
            <el-table-column label="岗位" prop="positionId" min-width="150">
              <template slot-scope="scope">
                {{ renderPosition(scope.row.positionId) }}
              </template>
            </el-table-column>
            <el-table-column label="主岗" prop="isPrimary" width="80">
              <template slot-scope="scope">
                <el-tag size="mini" :type="scope.row.isPrimary ? 'success' : 'info'">{{ scope.row.isPrimary ? '是' : '否' }}</el-tag>
              </template>
            </el-table-column>
            <el-table-column label="开始" prop="startDate" min-width="120">
              <template slot-scope="scope">{{ formatDate(scope.row.startDate, 'date') }}</template>
            </el-table-column>
            <el-table-column label="结束" prop="endDate" min-width="120">
              <template slot-scope="scope">{{ formatDate(scope.row.endDate, 'date') }}</template>
            </el-table-column>
            <el-table-column label="备注" prop="remark" min-width="140" show-overflow-tooltip />
            <el-table-column label="操作" width="140" fixed="right">
              <template slot-scope="scope">
                <el-button size="mini" type="text" @click="openRelDialog(scope.row)">编辑</el-button>
                <el-button size="mini" type="text" @click="delRel(scope.row)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-card>

        <el-card shadow="hover" class="metal-panel" style="margin-top:12px">
          <div slot="header" class="panel-header">
            <span>劳动合同</span>
            <el-button size="mini" type="primary" icon="el-icon-plus" @click="openContractDialog()">新增</el-button>
          </div>
          <el-table :data="contractList" v-loading="contractLoading" size="mini">
            <el-table-column label="编号" prop="contractNo" min-width="120" />
            <el-table-column label="类型" prop="contractType" min-width="120" />
            <el-table-column label="开始" prop="startDate" min-width="120">
              <template slot-scope="scope">{{ formatDate(scope.row.startDate, 'date') }}</template>
            </el-table-column>
            <el-table-column label="结束" prop="endDate" min-width="120">
              <template slot-scope="scope">{{ formatDate(scope.row.endDate, 'date') }}</template>
            </el-table-column>
            <el-table-column label="状态" prop="status" min-width="100" />
            <el-table-column label="备注" prop="remark" min-width="140" show-overflow-tooltip />
            <el-table-column label="操作" width="140" fixed="right">
              <template slot-scope="scope">
                <el-button size="mini" type="text" @click="openContractDialog(scope.row)">编辑</el-button>
                <el-button size="mini" type="text" @click="delContractRow(scope.row)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-card>

        <el-card shadow="hover" class="metal-panel" style="margin-top:12px">
          <div slot="header" class="panel-header">
            <span>证书</span>
            <el-button size="mini" type="primary" icon="el-icon-plus" @click="openCertDialog()">新增</el-button>
          </div>
          <el-table :data="certList" v-loading="certLoading" size="mini">
            <el-table-column label="名称" prop="certName" min-width="140" />
            <el-table-column label="证书编号" prop="certNo" min-width="140" />
            <el-table-column label="签发机构" prop="issuedBy" min-width="140" />
            <el-table-column label="有效期自" prop="validFrom" min-width="120">
              <template slot-scope="scope">{{ formatDate(scope.row.validFrom, 'date') }}</template>
            </el-table-column>
            <el-table-column label="有效期至" prop="validTo" min-width="120">
              <template slot-scope="scope">{{ formatDate(scope.row.validTo, 'date') }}</template>
            </el-table-column>
            <el-table-column label="备注" prop="remark" min-width="140" show-overflow-tooltip />
            <el-table-column label="操作" width="140" fixed="right">
              <template slot-scope="scope">
                <el-button size="mini" type="text" @click="openCertDialog(scope.row)">编辑</el-button>
                <el-button size="mini" type="text" @click="delCertRow(scope.row)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </div>

      <div v-else class="preview-placeholder">请选择员工查看档案</div>
    </el-drawer>

    <el-dialog
      title="新增员工"
      :visible.sync="empDialogVisible"
      width="520px"
      append-to-body
    >
      <el-form ref="empFormRef" :model="empForm" :rules="empRules" label-width="100px" size="small">
        <el-form-item label="工号" prop="empNo">
          <el-input v-model="empForm.empNo" />
        </el-form-item>
        <el-form-item label="姓名" prop="empName">
          <el-input v-model="empForm.empName" />
        </el-form-item>
        <el-form-item label="性别">
          <el-select v-model="empForm.gender" clearable placeholder="选择性别" style="width: 100%">
            <el-option label="男" value="male" />
            <el-option label="女" value="female" />
          </el-select>
        </el-form-item>
        <el-form-item label="手机">
          <el-input v-model="empForm.mobile" />
        </el-form-item>
        <el-form-item label="雇佣类型">
          <el-input v-model="empForm.employmentType" placeholder="如 全职/实习" />
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-select v-model="empForm.status" style="width: 100%">
            <el-option label="在职" value="active" />
            <el-option label="离职" value="inactive" />
          </el-select>
        </el-form-item>
        <el-form-item label="入职日期">
          <el-date-picker v-model="empForm.hireDate" type="date" placeholder="选择日期" style="width: 100%" />
        </el-form-item>
        <el-form-item label="所属组织" prop="mainOrgId">
          <el-select v-model="empForm.mainOrgId" filterable placeholder="选择组织" style="width: 100%">
            <el-option
              v-for="org in flatOrgOptions"
              :key="org.orgId"
              :label="org.label"
              :value="org.orgId"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="备注">
          <el-input v-model="empForm.remark" type="textarea" :rows="2" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="empDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="empSubmitting" @click="submitEmp">保存</el-button>
      </div>
    </el-dialog>

    <el-dialog
      title="新增组织"
      :visible.sync="orgDialogVisible"
      width="620px"
      append-to-body
      class="org-dialog"
    >
      <el-form
        ref="orgFormRef"
        :model="orgForm"
        :rules="orgRules"
        label-width="110px"
        size="small"
        label-position="top"
        class="org-form"
      >
        <el-row :gutter="14">
          <el-col :span="12">
            <el-form-item label="组织名称" prop="orgName">
              <div class="inline-field">
                <el-input v-model="orgForm.orgName" placeholder="如：生产一部 / 市场部" />
                <el-button type="primary" icon="el-icon-magic-stick" plain size="mini" @click="autoFillOrgName">智能生成</el-button>
              </div>
              <div class="field-hint">支持快速生成示例名称，可自行修改</div>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="组织类型" prop="orgType">
              <el-select v-model="orgForm.orgType" placeholder="选择类型" filterable style="width: 100%">
                <el-option label="部门" value="department" />
                <el-option label="事业部" value="division" />
                <el-option label="公司" value="company" />
                <el-option label="项目组" value="project" />
                <el-option label="其他" value="other" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="14">
          <el-col :span="24">
            <el-form-item label="上级组织" prop="parentId">
              <el-cascader
                v-model="orgForm.parentId"
                :options="orgTree"
                :props="{ label: 'orgName', value: 'orgId', children: 'children', emitPath: false, checkStrictly: true }"
                clearable
                filterable
                placeholder="默认取当前选中的组织，可搜索"
                style="width: 100%"
              />
              <div class="field-hint">留空则创建为顶级组织</div>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="orgForm.remark" type="textarea" :rows="2" placeholder="补充说明（可选）" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="orgDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="orgSubmitting" @click="submitOrg">保存</el-button>
      </div>
    </el-dialog>

    <el-dialog
      title="劳动合同"
      :visible.sync="contractDialogVisible"
      width="520px"
      append-to-body
    >
      <el-alert
        type="info"
        show-icon
        class="contract-hint"
        title="上传后自动用文件名填充合同编号"
        description="建议文件名格式：合同编号_员工名.pdf"
      />
      <el-form :model="contractForm" label-width="100px" size="small">
        <el-form-item label="合同文件" prop="file">
          <file-upload
            ref="contractUploader"
            v-model="contractForm.fileIds"
            :limit="1"
            :file-size="50"
            :file-type="['pdf','doc','docx','jpg','png']"
            :before-validate="validateContractBeforeUpload"
            @success="handleContractUploadSuccess"
          />
          <div class="field-hint">仅限 1 个文件，文件名将自动写入合同编号</div>
        </el-form-item>
        <el-form-item label="合同编号" prop="contractNo">
          <el-input v-model="contractForm.contractNo" placeholder="上传后自动带出，可手动调整" />
        </el-form-item>
        <el-form-item label="类型">
          <el-input v-model="contractForm.contractType" placeholder="如：劳动合同/实习协议" />
        </el-form-item>
        <el-form-item label="开始日期">
          <el-date-picker v-model="contractForm.startDate" type="date" placeholder="开始" style="width: 100%" />
        </el-form-item>
        <el-form-item label="结束日期">
          <el-date-picker v-model="contractForm.endDate" type="date" placeholder="结束" style="width: 100%" />
        </el-form-item>
        <el-form-item label="状态">
          <el-input v-model="contractForm.status" placeholder="如：生效/签署中" />
        </el-form-item>
        <el-form-item label="备注">
          <el-input v-model="contractForm.remark" type="textarea" :rows="2" placeholder="补充说明" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="contractDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="contractSubmitting" @click="submitContract">保存</el-button>
      </div>
    </el-dialog>

    <el-dialog
      title="证书"
      :visible.sync="certDialogVisible"
      width="720px"
      append-to-body
    >
      <el-alert
        type="info"
        show-icon
        class="contract-hint"
        title="上传证书附件，支持 pdf/doc/jpg/png"
        description="可登记证书编号、签发机构与有效期起始"
      />
      <el-form :model="certForm" label-width="100px" size="small">
        <el-row :gutter="12">
          <el-col :span="12">
            <el-form-item label="证书名称">
              <el-input v-model="certForm.certName" placeholder="如：安全生产证书" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="证书编号">
              <el-input v-model="certForm.certNo" placeholder="编号/执照号（可选）" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="12">
          <el-col :span="12">
            <el-form-item label="签发机构">
              <el-input v-model="certForm.issuedBy" placeholder="颁发单位" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="有效期起">
              <el-date-picker v-model="certForm.validFrom" type="date" placeholder="选择日期" style="width: 100%" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="证书附件">
          <file-upload
            v-model="certForm.fileIds"
            :limit="1"
            :file-size="20"
            :file-type="['pdf','doc','docx','jpg','png']"
            :is-show-tip="false"
          />
          <div class="field-hint">仅限 1 个附件，最大 20MB</div>
        </el-form-item>
        <el-form-item label="备注">
          <el-input v-model="certForm.remark" type="textarea" :rows="2" placeholder="补充说明（可选）" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="certDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="certSubmitting" @click="submitCert">保存</el-button>
      </div>
    </el-dialog>

    <el-dialog
      title="组织/岗位关系"
      :visible.sync="relDialogVisible"
      width="480px"
      append-to-body
    >
      <el-form ref="relFormRef" :model="relForm" :rules="relRules" label-width="100px" size="small">
        <el-form-item label="组织" prop="orgId">
          <el-select v-model="relForm.orgId" filterable placeholder="选择组织" style="width: 100%">
            <el-option
              v-for="org in flatOrgOptions"
              :key="org.orgId"
              :label="org.label"
              :value="org.orgId"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="岗位" prop="positionId">
          <el-select v-model="relForm.positionId" filterable placeholder="选择岗位" style="width: 100%">
            <el-option v-for="pos in positionOptions" :key="pos.positionId" :label="pos.positionName || pos.positionId" :value="pos.positionId" />
          </el-select>
        </el-form-item>
        <el-form-item label="主岗" prop="isPrimary">
          <el-switch v-model="relForm.isPrimary" :active-value="1" :inactive-value="0" />
        </el-form-item>
        <el-form-item label="开始日期">
          <el-date-picker v-model="relForm.startDate" type="date" placeholder="开始" style="width: 100%" />
        </el-form-item>
        <el-form-item label="结束日期">
          <el-date-picker v-model="relForm.endDate" type="date" placeholder="结束" style="width: 100%" />
        </el-form-item>
        <el-form-item label="备注">
          <el-input v-model="relForm.remark" type="textarea" :rows="2" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="relDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="relSubmitting" @click="submitRel">保存</el-button>
      </div>
    </el-dialog>

  </div>
</template>

<script>
import {
  listOrg,
  listEmployee,
  listPosition,
  listEmpOrgPosition,
  addEmpOrgPosition,
  updateEmpOrgPosition,
  delEmpOrgPosition,
  listContract,
  addContract,
  updateContract,
  delContract,
  listCertificate,
  addCertificate,
  updateCertificate,
  delCertificate,
  addEmployee,
  addOrg
} from '@/api/hrm'
import { delOss } from '@/api/system/oss'
import FileUpload from '@/components/FileUpload'

export default {
  name: 'HrmOrgEmployee',
  data() {
    return {
      orgTree: [],
      orgLoading: false,
      orgSelected: null,
      employeeList: [],
      empLoading: false,
      empQuery: { empName: '', status: undefined, mainOrgId: undefined },
      empDialogVisible: false,
      empSubmitting: false,
      empForm: { empNo: '', empName: '', gender: '', mobile: '', employmentType: '', status: 'active', hireDate: '', remark: '', mainOrgId: undefined },
      empRules: {
        empNo: [{ required: true, message: '请输入工号', trigger: 'blur' }],
        empName: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
        mainOrgId: [{ required: true, message: '请选择组织', trigger: 'change' }],
        status: [{ required: true, message: '请选择状态', trigger: 'change' }]
      },
      detailVisible: false,
      detailEmp: null,
      contractList: [],
      contractLoading: false,
      contractDialogVisible: false,
      contractSubmitting: false,
      contractForm: {
        contractNo: '',
        contractType: '',
        startDate: '',
        endDate: '',
        status: 'active',
        remark: '',
        fileIds: ''
      },
      certList: [],
      certLoading: false,
      certDialogVisible: false,
      certSubmitting: false,
      certForm: {},
      relList: [],
      relLoading: false,
      relDialogVisible: false,
      relSubmitting: false,
      relForm: {},
      relRules: {
        orgId: [{ required: true, message: '请选择组织', trigger: 'change' }],
        positionId: [{ required: true, message: '请选择岗位', trigger: 'change' }],
        isPrimary: [{ required: true, message: '请选择是否主岗', trigger: 'change' }]
      },
      positionOptions: [],
      positionLoading: false,
      flatOrgOptions: [],
      orgDialogVisible: false,
      orgSubmitting: false,
      orgForm: { orgName: '', orgType: '', parentId: undefined, orgCode: '', remark: '' },
      orgRules: {
        orgName: [{ required: true, message: '请输入组织名称', trigger: 'blur' }]
      }
    }
  },
  created() {
    this.loadOrg()
    this.loadPositions()
  },
  components: {
    FileUpload
  },
  methods: {
    loadTree() {
      // 兼容旧调用，直接复用 loadOrg
      this.loadOrg()
    },
    renderOrg(orgId) {
      const found = this.flatOrgOptions.find(o => o.orgId === orgId)
      return found ? found.label : orgId
    },
    renderPosition(positionId) {
      const found = this.positionOptions.find(p => p.positionId === positionId)
      return found ? (found.positionName || positionId) : positionId
    },
    statusType(status) {
      if (!status) return 'info'
      const map = { pending: 'warning', draft: 'info', approved: 'success', rejected: 'danger', active: 'success', inactive: 'info' }
      return map[status] || 'info'
    },
    formatDate(val, mode = 'datetime') {
      if (!val) return ''
      const d = new Date(val)
      const p = n => (n < 10 ? `0${n}` : n)
      if (mode === 'date') return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`
      return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}`
    },
    loadOrg() {
      this.orgLoading = true
      listOrg({ pageNum: 1, pageSize: 999 })
        .then(res => {
          const rows = res.rows || []
          this.orgTree = this.buildTree(rows)
          if (!this.orgSelected && this.orgTree.length) this.orgSelected = this.orgTree[0].orgId
          this.empQuery.mainOrgId = this.orgSelected
          this.buildFlatOrgOptions(this.orgTree)
          this.loadEmployee()
        })
        .finally(() => {
          this.orgLoading = false
        })
    },
    buildTree(list) {
      const map = {}
      list.forEach(item => {
        map[item.orgId] = { ...item, children: [] }
      })
      const roots = []
      list.forEach(item => {
        const parent = map[item.parentId]
        if (parent) parent.children.push(map[item.orgId])
        else roots.push(map[item.orgId])
      })
      return roots
    },
    buildFlatOrgOptions(orgs) {
      const flat = []
      const walk = list => {
        list.forEach(o => {
          flat.push({ orgId: o.orgId, label: `${o.orgName || o.orgId}${o.parentName ? ` / ${o.parentName}` : ''}` })
          if (o.children && o.children.length) walk(o.children)
        })
      }
      walk(orgs || [])
      this.flatOrgOptions = flat
    },
    handleOrgClick(node) {
      this.orgSelected = node.orgId
      this.empQuery.mainOrgId = node.orgId
      this.loadEmployee()
    },
    openOrgDialog() {
      this.orgForm = {
        orgName: '',
        orgType: '',
        parentId: this.orgSelected || undefined,
        orgCode: '',
        remark: ''
      }
      this.orgDialogVisible = true
      this.$nextTick(() => this.$refs.orgFormRef && this.$refs.orgFormRef.clearValidate())
    },
    buildOrgCode(name) {
      const clean = (name || '').replace(/\s+/g, '').replace(/[^\w\u4e00-\u9fa5]/g, '')
      if (clean) return clean.slice(0, 20)
      return `ORG${Date.now()}`
    },
    autoFillOrgName() {
      const typeLabelMap = {
        department: '部门',
        division: '事业部',
        company: '公司',
        project: '项目组',
        other: '组织'
      }
      const bases = ['运营', '生产', '市场', '研发', '交付', '采购', '质控', '客服', '财务', '人力']
      const randomBase = bases[Math.floor(Math.random() * bases.length)]
      const typeLabel = typeLabelMap[this.orgForm.orgType] || '部门'
      const suffix = new Date().getMilliseconds().toString().padStart(3, '0')
      this.orgForm.orgName = `${randomBase}${typeLabel}${suffix}`
    },
    submitOrg() {
      this.$refs.orgFormRef.validate(valid => {
        if (!valid) return
        this.orgSubmitting = true
        const payload = { ...this.orgForm }
        if (!payload.orgCode) {
          payload.orgCode = this.buildOrgCode(payload.orgName)
        }
        addOrg(payload)
          .then(() => {
            this.$message.success('新增成功')
            this.orgDialogVisible = false
            this.loadOrg()
          })
          .finally(() => {
            this.orgSubmitting = false
          })
      })
    },
    loadEmployee() {
      if (!this.empQuery.mainOrgId) return
      this.empLoading = true
      listEmployee({ ...this.empQuery, pageNum: 1, pageSize: 50 })
        .then(res => {
          this.employeeList = res.rows || []
        })
        .finally(() => {
          this.empLoading = false
        })
    },
    openEmpDialog() {
      const defaultOrg = this.orgSelected || (this.orgTree[0] && this.orgTree[0].orgId) || undefined
      this.empForm = {
        empNo: '',
        empName: '',
        gender: '',
        mobile: '',
        employmentType: '',
        status: 'active',
        hireDate: '',
        remark: '',
        mainOrgId: defaultOrg
      }
      this.empDialogVisible = true
      this.$nextTick(() => this.$refs.empFormRef && this.$refs.empFormRef.clearValidate())
    },
    formatDateOnly(val) {
      if (!val) return ''
      const d = new Date(val)
      const p = n => (n < 10 ? `0${n}` : n)
      return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} 00:00:00`
    },
    submitEmp() {
      this.$refs.empFormRef.validate(valid => {
        if (!valid) return
        this.empSubmitting = true
        const payload = { ...this.empForm }
        if (payload.hireDate) {
          payload.hireDate = this.formatDateOnly(payload.hireDate)
        }
        addEmployee(payload)
          .then(() => {
            this.$message.success('新增成功')
            this.empDialogVisible = false
            this.loadEmployee()
          })
          .finally(() => {
            this.empSubmitting = false
          })
      })
    },
    openDetail(row) {
      this.detailEmp = row
      this.detailVisible = true
      this.loadContracts(row.empId)
      this.loadCertificates(row.empId)
      this.loadEmpOrgRel(row.empId)
    },
    loadContracts(empId) {
      this.contractLoading = true
      listContract({ empId, pageNum: 1, pageSize: 50 })
        .then(res => {
          this.contractList = res.rows || []
        })
        .finally(() => {
          this.contractLoading = false
        })
    },
    handleContractUploadSuccess(fileList) {
      const arr = Array.isArray(fileList) ? fileList : fileList ? [fileList] : []
      if (!arr.length) return
      const first = arr[0]
      const name = (first && first.name) || ''
      if (!name) return
      // 二次兜底校验，防止后端已接收但命名不合规
      if (!this.validateContractBeforeUpload(first)) {
        this.resetContractUpload(first)
        return
      }
      const base = name.split('/').pop()
      const withoutExt = base ? base.replace(/\.[^.]+$/, '') : ''
      const no = withoutExt && withoutExt.indexOf('_') !== -1 ? withoutExt.split('_')[0] : ''
      if (no && !this.contractForm.contractNo) {
        this.contractForm.contractNo = no
      }
    },
    validateContractBeforeUpload(file) {
      const name = file && file.name
      if (!name) return false
      const base = name.split('/').pop()
      const withoutExt = base ? base.replace(/\.[^.]+$/, '') : ''
      if (!withoutExt || withoutExt.indexOf('_') === -1) {
        this.$message.error('文件名需包含编号与员工名，并用下划线分隔，例如：合同编号_员工名.pdf')
        this.resetContractUpload()
        return false
      }
      const no = withoutExt.split('_')[0]
      const validNo = /^[A-Za-z0-9-]+$/.test(no)
      if (!validNo) {
        this.$message.error('合同编号仅支持字母/数字/短横线，请调整文件名')
        this.resetContractUpload()
        return false
      }
      return true
    },
    async resetContractUpload(firstFile) {
      // 清前端状态
      this.contractForm.fileIds = ''
      this.contractForm.contractNo = ''
      const uploader = this.$refs.contractUploader
      if (uploader && uploader.resetUpload) {
        uploader.resetUpload()
      }
      // 仅在有 ossId 时请求删除
      const ossId = firstFile && firstFile.ossId
      if (ossId) {
        try {
          await delOss(ossId)
        } catch (e) {
          // 忽略删除异常
        }
      }
    },
    openContractDialog(row) {
      this.contractForm = row ? { ...row } : { empId: this.detailEmp?.empId, status: 'active', fileIds: '', contractNo: '' }
      this.contractDialogVisible = true
    },
    submitContract() {
      if (!this.detailEmp) return
      this.contractSubmitting = true
      const api = this.contractForm.contractId ? updateContract : addContract
      const payload = { ...this.contractForm, empId: this.detailEmp.empId }
      if (payload.startDate) payload.startDate = this.formatDateOnly(payload.startDate)
      if (payload.endDate) payload.endDate = this.formatDateOnly(payload.endDate)
      api(payload)
        .then(() => {
          this.$message.success('已保存')
          this.contractDialogVisible = false
          this.loadContracts(this.detailEmp.empId)
        })
        .finally(() => {
          this.contractSubmitting = false
        })
    },
    delContractRow(row) {
      this.$confirm('确认删除该合同吗？', '提示', { type: 'warning' }).then(() => {
        delContract(row.contractId).then(() => {
          this.$message.success('已删除')
          this.loadContracts(this.detailEmp.empId)
        })
      })
    },
    loadCertificates(empId) {
      if (!empId) return
      this.certLoading = true
      listCertificate({ empId, pageNum: 1, pageSize: 200 })
        .then(res => {
          this.certList = res.rows || []
        })
        .finally(() => {
          this.certLoading = false
        })
    },
    loadPositions() {
      this.positionLoading = true
      listPosition({ pageNum: 1, pageSize: 200 })
        .then(res => {
          this.positionOptions = res.rows || []
        })
        .finally(() => {
          this.positionLoading = false
        })
    },
    loadEmpOrgRel(empId) {
      if (!empId) return
      this.relLoading = true
      listEmpOrgPosition({ empId, pageNum: 1, pageSize: 200 })
        .then(res => {
          this.relList = res.rows || []
        })
        .finally(() => {
          this.relLoading = false
        })
    },
    openRelDialog(row) {
      if (!this.detailEmp) return
      this.relForm = row
        ? { ...row }
        : {
            empId: this.detailEmp.empId,
            orgId: this.detailEmp.mainOrgId || this.orgSelected || (this.orgTree[0] && this.orgTree[0].orgId),
            positionId: '',
            isPrimary: 0,
            startDate: '',
            endDate: '',
            remark: ''
          }
      this.relDialogVisible = true
      this.$nextTick(() => this.$refs.relFormRef && this.$refs.relFormRef.clearValidate())
    },
    submitRel() {
      this.$refs.relFormRef.validate(valid => {
        if (!valid) return
        this.relSubmitting = true
        const api = this.relForm.relId ? updateEmpOrgPosition : addEmpOrgPosition
        const payload = { ...this.relForm }
        if (payload.startDate) payload.startDate = this.formatDateOnly(payload.startDate)
        if (payload.endDate) payload.endDate = this.formatDateOnly(payload.endDate)
        api(payload)
          .then(() => {
            this.$message.success('已保存')
            this.relDialogVisible = false
            this.loadEmpOrgRel(this.detailEmp.empId)
          })
          .finally(() => {
            this.relSubmitting = false
          })
      })
    },
    delRel(row) {
      this.$confirm('确认删除该关系吗？', '提示', { type: 'warning' }).then(() => {
        delEmpOrgPosition(row.relId).then(() => {
          this.$message.success('已删除')
          this.loadEmpOrgRel(this.detailEmp.empId)
        })
      })
    },
    openCertDialog(row) {
      this.certForm = row
        ? { ...row }
        : {
            empId: this.detailEmp?.empId,
            fileIds: '',
            issuedBy: '',
            certNo: ''
          }
      this.certDialogVisible = true
    },
    submitCert() {
      if (!this.detailEmp) return
      this.certSubmitting = true
      const api = this.certForm.certId ? updateCertificate : addCertificate
      const payload = { ...this.certForm, empId: this.detailEmp.empId }
      if (payload.validFrom) payload.validFrom = this.formatDateOnly(payload.validFrom)
      api(payload)
        .then(() => {
          this.$message.success('已保存')
          this.certDialogVisible = false
          this.loadCertificates(this.detailEmp.empId)
        })
        .finally(() => {
          this.certSubmitting = false
        })
    },
    delCertRow(row) {
      this.$confirm('确认删除该证书吗？', '提示', { type: 'warning' }).then(() => {
        delCertificate(row.certId).then(() => {
          this.$message.success('已删除')
          this.loadCertificates(this.detailEmp.empId)
        })
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.hrm-page {
  padding: 16px 20px 32px;
  background: #f8f9fb;
}
.panel-grid {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: 12px;
}
.metal-panel {
  border: 1px solid #d7d9df;
  border-radius: 10px;
  background: #fff;
}
.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: 600;
  color: #303133;
}
.actions-inline {
  display: flex;
  gap: 8px;
  align-items: center;
}
.detail-wrap {
  padding-right: 4px;
}
.basic-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}
.preview-placeholder {
  color: #a0a3ad;
  font-size: 13px;
  padding: 12px;
  background: #fafafa;
  border: 1px dashed #ebeef5;
  border-radius: 6px;
}
.custom-tree-node {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}
.tree-tag {
  margin: 0;
  align-self: center;
  height: 22px;
  line-height: 22px;
  padding: 0 8px;
}
.org-dialog ::v-deep .el-dialog__body {
  background: linear-gradient(180deg, #fbfcff 0%, #f7f9fc 100%);
  padding: 18px 20px 10px;
}
.org-form .el-form-item {
  margin-bottom: 14px;
}
.org-form .el-input-group__append {
  padding: 0;
  background: transparent;
  border: none;
}
.org-form .el-input-group__append .el-button {
  height: 32px;
  margin: 0;
  border-radius: 0 4px 4px 0;
}
.org-form .el-form-item__label {
  font-weight: 600;
  color: #3c4257;
}
.org-dialog ::v-deep .el-dialog__header {
  border-bottom: 1px solid #ebeef5;
  padding-bottom: 10px;
}
.inline-field {
  display: flex;
  align-items: center;
  gap: 6px;
}
.inline-field .el-input {
  flex: 1;
}
.inline-field .el-button {
  border-radius: 6px;
  box-shadow: 0 2px 6px rgba(64, 158, 255, 0.2);
  height: 32px;
  line-height: 32px;
  padding: 0 12px;
}
.field-hint {
  color: #9aa2b1;
  font-size: 12px;
  line-height: 16px;
  margin-top: 4px;
}
@media (max-width: 1200px) {
  .panel-grid {
    grid-template-columns: 1fr;
  }
}
</style>
