import { useState, useRef } from 'react'
import { Link } from 'react-router-dom'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { toast } from 'sonner'
import { CalendarCheck, CheckCircle, Clock, AlertCircle, Plus, Trash2, Calendar, Users, BarChart3, Plane, Upload, Download, X, Send, Loader2, CheckCheck, Edit } from 'lucide-react'
import { attendanceApi, employeeApi, rosterApi } from '../lib/api-services'
import { useAuthStore } from '../store/authStore'
import { usePageSize } from '../hooks/usePageSize'
import Card from '../components/ui/Card'
import Button from '../components/ui/Button'
import { Input, Label, Select } from '../components/ui/Input'
import Modal from '../components/ui/Modal'
import Pagination from '../components/ui/Pagination'
import EmptyState from '../components/ui/EmptyState'
import { InlineAlert } from '../components/ui/InlineAlert'
import PageGuide from '../components/ui/PageGuide'
import { useConfirm } from '../hooks/useConfirm'

const STATUS_CONFIG: Record<string, { label: string; color: string; bg: string; icon: typeof CheckCircle }> = {
  PENDING: { label: '待确认', color: 'text-amber-700', bg: 'bg-amber-100', icon: Clock },
  CONFIRMED: { label: '已确认', color: 'text-green-700', bg: 'bg-green-100', icon: CheckCircle },
  DISPUTED: { label: '有异议', color: 'text-red-700', bg: 'bg-red-100', icon: AlertCircle },
}

const ATTENDANCE_STATUS: Record<string, string> = {
  NORMAL: '正常',
  LATE: '迟到',
  EARLY_LEAVE: '早退',
  ABSENT: '缺勤',
  LEAVE: '请假',
  BUSINESS_TRIP: '出差',
  UNREGISTERED: '未打卡',
}

const LEAVE_TYPES: Record<string, string> = {
  SICK: '病假',
  PERSONAL: '事假',
  ANNUAL: '年假',
  MATERNITY: '产假',
  OTHER: '其他',
}

const TABS = [
  { key: 'confirm', label: '考勤确认', icon: CalendarCheck },
  { key: 'daily', label: '每日出勤', icon: Users },
  { key: 'monthly', label: '月度报表', icon: BarChart3 },
  { key: 'leaves', label: '休假记录', icon: Plane },
]

export default function Attendance() {
  const [activeTab, setActiveTab] = useState('confirm')

  return (
    <div className="space-y-4">
      <PageGuide>
        考勤管理，支持出勤查询、月度报表和休假记录。流程：①每日打卡或导入考勤 → ②月度汇总 → ③考勤确认。关联：考勤数据影响薪税管理的工资和加班费计算。排班设置请前往「排班管理」。
      </PageGuide>
      <div>
        <div className="flex items-center gap-2">
          <CalendarCheck className="h-5 w-5 text-primary" />
          <h1 className="text-base font-semibold">考勤管理</h1>
        </div>
        <p className="mt-1 text-sm text-gray-500">出勤查询、月度报表、休假记录</p>
      </div>

      {/* Tab 导航 */}
      <div className="flex flex-wrap gap-1 border-b border-gray-200">
        {TABS.map(tab => {
          const Icon = tab.icon
          return (
            <button
              key={tab.key}
              onClick={() => setActiveTab(tab.key)}
              className={`flex items-center gap-1.5 px-3 py-2 text-sm font-medium border-b-2 transition-colors ${
                activeTab === tab.key
                  ? 'border-primary text-primary'
                  : 'border-transparent text-gray-500 hover:text-gray-700'
              }`}
            >
              <Icon className="w-4 h-4" />
              {tab.label}
            </button>
          )
        })}
      </div>

      {activeTab === 'confirm' && <ConfirmTab onGoToTab={setActiveTab} />}
      {activeTab === 'daily' && <DailyTab />}
      {activeTab === 'monthly' && <MonthlyTab />}
      {activeTab === 'leaves' && <LeavesTab />}
    </div>
  )
}

