<template>
  <div class="hrm-page attendance-page">
    <section class="panel-grid">
      <el-card class="metal-panel flat" shadow="never">
        <div class="card-toolbar">
          <div class="actions-inline">
            <el-button size="mini" type="primary" plain icon="el-icon-plus" @click="openShiftDialog()">新增</el-button>
            <el-button size="mini" plain icon="el-icon-refresh" @click="loadShift">刷新</el-button>
          </div>
        </div>
        <el-table :data="shiftList" v-loading="shiftLoading" height="320" stripe>
          <el-table-column label="名称" prop="shiftName" min-width="140" />
          <el-table-column label="时间段" min-width="180">
            <template slot-scope="scope">{{ scope.row.startTime }} - {{ scope.row.endTime }}</template>
          </el-table-column>
          <el-table-column label="夜班" prop="nightShift" min-width="80">
            <template slot-scope="scope">
              <el-tag size="mini" :type="scope.row.nightShift ? 'warning' : 'info'">
                {{ scope.row.nightShift ? '是' : '否' }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="休息" prop="restMinutes" min-width="100" />
          <el-table-column label="操作" width="140" fixed="right">
            <template slot-scope="scope">
              <el-button size="mini" type="text" @click.stop="openShiftDialog(scope.row)">编辑</el-button>
              <el-button size="mini" type="text" @click.stop="delShift(scope.row)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-card>

      <el-card class="metal-panel flat" shadow="never">
        <div class="card-toolbar">
          <div class="actions-inline">
            <el-date-picker
              v-model="scheduleQuery.date"
              type="date"
              placeholder="日期"
              size="mini"
              style="width: 140px"
              @change="loadSchedule"
            />
            <el-button size="mini" type="primary" plain @click="loadSchedule">查询</el-button>
            <el-button size="mini" plain icon="el-icon-plus" @click="openScheduleDialog()">新增</el-button>
          </div>
        </div>
        <el-table :data="scheduleList" v-loading="scheduleLoading" height="320" stripe>
          <el-table-column label="员工" prop="empId" min-width="120">
            <template slot-scope="scope">
              {{ renderEmp(scope.row.empId) }}
            </template>
          </el-table-column>
          <el-table-column label="日期" prop="workDate" min-width="120" />
          <el-table-column label="班次" prop="shiftId" min-width="140">
            <template slot-scope="scope">
              {{ renderShift(scope.row.shiftId) }}
            </template>
          </el-table-column>
          <el-table-column label="备注" prop="remark" min-width="160" show-overflow-tooltip />
          <el-table-column label="操作" width="140" fixed="right">
            <template slot-scope="scope">
              <el-button size="mini" type="text" @click.stop="openScheduleDialog(scope.row)">编辑</el-button>
              <el-button size="mini" type="text" @click.stop="delSchedule(scope.row)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-card>

      <el-card class="metal-panel flat wide" shadow="never">
        <div class="card-toolbar">
          <div class="actions-inline">
            <el-date-picker
              v-model="punchQuery.range"
              type="daterange"
              start-placeholder="开始"
              end-placeholder="结束"
              size="mini"
              value-format="yyyy-MM-dd"
              @change="loadPunchAndAttend"
            />
          </div>
        </div>
        <div class="dual-tables">
          <div class="table-half">
            <div class="table-title">打卡记录</div>
            <el-table :data="punchList" v-loading="punchLoading" height="230" stripe>
              <el-table-column label="时间" prop="punchTime" min-width="150">
                <template slot-scope="scope">{{ formatDate(scope.row.punchTime) }}</template>
              </el-table-column>
              <el-table-column label="员工" prop="empId" min-width="120">
                <template slot-scope="scope">
                  {{ renderEmp(scope.row.empId) }}
                </template>
              </el-table-column>
              <el-table-column label="来源" prop="source" min-width="100" />
              <el-table-column label="定位/设备" prop="location" min-width="140" show-overflow-tooltip />
              <el-table-column label="操作" width="120" fixed="right">
                <template slot-scope="scope">
                  <el-button size="mini" type="text" @click.stop="openPunchDialog(scope.row)">编辑</el-button>
                  <el-button size="mini" type="text" @click.stop="delPunch(scope.row)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
          </div>
          <div class="table-half">
            <div class="table-title">考勤结果</div>
            <el-table :data="attendList" v-loading="attendLoading" height="230" stripe>
              <el-table-column label="日期" prop="workDate" min-width="120" />
              <el-table-column label="出勤分钟" prop="attendMinutes" min-width="110" />
              <el-table-column label="加班分钟" prop="overtimeMinutes" min-width="110" />
              <el-table-column label="请假分钟" prop="leaveMinutes" min-width="110" />
              <el-table-column label="异常" prop="exceptionMsg" min-width="140" show-overflow-tooltip>
                <template slot-scope="scope">
                  <span :class="['exception-tag', scope.row.exceptionMsg ? 'is-error' : '']">
                    {{ scope.row.exceptionMsg || '正常' }}
                  </span>
                </template>
              </el-table-column>
            </el-table>
          </div>
        </div>
      </el-card>
    </section>

    <!-- 班次弹窗 -->
    <el-dialog :visible.sync="shiftDialogVisible" title="班次" width="420px">
      <el-form ref="shiftForm" :model="shiftForm" :rules="shiftRules" label-width="90px" size="small">
        <el-form-item label="名称" prop="shiftName">
          <el-input v-model="shiftForm.shiftName" placeholder="班次名称" />
        </el-form-item>
        <el-form-item label="开始时间" prop="startTime">
          <el-time-picker v-model="shiftForm.startTime" placeholder="开始时间" style="width: 100%" value-format="HH:mm" />
        </el-form-item>
        <el-form-item label="结束时间" prop="endTime">
          <el-time-picker v-model="shiftForm.endTime" placeholder="结束时间" style="width: 100%" value-format="HH:mm" />
        </el-form-item>
        <el-form-item label="夜班" prop="nightShift">
          <el-switch v-model="shiftForm.nightShift" :active-value="1" :inactive-value="0" />
        </el-form-item>
        <el-form-item label="休息分钟" prop="restMinutes">
          <el-input-number v-model="shiftForm.restMinutes" :min="0" :max="600" controls-position="right" style="width: 100%" />
        </el-form-item>
        <el-form-item label="备注">
          <el-input v-model="shiftForm.remark" type="textarea" :rows="2" placeholder="备注" />
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="shiftDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="shiftSubmitting" @click="submitShift">保存</el-button>
      </div>
    </el-dialog>

    <!-- 排班弹窗 -->
    <el-dialog :visible.sync="scheduleDialogVisible" title="排班" width="420px">
      <el-form ref="scheduleForm" :model="scheduleForm" :rules="scheduleRules" label-width="90px" size="small">
        <el-form-item label="日期" prop="workDate">
          <el-date-picker v-model="scheduleForm.workDate" type="date" placeholder="选择日期" style="width: 100%" value-format="yyyy-MM-dd" />
        </el-form-item>
        <el-form-item label="员工" prop="empId">
          <el-select v-model="scheduleForm.empId" placeholder="选择员工" filterable style="width: 100%">
            <el-option v-for="emp in employeeOptions" :key="emp.empId" :label="`${emp.empName} (${emp.empCode || emp.empId})`" :value="emp.empId" />
          </el-select>
        </el-form-item>
        <el-form-item label="班次" prop="shiftId">
          <el-select v-model="scheduleForm.shiftId" placeholder="选择班次" filterable style="width: 100%">
            <el-option v-for="shift in shiftList" :key="shift.shiftId" :label="`${shift.shiftName} ${shift.startTime || ''}-${shift.endTime || ''}`" :value="shift.shiftId" />
          </el-select>
        </el-form-item>
        <el-form-item label="备注">
          <el-input v-model="scheduleForm.remark" type="textarea" :rows="2" placeholder="备注" />
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="scheduleDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="scheduleSubmitting" @click="submitSchedule">保存</el-button>
      </div>
    </el-dialog>

    <!-- 打卡弹窗 -->
    <el-dialog :visible.sync="punchDialogVisible" title="打卡" width="420px">
      <el-form ref="punchForm" :model="punchForm" :rules="punchRules" label-width="90px" size="small">
        <el-form-item label="员工" prop="empId">
          <el-select v-model="punchForm.empId" placeholder="选择员工" filterable style="width: 100%">
            <el-option v-for="emp in employeeOptions" :key="emp.empId" :label="`${emp.empName} (${emp.empCode || emp.empId})`" :value="emp.empId" />
          </el-select>
        </el-form-item>
        <el-form-item label="时间" prop="punchTime">
          <el-date-picker
            v-model="punchForm.punchTime"
            type="datetime"
            placeholder="选择时间"
            style="width: 100%"
            value-format="yyyy-MM-dd HH:mm:ss"
          />
        </el-form-item>
        <el-form-item label="来源" prop="source">
          <el-select v-model="punchForm.source" placeholder="选择来源" style="width: 100%">
            <el-option label="手工" value="manual" />
            <el-option label="设备" value="device" />
            <el-option label="移动" value="mobile" />
          </el-select>
        </el-form-item>
        <el-form-item label="定位/设备" prop="location">
          <el-input v-model="punchForm.location" placeholder="如：门禁A / GPS坐标" />
        </el-form-item>
        <el-form-item label="备注">
          <el-input v-model="punchForm.remark" type="textarea" :rows="2" placeholder="备注" />
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="punchDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="punchSubmitting" @click="submitPunch">保存</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  listEmployee,
  listShift,
  listSchedule,
  listPunch,
  listAttendCalc,
  addShift,
  updateShift,
  delShift,
  addSchedule,
  updateSchedule,
  delSchedule,
  addPunch,
  updatePunch,
  delPunch
} from '@/api/hrm'