// ========== 考勤确认 Tab ==========
function ConfirmTab({ onGoToTab }: { onGoToTab?: (tab: string) => void }) {
  const queryClient = useQueryClient()
  const confirm = useConfirm()
  const [month, setMonth] = useState(new Date().toISOString().slice(0, 7))
  const [filterDepartment, setFilterDepartment] = useState('')
  const [filterStatus, setFilterStatus] = useState('')
  const [showImport, setShowImport] = useState(false)
  const [importFile, setImportFile] = useState<File | null>(null)
  const [importResult, setImportResult] = useState<any>(null)
  const [importing, setImporting] = useState(false)
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set())
  const [searchQuery, setSearchQuery] = useState('')
  const [editItem, setEditItem] = useState<any>(null)
  const [editForm, setEditForm] = useState({ workDays: 0, lateCount: 0, earlyLeaveCount: 0, absentDays: 0, leaveDays: 0, overtimeHours: 0, overtimePay: 0, deductionAmount: 0 })
  const fileInputRef = useRef<HTMLInputElement>(null)
  const pageSize = usePageSize()
  const [page, setPage] = useState(1)

  const { data: list, isLoading } = useQuery<any>({
    queryKey: ['attendance', month, filterDepartment, filterStatus],
    queryFn: async () => {
      const params: any = { month }
      if (filterDepartment) params.department = filterDepartment
      if (filterStatus) params.status = filterStatus
      return await attendanceApi.list({ month, department: filterDepartment || undefined, status: filterStatus || undefined })
    },
  })

  const { data: stats } = useQuery<any>({
    queryKey: ['attendance-stats', month],
    queryFn: async () => {
      return await attendanceApi.stats(month)
    },
  })

  const { data: departmentList } = useQuery<string[]>({
    queryKey: ['roster-departments'],
    queryFn: () => rosterApi.departments(),
  })

  const { data: publishRecords } = useQuery<any[]>({
    queryKey: ['attendance-publish-records'],
    queryFn: async () => {
      return await attendanceApi.publishRecords()
    },
  })

  const publishMutation = useMutation({
    mutationFn: async () => {
      return await attendanceApi.publish(month)
    },
    onSuccess: () => {
      toast.success(`${month}月考勤表已发布`)
      queryClient.invalidateQueries({ queryKey: ['attendance-publish-records'] })
    },
    onError: (err: any) => toast.error(err?.response?.data?.error?.message || '发布失败'),
  })

  const cancelPublishMutation = useMutation({
    mutationFn: async (id: string) => {
      return await attendanceApi.cancelPublish(id)
    },
    onSuccess: () => {
      toast.success('已取消发布')
      queryClient.invalidateQueries({ queryKey: ['attendance-publish-records'] })
    },
    onError: (err: any) => toast.error(err?.response?.data?.error?.message || '取消失败'),
  })

  const batchConfirmMutation = useMutation({
    mutationFn: async (params: { all?: boolean; ids?: string[] }) => {
      return await attendanceApi.batchConfirm({ month, ...params })
    },
    onSuccess: (data: any) => {
      toast.success(`已批量确认 ${data.count} 条考勤记录`)
      queryClient.invalidateQueries({ queryKey: ['attendance'] })
      queryClient.invalidateQueries({ queryKey: ['attendance-stats'] })
      setSelectedIds(new Set())
    },
    onError: (err: any) => toast.error(err?.response?.data?.error?.message || '批量确认失败'),
  })

  const singleConfirmMutation = useMutation({
    mutationFn: async (id: string) => {
      return await attendanceApi.confirm({ employeeId: list.find((i: any) => i.id === id)?.employeeId, month })
    },
    onSuccess: () => {
      toast.success('已确认')
      queryClient.invalidateQueries({ queryKey: ['attendance'] })
      queryClient.invalidateQueries({ queryKey: ['attendance-stats'] })
    },
    onError: (err: any) => toast.error(err?.response?.data?.error?.message || '确认失败'),
  })

  const editMutation = useMutation({
    mutationFn: async (data: any) => {
      // 通过批量创建接口更新考勤确认记录（upsert 语义）
      return await attendanceApi.batchCreate({
        month: data.month,
        items: [{
          employeeId: data.employeeId,
          workDays: data.workDays,
          weekdayHours: 0,
          weekendHours: 0,
          holidayHours: 0,
          overtimePay: data.overtimePay,
          deductionAmount: data.deductionAmount || 0,
        }],
      })
    },
    onSuccess: () => {
      toast.success('考勤记录已修改')
      queryClient.invalidateQueries({ queryKey: ['attendance'] })
      queryClient.invalidateQueries({ queryKey: ['attendance-stats'] })
      setEditItem(null)
    },
    onError: (err: any) => toast.error(err?.response?.data?.error?.message || '修改失败'),
  })

  const currentPublish = publishRecords?.find((r: any) => r.month === month && r.status === 'PUBLISHED')
  const pendingCount = stats?.pending || 0
  const allList = list || []
  const filteredList = allList.filter((i: any) => {
    if (searchQuery.trim()) {
      const q = searchQuery.trim().toLowerCase()
      if (!i.employee?.name?.toLowerCase().includes(q) && !i.employee?.department?.toLowerCase().includes(q)) return false
    }
    return true
  })
  const pendingItems = filteredList.filter((i: any) => i.status === 'PENDING')
  const allPendingSelected = pendingItems.length > 0 && pendingItems.every((i: any) => selectedIds.has(i.id))
  const total = filteredList.length
  const pagedList = filteredList.slice((page - 1) * pageSize, page * pageSize)

  const toggleSelect = (id: string) => {
    const next = new Set(selectedIds)
    if (next.has(id)) next.delete(id)
    else next.add(id)
    setSelectedIds(next)
  }

  const toggleSelectAllPending = () => {
    if (allPendingSelected) {
      const next = new Set(selectedIds)
      pendingItems.forEach((i: any) => next.delete(i.id))
      setSelectedIds(next)
    } else {
      const next = new Set(selectedIds)
      pendingItems.forEach((i: any) => next.add(i.id))
      setSelectedIds(next)
    }
  }

  // 流程步骤
  const FLOW_STEPS = [
    { label: '导入考勤', desc: 'Excel 批量导入', done: (list?.length || 0) > 0 },
    { label: 'HR 确认', desc: `待确认 ${pendingCount} 人`, done: pendingCount === 0 && (list?.length || 0) > 0 },
    { label: '发布考勤表', desc: currentPublish ? '已发布' : '未发布', done: !!currentPublish },
    { label: '员工确认', desc: stats ? `已确认 ${stats.confirmed}/${stats.total}` : '', done: stats?.confirmed === stats?.total && stats?.total > 0 },
  ]

  return (
    <div className="space-y-3">
      {/* 流程指示器 */}
      <div className="flex items-center gap-1 overflow-x-auto pb-1">
        {FLOW_STEPS.map((step, i) => (
          <div key={i} className="flex items-center gap-1 shrink-0">
            <div className={`flex items-center gap-1.5 px-2.5 py-1.5 rounded-lg text-xs ${step.done ? 'bg-green-50 text-green-700' : 'bg-gray-50 text-gray-500'}`}>
              {step.done ? <CheckCircle className="w-3.5 h-3.5" /> : <Clock className="w-3.5 h-3.5" />}
              <span className="font-medium">{step.label}</span>
              <span className="text-gray-400">{step.desc}</span>
            </div>
            {i < FLOW_STEPS.length - 1 && <span className="text-gray-300">→</span>}
          </div>
        ))}
      </div>

      {/* 指引提示 */}
      {!currentPublish && pendingCount > 0 && (
        <InlineAlert type="info" title="考勤确认流程">
          请核对考勤数据后批量确认，确认无误后点击「发布考勤表」推送给员工端确认。员工有异议时可提交异议说明。
        </InlineAlert>
      )}
      {currentPublish && (
        <InlineAlert type="success" title="考勤表已发布">
          {month}月考勤表已发布至员工端，员工可自行查看并确认。已确认 {stats?.confirmed || 0}/{stats?.total || 0} 人。
        </InlineAlert>
      )}
      {stats?.disputed > 0 && (
        <InlineAlert type="warning" title="有员工提出异议">
          {stats.disputed} 名员工对考勤数据有异议，请查看异议说明并处理。
        </InlineAlert>
      )}

      <div className="flex items-center gap-2 justify-between flex-wrap">
        <div className="flex items-center gap-2">
          {pendingCount > 0 && (
            <>
              <Button
                size="sm"
                variant="secondary"
                onClick={toggleSelectAllPending}
              >
                {allPendingSelected ? '取消全选' : '全选待确认'}
              </Button>
              {selectedIds.size > 0 && (
                <Button
                  size="sm"
                  onClick={async () => {
                    const ok = await confirm({ title: '批量确认考勤', message: `确认将选中的 ${selectedIds.size} 条考勤记录标记为已确认？` })
                    if (ok) batchConfirmMutation.mutate({ ids: Array.from(selectedIds) })
                  }}
                  disabled={batchConfirmMutation.isPending}
                >
                  <CheckCheck className="w-3.5 h-3.5 mr-1" />
                  确认选中 ({selectedIds.size})
                </Button>
              )}
              <Button
                size="sm"
                variant="secondary"
                onClick={async () => {
                  const ok = await confirm({ title: '全部确认', message: `确认将全部 ${pendingCount} 条待确认记录标记为已确认？` })
                  if (ok) batchConfirmMutation.mutate({ all: true })
                }}
                disabled={batchConfirmMutation.isPending}
              >
                全部确认 ({pendingCount})
              </Button>
            </>
          )}
        </div>
        <div className="flex items-center gap-2">
          {currentPublish ? (
            <Button size="sm" variant="secondary" onClick={async () => {
              const ok = await confirm({ title: '取消发布', message: '取消发布后员工端将无法查看该月考勤表，确定操作？' })
              if (ok) cancelPublishMutation.mutate(currentPublish.id)
            }}>
              <X className="w-3.5 h-3.5 mr-1" />取消发布
            </Button>
          ) : (
            <Button size="sm" onClick={() => publishMutation.mutate()} disabled={publishMutation.isPending || pendingCount > 0}>
              {publishMutation.isPending ? <Loader2 className="w-3.5 h-3.5 mr-1 animate-spin" /> : <Send className="w-3.5 h-3.5 mr-1" />}
              发布考勤表
            </Button>
          )}
          <Button size="sm" variant="secondary" onClick={() => setShowImport(true)}>
            <Upload className="w-3.5 h-3.5 mr-1" />导入考勤
          </Button>
          <input
            type="text"
            placeholder="搜索姓名或部门"
            value={searchQuery}
            onChange={e => { setSearchQuery(e.target.value); setPage(1) }}
            className="px-3 py-1.5 text-sm border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary w-44"
          />
          <select
            value={filterStatus}
            onChange={e => setFilterStatus(e.target.value)}
            className="h-9 rounded-md border border-gray-200 bg-white px-3 text-sm text-gray-700 shadow-sm outline-none transition focus:border-primary focus:ring-2 focus:ring-primary/10"
          >
            <option value="">全部状态</option>
            <option value="PENDING">待确认</option>
            <option value="CONFIRMED">已确认</option>
            <option value="DISPUTED">有异议</option>
          </select>
          <select
            value={filterDepartment}
            onChange={e => setFilterDepartment(e.target.value)}
            className="h-9 rounded-md border border-gray-200 bg-white px-3 text-sm text-gray-700 shadow-sm outline-none transition focus:border-primary focus:ring-2 focus:ring-primary/10"
          >
            <option value="">全部部门</option>
            {departmentList?.map((d: string) => <option key={d} value={d}>{d}</option>)}
          </select>
          <input
            type="month"
            value={month}
            onChange={e => setMonth(e.target.value)}
            className="px-3 py-1.5 text-sm border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"
          />
        </div>
      </div>

      {stats && (
        <div className="grid grid-cols-2 sm:grid-cols-4 gap-2">
          {[
            { label: '总计', value: stats.total, color: 'text-gray-700' },
            { label: '待确认', value: stats.pending, color: 'text-amber-600' },
            { label: '已确认', value: stats.confirmed, color: 'text-green-600' },
            { label: '有异议', value: stats.disputed, color: 'text-red-600' },
          ].map(s => (
            <Card key={s.label} className="text-center">
              <div className={`text-lg font-bold ${s.color}`}>{s.value}</div>
              <div className="text-xs text-gray-500">{s.label}</div>
            </Card>
          ))}
        </div>
      )}

      {isLoading ? (
        <div className="text-center py-8 text-gray-500">加载中...</div>
      ) : total === 0 ? (
        <EmptyState title="本月暂无考勤确认记录" description="请先批量导入考勤数据" />
      ) : (
        <>
        <div className="space-y-2">
          {pagedList.map((item: any) => {
            const config = STATUS_CONFIG[item.status] || STATUS_CONFIG.PENDING
            const StatusIcon = config.icon
            const isSelected = selectedIds.has(item.id)
            return (
              <Card key={item.id}>
                <div className="flex items-center justify-between">
                  <div className="flex items-center gap-3 flex-1 min-w-0">
                    {item.status === 'PENDING' && (
                      <input
                        type="checkbox"
                        checked={isSelected}
                        onChange={() => toggleSelect(item.id)}
                        className="w-4 h-4 rounded border-gray-300 text-primary focus:ring-primary shrink-0"
                      />
                    )}
                    <div className="flex items-center justify-center w-8 h-8 rounded-lg bg-gray-50 flex-shrink-0">
                      <CalendarCheck className="w-4 h-4 text-gray-600" />
                    </div>
                    <div className="flex-1 min-w-0">
                      <div className="flex items-center gap-2">
                        <span className="text-sm font-medium">{item.employee?.name}</span>
                        <span className="text-xs text-gray-500">{item.employee?.department}</span>
                      </div>
                      <div className="flex items-center gap-3 text-xs text-gray-500 mt-0.5">
                        <span>出勤 {item.workDays} 天</span>
                        <span>工作日加班 {item.weekdayHours}h</span>
                        <span>周末加班 {item.weekendHours}h</span>
                        <span>法定加班 {item.holidayHours}h</span>
                        <span className="text-gray-700">加班费 ¥{item.overtimePay?.toFixed(2)}</span>
                        {item.deductionAmount > 0 && <span className="text-danger">扣款 ¥{item.deductionAmount?.toFixed(2)}</span>}
                      </div>
                      {item.disputeNote && (
                        <div className="text-xs text-red-600 mt-1">异议说明：{item.disputeNote}</div>
                      )}
                    </div>
                  </div>
                  <div className="flex items-center gap-2 flex-shrink-0">
                    {item.status === 'PENDING' && (
                      <>
                        <button
                          className="text-xs text-primary hover:underline"
                          onClick={() => singleConfirmMutation.mutate(item.id)}
                          disabled={singleConfirmMutation.isPending}
                        >
                          确认
                        </button>
                        <button
                          className="text-xs text-gray-500 hover:text-primary"
                          onClick={() => {
                            setEditItem(item)
                            setEditForm({
                              workDays: item.workDays || 0,
                              lateCount: item.lateCount || 0,
                              earlyLeaveCount: item.earlyLeaveCount || 0,
                              absentDays: item.absentDays || 0,
                              leaveDays: item.leaveDays || 0,
                              overtimeHours: (item.weekdayHours || 0) + (item.weekendHours || 0) + (item.holidayHours || 0),
                              overtimePay: item.overtimePay || 0,
                              deductionAmount: item.deductionAmount || 0,
                            })
                          }}
                        >
                          编辑
                        </button>
                      </>
                    )}
                    <div className={`flex items-center gap-1 px-2 py-1 rounded-lg ${config.bg} ${config.color}`}>
                      <StatusIcon className="w-3.5 h-3.5" />
                      <span className="text-xs font-medium">{config.label}</span>
                    </div>
                  </div>
                </div>
              </Card>
            )
          })}
        </div>
        {editItem && (
          <div className="fixed inset-0 bg-black/30 flex items-center justify-center z-50 p-4" onClick={() => setEditItem(null)}>
            <Card className="max-w-md w-full" >
              <div onClick={(e) => e.stopPropagation()} className="p-4">
                <div className="flex items-center justify-between mb-3">
                  <h2 className="text-sm font-medium">编辑考勤 — {editItem.employee?.name}</h2>
                  <button onClick={() => setEditItem(null)} className="text-gray-400 hover:text-gray-600"><X className="w-4 h-4" /></button>
                </div>
                <div className="grid grid-cols-2 gap-3">
                  <div>
                    <label className="text-xs text-gray-500">出勤天数</label>
                    <input type="number" min="0" className="w-full px-2 py-1.5 text-sm border rounded-md" value={editForm.workDays}
                      onChange={(e) => setEditForm({ ...editForm, workDays: Number(e.target.value) })} />
                  </div>
                  <div>
                    <label className="text-xs text-gray-500">迟到次数</label>
                    <input type="number" min="0" className="w-full px-2 py-1.5 text-sm border rounded-md" value={editForm.lateCount}
                      onChange={(e) => setEditForm({ ...editForm, lateCount: Number(e.target.value) })} />
                  </div>
                  <div>
                    <label className="text-xs text-gray-500">早退次数</label>
                    <input type="number" min="0" className="w-full px-2 py-1.5 text-sm border rounded-md" value={editForm.earlyLeaveCount}
                      onChange={(e) => setEditForm({ ...editForm, earlyLeaveCount: Number(e.target.value) })} />
                  </div>
                  <div>
                    <label className="text-xs text-gray-500">缺勤天数</label>
                    <input type="number" min="0" className="w-full px-2 py-1.5 text-sm border rounded-md" value={editForm.absentDays}
                      onChange={(e) => setEditForm({ ...editForm, absentDays: Number(e.target.value) })} />
                  </div>
                  <div>
                    <label className="text-xs text-gray-500">请假天数</label>
                    <input type="number" min="0" className="w-full px-2 py-1.5 text-sm border rounded-md" value={editForm.leaveDays}
                      onChange={(e) => setEditForm({ ...editForm, leaveDays: Number(e.target.value) })} />
                  </div>
                  <div>
                    <label className="text-xs text-gray-500">加班工时</label>
                    <input type="number" min="0" step="0.5" className="w-full px-2 py-1.5 text-sm border rounded-md" value={editForm.overtimeHours}
                      onChange={(e) => setEditForm({ ...editForm, overtimeHours: Number(e.target.value) })} />
                  </div>
                  <div className="col-span-2">
                    <label className="text-xs text-gray-500">加班费（元）</label>
                    <input type="number" min="0" step="0.01" className="w-full px-2 py-1.5 text-sm border rounded-md" value={editForm.overtimePay}
                      onChange={(e) => setEditForm({ ...editForm, overtimePay: Number(e.target.value) })} />
                  </div>
                  <div className="col-span-2">
                    <label className="text-xs text-gray-500">考勤扣款（元）</label>
                    <input type="number" min="0" step="0.01" className="w-full px-2 py-1.5 text-sm border rounded-md" value={editForm.deductionAmount}
                      onChange={(e) => setEditForm({ ...editForm, deductionAmount: Number(e.target.value) })} placeholder="迟到/早退/旷工等扣款金额" />
                  </div>
                </div>
                <div className="flex justify-end gap-2 mt-4">
                  <Button size="sm" variant="secondary" onClick={() => setEditItem(null)}>取消</Button>
                  <Button size="sm" onClick={() => editMutation.mutate({ employeeId: editItem.employeeId, month, ...editForm })} disabled={editMutation.isPending}>
                    {editMutation.isPending ? '保存中...' : '保存'}
                  </Button>
                </div>
              </div>
            </Card>
          </div>
        )}
        <Pagination page={page} pageSize={pageSize} total={total} onPageChange={setPage} onPageSizeChange={() => setPage(1)} />
        </>
      )}

      {/* 导入考勤弹窗 */}
      {showImport && (
        <div className="fixed inset-0 bg-black/30 flex items-center justify-center z-50 p-4" onClick={() => setShowImport(false)}>
          <Card className="max-w-lg w-full" >
            <div onClick={(e) => e.stopPropagation()} className="p-4">
              <div className="flex items-center justify-between mb-3">
                <h2 className="text-sm font-medium">导入考勤数据 — {month}</h2>
                <button onClick={() => { setShowImport(false); setImportFile(null); setImportResult(null) }} className="text-gray-400 hover:text-gray-600"><X className="w-4 h-4" /></button>
              </div>

              <div className="space-y-3">
                <div className="flex gap-2">
                  <Button size="sm" variant="secondary" onClick={async () => {
                    try {
                      const token = useAuthStore.getState().accessToken
                      const baseURL = import.meta.env.DEV ? 'http://localhost:3000/api/v1' : '/api/v1'
                      const res = await fetch(`${baseURL}/import/monthly-template`, {
                        headers: token ? { Authorization: `Bearer ${token}` } : {},
                      })
                      const blob = await res.blob()
                      const url = URL.createObjectURL(blob)
                      const a = document.createElement('a')
                      a.href = url
                      a.download = '考勤月度导入模板.xlsx'
                      a.click()
                      URL.revokeObjectURL(url)
                    } catch { toast.error('下载模板失败') }
                  }}>
                    <Download className="w-3.5 h-3.5 mr-1" />下载模板
                  </Button>
                </div>

                <div className="text-xs text-gray-500 bg-blue-50/50 rounded-md p-2">
                  模板中「考勤与加班」Sheet 包含：姓名、证件号码、日期、考勤状态、上下班时间、各类加班时长。证件号码优先匹配，未填时用姓名匹配。加班时长为0的行只导入考勤。
                </div>

                <div className="border-2 border-dashed border-gray-200 rounded-lg p-6 text-center">
                  <input ref={fileInputRef} type="file" accept=".xlsx,.xls" className="hidden" id="attendance-import-file" onChange={(e) => { setImportFile(e.target.files?.[0] || null); setImportResult(null) }} />
                  <label htmlFor="attendance-import-file" className="cursor-pointer text-xs text-primary hover:underline">
                    {importFile ? importFile.name : '点击选择 Excel 文件'}
                  </label>
                </div>

                {importResult && (
                  <div className="px-3 py-2 rounded-md bg-green-50 text-green-700 text-xs space-y-1">
                    <div className="font-medium">导入完成</div>
                    {importResult.attendance > 0 && <div>考勤记录：{importResult.attendance} 条</div>}
                    {importResult.overtime > 0 && <div>加班记录：{importResult.overtime} 条</div>}
                    {importResult.discipline > 0 && <div>违纪记录：{importResult.discipline} 条</div>}
                    {importResult.salaryChanges > 0 && <div>薪资调整：{importResult.salaryChanges} 条</div>}
                    {importResult.socialInsChanges > 0 && <div>社保变动：{importResult.socialInsChanges} 条</div>}
                    {importResult.housingFundChanges > 0 && <div>公积金变动：{importResult.housingFundChanges} 条</div>}
                    {importResult.employees > 0 && <div>员工：{importResult.employees} 人</div>}
                    {importResult.contracts > 0 && <div>合同：{importResult.contracts} 份</div>}
                    {importResult.skipped > 0 && <div className="text-amber-600">跳过 {importResult.skipped} 条</div>}
                    {importResult.errors?.length > 0 && (
                      <div className="mt-1 pt-1 border-t border-green-200">
                        {importResult.errors.slice(0, 5).map((e: string, i: number) => <div key={i} className="text-amber-600">{e}</div>)}
                        {importResult.errors.length > 5 && <div className="text-amber-600">...还有 {importResult.errors.length - 5} 条</div>}
                      </div>
                    )}
                    <button
                      className="mt-1 text-primary hover:underline font-medium"
                      onClick={() => { setShowImport(false); setImportFile(null); setImportResult(null); onGoToTab?.('confirm') }}
                    >
                      点击查看考勤确认 →
                    </button>
                  </div>
                )}

                <div className="flex justify-end gap-2">
                  <Button variant="secondary" size="sm" onClick={() => { setShowImport(false); setImportFile(null); setImportResult(null) }}>取消</Button>
                  <Button size="sm" onClick={async () => {
                    if (!importFile) return toast.error('请选择文件')
                    setImporting(true)
                    setImportResult(null)
                    try {
                      const token = useAuthStore.getState().accessToken
                      const formData = new FormData()
                      formData.append('file', importFile)
                      const res = await fetch('/api/v1/import/excel', {
                        method: 'POST',
                        headers: token ? { Authorization: `Bearer ${token}` } : {},
                        body: formData,
                      })
                      const data = await res.json()
                      if (!data.success) { toast.error(data.error?.message || '导入失败') }
                      else {
                        setImportResult(data.data)
                        queryClient.invalidateQueries({ queryKey: ['attendance'] })
                        queryClient.invalidateQueries({ queryKey: ['attendance-stats'] })
                        toast.success('考勤数据导入完成')
                      }
                    } catch (e: any) { toast.error(e?.message || '导入失败') }
                    finally { setImporting(false) }
                  }} disabled={!importFile || importing}>{importing ? '导入中...' : '开始导入'}</Button>
                </div>
              </div>
            </div>
          </Card>
        </div>
      )}
    </div>
  )
}

// ========== 每日出勤 Tab ==========
function DailyTab() {
  const queryClient = useQueryClient()
  const [date, setDate] = useState(new Date().toISOString().slice(0, 10))
  const [editEmp, setEditEmp] = useState<any>(null)
  const [editForm, setEditForm] = useState({ checkInTime: '', checkOutTime: '', status: 'NORMAL', remark: '' })
  const [searchQuery, setSearchQuery] = useState('')
  const [filterDept, setFilterDept] = useState('')
  const pageSize = usePageSize()
  const [page, setPage] = useState(1)

  const { data, isLoading } = useQuery<any>({
    queryKey: ['daily-attendance', date],
    queryFn: async () => {
      return await attendanceApi.daily(date)
    },
  })

  const correctMutation = useMutation({
    mutationFn: (data: any) => attendanceApi.manualCorrect(data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['daily-attendance'] })
      toast.success('考勤记录已修正')
      setEditEmp(null)
    },
    onError: () => toast.error('修正失败'),
  })

  const statusColors: Record<string, string> = {
    NORMAL: 'bg-green-50 text-green-700',
    LATE: 'bg-amber-50 text-amber-700',
    EARLY_LEAVE: 'bg-orange-50 text-orange-700',
    ABSENT: 'bg-red-50 text-red-700',
    LEAVE: 'bg-blue-50 text-blue-700',
    BUSINESS_TRIP: 'bg-purple-50 text-purple-700',
    UNREGISTERED: 'bg-gray-100 text-gray-500',
  }

  const allData = data || []
  const filteredData = allData.filter((emp: any) => {
    if (filterDept && emp.department !== filterDept) return false
    if (searchQuery.trim()) {
      const q = searchQuery.trim().toLowerCase()
      if (!emp.name?.toLowerCase().includes(q) && !emp.department?.toLowerCase().includes(q)) return false
    }
    return true
  })
  const total = filteredData.length
  const pagedData = filteredData.slice((page - 1) * pageSize, page * pageSize)

  return (
    <div className="space-y-3">
      <div className="flex flex-wrap items-center justify-between gap-2">
        <div className="flex items-center gap-2">
          <input
            type="date"
            value={date}
            onChange={e => setDate(e.target.value)}
            className="px-3 py-1.5 text-sm border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"
          />
          <input
            type="text"
            placeholder="搜索姓名或部门"
            value={searchQuery}
            onChange={e => { setSearchQuery(e.target.value); setPage(1) }}
            className="px-3 py-1.5 text-sm border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary w-44"
          />
          <select
            value={filterDept}
            onChange={e => { setFilterDept(e.target.value); setPage(1) }}
            className="h-9 rounded-md border border-gray-200 bg-white px-3 text-sm"
          >
            <option value="">全部部门</option>
            {Array.from(new Set(allData.map((e: any) => e.department).filter(Boolean) as string[])).map(d => (
              <option key={d} value={d}>{d}</option>
            ))}
          </select>
        </div>
        <Button variant="secondary" size="sm" onClick={() => {
          if (!data || data.length === 0) return
          const headers = ['姓名', '身份证号', '部门', '班次', '签到', '签退', '状态', '工时']
          const rows = data.map((emp: any) => [
            emp.name, emp.idCardNumber || '', emp.department, emp.shift?.name || '', emp.checkInTime || '', emp.checkOutTime || '',
            ATTENDANCE_STATUS[emp.status] || emp.status, emp.workHours > 0 ? `${emp.workHours}h` : '0',
          ])
          const csv = [headers, ...rows].map(r => r.join(',')).join('\n')
          const blob = new Blob(['\ufeff' + csv], { type: 'text/csv;charset=utf-8' })
          const url = URL.createObjectURL(blob)
          const a = document.createElement('a')
          a.href = url
          a.download = `考勤-${date}.csv`
          a.click()
          URL.revokeObjectURL(url)
        }} disabled={!data || data.length === 0}>
          <Download className="w-4 h-4 mr-1" />导出
        </Button>
      </div>

      {isLoading ? (
        <div className="text-center py-8 text-gray-500">加载中...</div>
      ) : total === 0 ? (
        <EmptyState title="暂无员工" description="没有出勤数据" />
      ) : (
        <>
        <Card className="overflow-hidden p-0">
          <table className="w-full text-sm">
            <thead className="bg-gray-50/90">
              <tr className="border-b border-gray-200 text-xs font-medium text-gray-500">
                <th className="px-4 py-3 text-left">姓名</th>
                <th className="px-4 py-3 text-left">身份证号</th>
                <th className="px-4 py-3 text-left">部门</th>
                <th className="px-4 py-3 text-left">班次</th>
                <th className="px-4 py-3 text-left">签到</th>
                <th className="px-4 py-3 text-left">签退</th>
                <th className="px-4 py-3 text-left">状态</th>
                <th className="px-4 py-3 text-right">工时</th>
                <th className="px-4 py-3 text-center">操作</th>
              </tr>
            </thead>
            <tbody>
              {pagedData.map((emp: any) => (
                <tr key={emp.employeeId} className="border-b border-gray-100 last:border-0">
                  <td className="px-4 py-3 font-medium">{emp.name}</td>
                  <td className="px-4 py-3 text-gray-500 font-mono text-xs">{emp.idCardNumber || '-'}</td>
                  <td className="px-4 py-3 text-gray-500">{emp.department}</td>
                  <td className="px-4 py-3 text-xs text-gray-500">{emp.shift ? `${emp.shift.name}` : '—'}</td>
                  <td className="px-4 py-3 text-xs font-mono">{emp.checkInTime ? (() => { const d = new Date(emp.checkInTime); return `${String(d.getUTCHours()).padStart(2,'0')}:${String(d.getUTCMinutes()).padStart(2,'0')}`; })() : '—'}</td>
                  <td className="px-4 py-3 text-xs font-mono">{emp.checkOutTime ? (() => { const d = new Date(emp.checkOutTime); return `${String(d.getUTCHours()).padStart(2,'0')}:${String(d.getUTCMinutes()).padStart(2,'0')}`; })() : '—'}</td>
                  <td className="px-4 py-3">
                    <span className={`px-2 py-0.5 rounded text-xs ${statusColors[emp.status] || 'bg-gray-100 text-gray-500'}`}>
                      {ATTENDANCE_STATUS[emp.status] || emp.status}
                    </span>
                  </td>
                  <td className="px-4 py-3 text-right text-xs">{emp.workHours > 0 ? `${emp.workHours}h` : '—'}</td>
                  <td className="px-4 py-3 text-center">
                    <button
                      className="text-xs text-primary hover:underline"
                      onClick={() => {
                        setEditEmp(emp)
                        const fmtTime = (t: string) => { if (!t) return ''; const d = new Date(t); return `${String(d.getUTCHours()).padStart(2,'0')}:${String(d.getUTCMinutes()).padStart(2,'0')}` }
                        setEditForm({
                          checkInTime: fmtTime(emp.checkInTime),
                          checkOutTime: fmtTime(emp.checkOutTime),
                          status: emp.status || 'NORMAL',
                          remark: '',
                        })
                      }}
                    >
                      <Edit className="w-3.5 h-3.5 inline" /> 补卡
                    </button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </Card>
        <Pagination page={page} pageSize={pageSize} total={total} onPageChange={setPage} onPageSizeChange={() => setPage(1)} />
        </>
      )}

      {/* 补卡弹窗 */}
      {editEmp && (
        <Modal open onClose={() => setEditEmp(null)}>
          <div className="space-y-4">
            <div className="flex items-center justify-between">
              <h3 className="font-medium">考勤修正 - {editEmp.name}</h3>
              <button onClick={() => setEditEmp(null)} className="text-gray-500 hover:text-gray-600">
                <X className="w-5 h-5" />
              </button>
            </div>
            <div className="text-xs text-gray-500">日期：{date}</div>
            <div className="grid grid-cols-2 gap-3">
              <div>
                <Label>签到时间</Label>
                <Input type="time" value={editForm.checkInTime} onChange={(e) => setEditForm({ ...editForm, checkInTime: e.target.value })} />
              </div>
              <div>
                <Label>签退时间</Label>
                <Input type="time" value={editForm.checkOutTime} onChange={(e) => setEditForm({ ...editForm, checkOutTime: e.target.value })} />
              </div>
              <div className="col-span-2">
                <Label>考勤状态</Label>
                <Select value={editForm.status} onChange={(e) => setEditForm({ ...editForm, status: e.target.value })}>
                  <option value="NORMAL">正常</option>
                  <option value="LATE">迟到</option>
                  <option value="EARLY_LEAVE">早退</option>
                  <option value="ABSENT">缺勤</option>
                  <option value="LEAVE">请假</option>
                  <option value="BUSINESS_TRIP">出差</option>
                  <option value="UNREGISTERED">未打卡</option>
                </Select>
              </div>
              <div className="col-span-2">
                <Label>备注</Label>
                <Input value={editForm.remark} onChange={(e) => setEditForm({ ...editForm, remark: e.target.value })} placeholder="补卡原因/备注" />
              </div>
            </div>
            <Button onClick={() => correctMutation.mutate({ employeeId: editEmp.employeeId, date, ...editForm })} disabled={correctMutation.isPending} className="w-full">
              {correctMutation.isPending ? '提交中...' : '确认修正'}
            </Button>
          </div>
        </Modal>
      )}
    </div>
  )
}

// ========== 月度报表 Tab ==========
function MonthlyTab() {
  const [month, setMonth] = useState(new Date().toISOString().slice(0, 7))
  const [searchQuery, setSearchQuery] = useState('')
  const [filterDept, setFilterDept] = useState('')
  const pageSize = usePageSize()
  const [page, setPage] = useState(1)

  const { data, isLoading } = useQuery<any>({
    queryKey: ['monthly-report', month],
    queryFn: async () => {
      return await attendanceApi.monthlyReport(month)
    },
  })

  const handleExport = () => {
    if (!data || data.length === 0) return
    const headers = ['姓名', '部门', '出勤天数', '迟到次数', '早退次数', '缺勤天数', '请假天数', '加班工时', '加班费', '确认状态']
    const rows = data.map((r: any) => [
      r.name, r.department, r.workDays, r.lateCount, r.earlyLeaveCount, r.absentDays, r.leaveDays,
      r.overtimeHours, r.overtimePay, r.confirmationStatus === 'CONFIRMED' ? '已确认' : r.confirmationStatus === 'PENDING' ? '待确认' : r.confirmationStatus === 'DISPUTED' ? '有异议' : '未创建',
    ])
    const csv = [headers, ...rows].map(r => r.join(',')).join('\n')
    const blob = new Blob(['\ufeff' + csv], { type: 'text/csv;charset=utf-8' })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `attendance-report-${month}.csv`
    a.click()
    URL.revokeObjectURL(url)
  }

  const handleExportSingle = (r: any) => {
    const headers = ['项目', '数值']
    const rows = [
      ['姓名', r.name],
      ['部门', r.department],
      ['月份', month],
      ['出勤天数', r.workDays],
      ['迟到次数', r.lateCount],
      ['早退次数', r.earlyLeaveCount],
      ['缺勤天数', r.absentDays],
      ['请假天数', r.leaveDays],
      ['加班工时', r.overtimeHours?.toFixed(1) || '0'],
      ['加班费', `¥${r.overtimePay?.toFixed(2) || '0.00'}`],
      ['确认状态', r.confirmationStatus === 'CONFIRMED' ? '已确认' : r.confirmationStatus === 'PENDING' ? '待确认' : r.confirmationStatus === 'DISPUTED' ? '有异议' : '未创建'],
    ]
    const csv = [headers, ...rows].map(row => row.join(',')).join('\n')
    const blob = new Blob(['\ufeff' + csv], { type: 'text/csv;charset=utf-8' })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `考勤明细-${r.name}-${month}.csv`
    a.click()
    URL.revokeObjectURL(url)
    toast.success(`已导出 ${r.name} 的 ${month} 月考勤明细`)
  }

  const allData = data || []
  const filteredData = allData.filter((r: any) => {
    if (filterDept && r.department !== filterDept) return false
    if (searchQuery.trim()) {
      const q = searchQuery.trim().toLowerCase()
      if (!r.name?.toLowerCase().includes(q) && !r.department?.toLowerCase().includes(q)) return false
    }
    return true
  })
  const total = filteredData.length
  const pagedData = filteredData.slice((page - 1) * pageSize, page * pageSize)

  return (
    <div className="space-y-3">
      <div className="flex flex-wrap items-center justify-between gap-2">
        <div className="flex items-center gap-2">
          <input
            type="month"
            value={month}
            onChange={e => setMonth(e.target.value)}
            className="px-3 py-1.5 text-sm border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"
          />
          <input
            type="text"
            placeholder="搜索姓名或部门"
            value={searchQuery}
            onChange={e => { setSearchQuery(e.target.value); setPage(1) }}
            className="px-3 py-1.5 text-sm border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary w-44"
          />
          <select
            value={filterDept}
            onChange={e => { setFilterDept(e.target.value); setPage(1) }}
            className="h-9 rounded-md border border-gray-200 bg-white px-3 text-sm"
          >
            <option value="">全部部门</option>
            {Array.from(new Set(allData.map((e: any) => e.department).filter(Boolean) as string[])).map(d => (
              <option key={d} value={d}>{d}</option>
            ))}
          </select>
        </div>
        <Button variant="secondary" onClick={handleExport} disabled={!data || data.length === 0}>
          <BarChart3 className="w-4 h-4 mr-1" />导出 CSV
        </Button>
      </div>

      {isLoading ? (
        <div className="text-center py-8 text-gray-500">加载中...</div>
      ) : total === 0 ? (
        <EmptyState title="暂无报表数据" description="该月份没有出勤数据" />
      ) : (
        <>
        <Card className="overflow-hidden p-0">
          <table className="w-full text-sm">
            <thead className="bg-gray-50/90">
              <tr className="border-b border-gray-200 text-xs font-medium text-gray-500">
                <th className="px-4 py-3 text-left">姓名</th>
                <th className="px-4 py-3 text-left">部门</th>
                <th className="px-4 py-3 text-center">出勤</th>
                <th className="px-4 py-3 text-center">迟到</th>
                <th className="px-4 py-3 text-center">早退</th>
                <th className="px-4 py-3 text-center">缺勤</th>
                <th className="px-4 py-3 text-center">请假</th>
                <th className="px-4 py-3 text-center">加班(h)</th>
                <th className="px-4 py-3 text-right">加班费</th>
                <th className="px-4 py-3 text-center">确认</th>
                <th className="px-4 py-3 text-center">操作</th>
              </tr>
            </thead>
            <tbody>
              {pagedData.map((r: any) => (
                <tr key={r.employeeId} className="border-b border-gray-100 last:border-0">
                  <td className="px-4 py-3 font-medium">{r.name}</td>
                  <td className="px-4 py-3 text-gray-500">{r.department}</td>
                  <td className="px-4 py-3 text-center">{r.workDays}</td>
                  <td className="px-4 py-3 text-center">{r.lateCount > 0 ? <span className="text-amber-600">{r.lateCount}</span> : '0'}</td>
                  <td className="px-4 py-3 text-center">{r.earlyLeaveCount > 0 ? <span className="text-orange-600">{r.earlyLeaveCount}</span> : '0'}</td>
                  <td className="px-4 py-3 text-center">{r.absentDays > 0 ? <span className="text-red-600">{r.absentDays}</span> : '0'}</td>
                  <td className="px-4 py-3 text-center">{r.leaveDays > 0 ? <span className="text-blue-600">{r.leaveDays}</span> : '0'}</td>
                  <td className="px-4 py-3 text-center">{r.overtimeHours > 0 ? r.overtimeHours.toFixed(1) : '—'}</td>
                  <td className="px-4 py-3 text-right">{r.overtimePay > 0 ? `¥${r.overtimePay.toFixed(2)}` : '—'}</td>
                  <td className="px-4 py-3 text-center">
                    {r.confirmationStatus === 'CONFIRMED' ? <span className="text-xs text-green-600">已确认</span>
                      : r.confirmationStatus === 'PENDING' ? <span className="text-xs text-amber-600">待确认</span>
                      : r.confirmationStatus === 'DISPUTED' ? <span className="text-xs text-red-600">有异议</span>
                      : <span className="text-xs text-gray-400">—</span>}
                  </td>
                  <td className="px-4 py-3 text-center">
                    <button
                      className="text-xs text-primary hover:underline"
                      onClick={() => handleExportSingle(r)}
                    >
                      导出
                    </button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </Card>
        <Pagination page={page} pageSize={pageSize} total={total} onPageChange={setPage} onPageSizeChange={() => setPage(1)} />
        </>
      )}
    </div>
  )
}

// ========== 休假记录 Tab ==========
function LeavesTab() {
  const queryClient = useQueryClient()
  const confirm = useConfirm()
  const [showAdd, setShowAdd] = useState(false)
  const [form, setForm] = useState({ employeeId: '', leaveType: 'PERSONAL', startDate: '', endDate: '', days: 1, reason: '', remark: '' })
  const [searchQuery, setSearchQuery] = useState('')
  const pageSize = usePageSize()
  const [page, setPage] = useState(1)

  const { data: leaves, isLoading } = useQuery<any>({
    queryKey: ['leave-records'],
    queryFn: async () => {
      return await attendanceApi.leaves()
    },
  })

  const { data: rosterData } = useQuery<any>({
    queryKey: ['employee-list'],
    queryFn: () => employeeApi.list({ status: 'ACTIVE' }),
  })

  const createMutation = useMutation({
    mutationFn: (data: any) => attendanceApi.createLeave(data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['leave-records'] })
      setShowAdd(false)
      setForm({ employeeId: '', leaveType: 'PERSONAL', startDate: '', endDate: '', days: 1, reason: '', remark: '' })
      toast.success('休假记录已添加')
    },
  })

  const deleteMutation = useMutation({
    mutationFn: (id: string) => attendanceApi.removeLeave(id),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['leave-records'] }),
  })

  const handleSubmit = () => {
    if (!form.employeeId) return toast.error('请选择员工')
    if (!form.startDate || !form.endDate) return toast.error('请选择日期')
    createMutation.mutate(form)
  }

  const employees = rosterData || []
  const allLeaves = leaves || []
  const filteredLeaves = allLeaves.filter((lv: any) => {
    if (searchQuery.trim()) {
      const q = searchQuery.trim().toLowerCase()
      if (!lv.employee?.name?.toLowerCase().includes(q) && !lv.employee?.department?.toLowerCase().includes(q)) return false
    }
    return true
  })
  const total = filteredLeaves.length
  const pagedLeaves = filteredLeaves.slice((page - 1) * pageSize, page * pageSize)

  return (
    <div className="space-y-3">
      <div className="flex justify-end items-center gap-3">
        <input
          type="text"
          placeholder="搜索姓名或部门"
          value={searchQuery}
          onChange={e => { setSearchQuery(e.target.value); setPage(1) }}
          className="px-3 py-1.5 text-sm border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary w-44"
        />
        <Link to="/leave-approval" className="text-xs text-primary hover:underline flex items-center gap-1">
          <Plane className="w-3.5 h-3.5" />
          前往休假审批
        </Link>
        <Button onClick={() => setShowAdd(true)}>
          <Plus className="w-4 h-4 mr-1" />新增休假记录
        </Button>
      </div>

      {isLoading ? (
        <div className="text-center py-8 text-gray-500">加载中...</div>
      ) : total === 0 ? (
        <EmptyState title="暂无休假记录" description="点击右上角添加休假记录" />
      ) : (
        <>
        <div className="space-y-2">
          {pagedLeaves.map((lv: any) => (
            <Card key={lv.id}>
              <div className="flex items-center justify-between">
                <div className="flex items-center gap-3 flex-1 min-w-0">
                  <div className="flex items-center justify-center w-8 h-8 rounded-lg bg-blue-50 flex-shrink-0">
                    <Plane className="w-4 h-4 text-blue-600" />
                  </div>
                  <div className="flex-1 min-w-0">
                    <div className="flex items-center gap-2">
                      <span className="text-sm font-medium">{lv.employee?.name}</span>
                      <span className="text-xs text-gray-500">{lv.employee?.department}</span>
                      <span className="px-1.5 py-0.5 rounded text-xs bg-blue-50 text-blue-700">{LEAVE_TYPES[lv.leaveType] || lv.leaveType}</span>
                    </div>
                    <div className="text-xs text-gray-500 mt-0.5">
                      {lv.startDate?.toString().slice(0, 10)} ~ {lv.endDate?.toString().slice(0, 10)}（{lv.days}天）
                      {lv.reason && <span className="ml-2">原因：{lv.reason}</span>}
                    </div>
                  </div>
                </div>
                <button className="text-xs text-gray-400 hover:text-red-500 flex-shrink-0" onClick={async () => { if (await confirm({ title: '删除休假记录', message: '确认删除？' })) deleteMutation.mutate(lv.id) }}>
                  <Trash2 className="w-3.5 h-3.5" />
                </button>
              </div>
            </Card>
          ))}
        </div>
        <Pagination page={page} pageSize={pageSize} total={total} onPageChange={setPage} onPageSizeChange={() => setPage(1)} />
        </>
      )}

      <Modal open={showAdd} onClose={() => setShowAdd(false)} title="新增休假记录">
        <div className="space-y-3">
          <div>
            <Label>选择员工</Label>
            <Select value={form.employeeId} onChange={e => setForm({ ...form, employeeId: e.target.value })}>
              <option value="">请选择员工</option>
              {employees.map((emp: any) => (
                <option key={emp.id} value={emp.id}>{emp.name} - {emp.department}</option>
              ))}
            </Select>
          </div>
          <div>
            <Label>休假类型</Label>
            <Select value={form.leaveType} onChange={e => setForm({ ...form, leaveType: e.target.value })}>
              {Object.entries(LEAVE_TYPES).map(([k, v]) => (
                <option key={k} value={k}>{v}</option>
              ))}
            </Select>
          </div>
          <div className="grid grid-cols-2 gap-3">
            <div>
              <Label>开始日期</Label>
              <Input type="date" value={form.startDate} onChange={e => setForm({ ...form, startDate: e.target.value })} />
            </div>
            <div>
              <Label>结束日期</Label>
              <Input type="date" value={form.endDate} onChange={e => setForm({ ...form, endDate: e.target.value })} />
            </div>
          </div>
          <div>
            <Label>请假天数</Label>
            <Input type="number" step="0.5" value={form.days} onChange={e => setForm({ ...form, days: Number(e.target.value) })} />
          </div>
          <div>
            <Label>原因（选填）</Label>
            <Input value={form.reason} onChange={e => setForm({ ...form, reason: e.target.value })} placeholder="请简述请假原因" />
          </div>
          <div className="flex justify-end gap-2 pt-2">
            <Button variant="secondary" onClick={() => setShowAdd(false)}>取消</Button>
            <Button onClick={handleSubmit} disabled={createMutation.isPending}>{createMutation.isPending ? '保存中...' : '保存'}</Button>
          </div>
        </div>
      </Modal>
    </div>
  )
}