export default {
  name: 'HrmAttendance',
  data() {
    return {
      employeeOptions: [],
      shiftList: [],
      shiftLoading: false,
      scheduleList: [],
      scheduleLoading: false,
      scheduleQuery: { date: '' },
      punchList: [],
      punchLoading: false,
      punchQuery: { range: [] },
      attendList: [],
      attendLoading: false,
      shiftDialogVisible: false,
      shiftForm: {},
      shiftRules: {
        shiftName: [{ required: true, message: '请输入名称', trigger: 'blur' }],
        startTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
        endTime: [{ required: true, message: '请选择结束时间', trigger: 'change' }]
      },
      shiftSubmitting: false,
      scheduleDialogVisible: false,
      scheduleForm: {},
      scheduleRules: {
        workDate: [{ required: true, message: '请选择日期', trigger: 'change' }],
        empId: [{ required: true, message: '请选择员工', trigger: 'change' }],
        shiftId: [{ required: true, message: '请选择班次', trigger: 'change' }]
      },
      scheduleSubmitting: false,
      punchDialogVisible: false,
      punchForm: {},
      punchRules: {
        empId: [{ required: true, message: '请选择员工', trigger: 'change' }],
        punchTime: [{ required: true, message: '请选择时间', trigger: 'change' }],
        source: [{ required: true, message: '请选择来源', trigger: 'change' }],
        location: [{ required: true, message: '请输入定位/设备', trigger: 'blur' }]
      },
      punchSubmitting: false
    }
  },
  created() {
    this.loadEmployees()
    this.loadShift()
    this.loadSchedule()
    this.loadPunchAndAttend()
  },
  methods: {
    formatDate(val) {
      if (!val) return ''
      const date = new Date(val)
      const pad = n => (n < 10 ? `0${n}` : n)
      return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`
    },
    loadEmployees() {
      listEmployee({ pageNum: 1, pageSize: 500 })
        .then(res => {
          this.employeeOptions = res.rows || []
        })
    },
    loadShift() {
      this.shiftLoading = true
      listShift({ pageNum: 1, pageSize: 200 })
        .then(res => {
          this.shiftList = res.rows || []
        })
        .finally(() => {
          this.shiftLoading = false
        })
    },
    loadSchedule() {
      this.scheduleLoading = true
      listSchedule({ ...this.scheduleQuery, pageNum: 1, pageSize: 200 })
        .then(res => {
          this.scheduleList = res.rows || []
        })
        .finally(() => {
          this.scheduleLoading = false
        })
    },
    loadPunchAndAttend() {
      this.punchLoading = true
      this.attendLoading = true
      const [startTime, endTime] = this.punchQuery.range || []
      listPunch({ pageNum: 1, pageSize: 200, startTime, endTime })
        .then(res => {
          this.punchList = res.rows || []
        })
        .finally(() => {
          this.punchLoading = false
        })
      listAttendCalc({ pageNum: 1, pageSize: 200 })
        .then(res => {
          this.attendList = res.rows || []
        })
        .finally(() => {
          this.attendLoading = false
        })
    },
    renderEmp(empId) {
      const emp = this.employeeOptions.find(e => e.empId === empId)
      if (!emp) return empId || ''
      return `${emp.empName}${emp.empCode ? ` (${emp.empCode})` : ''}`
    },
    renderShift(shiftId) {
      const shift = this.shiftList.find(s => s.shiftId === shiftId)
      if (!shift) return shiftId || ''
      return `${shift.shiftName}${shift.startTime ? ` ${shift.startTime}-${shift.endTime}` : ''}`
    },
    // 班次
    openShiftDialog(row) {
      this.shiftForm = row
        ? { ...row }
        : { shiftName: '', startTime: '', endTime: '', nightShift: 0, restMinutes: 0, remark: '' }
      this.shiftDialogVisible = true
      this.$nextTick(() => this.$refs.shiftForm && this.$refs.shiftForm.clearValidate())
    },
    submitShift() {
      this.$refs.shiftForm.validate(valid => {
        if (!valid) return
        this.shiftSubmitting = true
        const api = this.shiftForm.shiftId ? updateShift : addShift
        api(this.shiftForm)
          .then(() => {
            this.$message.success('已保存')
            this.shiftDialogVisible = false
            this.loadShift()
          })
          .finally(() => {
            this.shiftSubmitting = false
          })
      })
    },
    delShift(row) {
      this.$confirm('确认删除该班次吗？', '提示', { type: 'warning' }).then(() => {
        delShift(row.shiftId).then(() => {
          this.$message.success('已删除')
          this.loadShift()
        })
      })
    },
    // 排班
    openScheduleDialog(row) {
      this.scheduleForm = row
        ? { ...row }
        : { workDate: '', empId: '', shiftId: '', remark: '' }
      this.scheduleDialogVisible = true
      this.$nextTick(() => this.$refs.scheduleForm && this.$refs.scheduleForm.clearValidate())
    },
    submitSchedule() {
      this.$refs.scheduleForm.validate(valid => {
        if (!valid) return
        this.scheduleSubmitting = true
        const api = this.scheduleForm.scheduleId ? updateSchedule : addSchedule
        api(this.scheduleForm)
          .then(() => {
            this.$message.success('已保存')
            this.scheduleDialogVisible = false
            this.loadSchedule()
          })
          .finally(() => {
            this.scheduleSubmitting = false
          })
      })
    },
    delSchedule(row) {
      this.$confirm('确认删除该排班吗？', '提示', { type: 'warning' }).then(() => {
        delSchedule(row.scheduleId).then(() => {
          this.$message.success('已删除')
          this.loadSchedule()
        })
      })
    },
    // 打卡
    openPunchDialog(row) {
      this.punchForm = row
        ? { ...row }
        : { empId: '', punchTime: '', source: 'manual', location: '', remark: '' }
      this.punchDialogVisible = true
      this.$nextTick(() => this.$refs.punchForm && this.$refs.punchForm.clearValidate())
    },
    submitPunch() {
      this.$refs.punchForm.validate(valid => {
        if (!valid) return
        this.punchSubmitting = true
        const api = this.punchForm.punchId ? updatePunch : addPunch
        api(this.punchForm)
          .then(() => {
            this.$message.success('已保存')
            this.punchDialogVisible = false
            this.loadPunchAndAttend()
          })
          .finally(() => {
            this.punchSubmitting = false
          })
      })
    },
    delPunch(row) {
      this.$confirm('确认删除该打卡记录吗？', '提示', { type: 'warning' }).then(() => {
        delPunch(row.punchId).then(() => {
          this.$message.success('已删除')
          this.loadPunchAndAttend()
        })
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.attendance-page {
  padding: 0;
  background: transparent;
}
.panel-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  align-items: start;
}
.metal-panel {
  border: none;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}
.metal-panel :deep(.el-card__body) {
  padding: 0;
  background: transparent;
}
.card-toolbar {
  display: flex;
  justify-content: flex-end;
  padding: 4px 0 8px;
}
.actions-inline {
  display: flex;
  gap: 8px;
  align-items: center;
}
.flat :deep(.el-card__body) {
  padding: 0;
}
.flat {
  padding: 0;
}
.wide {
  grid-column: span 2;
}
.flat :deep(.el-table),
.flat :deep(.el-table__body-wrapper),
.flat :deep(.el-table__header-wrapper),
.flat :deep(.el-table__empty-block) {
  background: transparent;
}
.dual-tables {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.table-half {
  border: none;
  border-radius: 0;
  padding: 0;
  background: transparent;
}
.table-title {
  font-weight: 600;
  margin-bottom: 6px;
  color: #1f2937;
}
.exception-tag {
  color: #409eff;
  &.is-error {
    color: #e76f51;
    font-weight: 600;
  }
}
@media (max-width: 1200px) {
  .panel-grid {
    grid-template-columns: 1fr;
  }
  .wide {
    grid-column: span 1;
  }
  .dual-tables {
    grid-template-columns: 1fr;
  }
}
</style>
