import { useState, useMemo, useRef } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { Calculator, AlertCircle, Info, Save, Check, Upload, Bell, Layers, Settings as SettingsIcon, Archive, Plus, Trash2, AlertTriangle, Download, FileText, History } from 'lucide-react'
import api from '../lib/api'
import Card from '../components/ui/Card'
import Button from '../components/ui/Button'
import { Input, Label, Select } from '../components/ui/Input'
import EmptyState from '../components/ui/EmptyState'
import Pagination from '../components/ui/Pagination'

// 金额格式化：保留两位小数 + 千分位
const fmt = (n: number) => (n || 0).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })

type Tab = 'batch' | 'template' | 'overtime' | 'payslip'

export default function Money() {
  const [tab, setTab] = useState<Tab>('batch')

  const tabs: { key: Tab; label: string }[] = [
    { key: 'batch', label: '发薪批次' },
    { key: 'template', label: '薪酬模版' },
    { key: 'overtime', label: '加班费计算' },
    { key: 'payslip', label: '工资条管理' },
  ]

  return (
    <div className="space-y-3">
      <h1 className="text-xs font-medium">薪税计算</h1>

      <div className="flex gap-1 border-b overflow-x-auto">
        {tabs.map((t) => (
          <button
            key={t.key}
            onClick={() => setTab(t.key)}
            className={`px-3 py-1.5 text-xs font-medium border-b-2 transition-colors whitespace-nowrap ${
              tab === t.key ? 'border-primary text-primary' : 'border-transparent text-gray-500 hover:text-gray-700'
            }`}
          >
            {t.label}
          </button>
        ))}
      </div>

      {tab === 'batch' && <BatchManager />}
      {tab === 'template' && <TemplateManager />}
      {tab === 'overtime' && <OvertimeCalculator />}
      {tab === 'payslip' && <PayslipManager />}
    </div>
  )
}

// ========== 发薪批次管理 ==========

function BatchManager() {
  const queryClient = useQueryClient()
  const [month, setMonth] = useState(new Date().toISOString().slice(0, 7))
  const [selectedBatchId, setSelectedBatchId] = useState<string | null>(null)
  const [showCreateModal, setShowCreateModal] = useState(false)
  const [createType, setCreateType] = useState<'REGULAR' | 'TERMINATION' | 'BONUS'>('REGULAR')
  const [createMode, setCreateMode] = useState<'copy_last' | 'blank_employees' | 'blank_all' | 'copy_batch'>('copy_last')
  const [sourceBatchId, setSourceBatchId] = useState<string>('')
  const [page, setPage] = useState(1)
  const [pageSize, setPageSize] = useState(10)

  const { data: checkResult } = useQuery<any>({
    queryKey: ['batch-check', month],
    queryFn: async () => {
      const res = await api.get('/payroll2/batches/check', { params: { month } }) as any
      return res.data
    },
  })

  const { data: batches, isLoading } = useQuery<any[]>({
    queryKey: ['batches', month],
    queryFn: async () => {
      const res = await api.get('/payroll2/batches', { params: { month } }) as any
      return res.data
    },
  })

  const { data: archivedBatches } = useQuery<any[]>({
    queryKey: ['archived-batches'],
    queryFn: async () => {
      const res = await api.get('/payroll2/batches/archived/list') as any
      return res.data
    },
    enabled: createMode === 'copy_batch',
  })

  const createMutation = useMutation({
    mutationFn: (data: any) => api.post('/payroll2/batches', data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['batches'] })
      queryClient.invalidateQueries({ queryKey: ['batch-check'] })
      setShowCreateModal(false)
    },
  })

  const deleteBatchMutation = useMutation({
    mutationFn: (batchId: string) => api.delete(`/payroll2/batches/${batchId}`),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['batches'] })
      queryClient.invalidateQueries({ queryKey: ['batch-check'] })
    },
  })

  if (selectedBatchId) {
    return <BatchDetail batchId={selectedBatchId} onBack={() => setSelectedBatchId(null)} />
  }

  return (
    <div className="space-y-3">
      {/* 重复发薪提醒 */}
      {checkResult?.hasArchivedBatch && (
        <div className="flex items-center gap-2 p-2 rounded-md bg-amber-50 text-warning text-xs">
          <AlertCircle className="w-4 h-4 flex-shrink-0" />
          本月已有 {checkResult.archivedCount} 个已归档批次{checkResult.payslipsPublished ? '，工资条已发布' : ''}
        </div>
      )}

      <div className="flex items-center justify-between gap-2">
        <div className="flex items-center gap-3">
          <Input type="month" value={month} onChange={(e) => setMonth(e.target.value)} className="w-48" />
          {batches && batches.length > 0 && (
            <span className="text-xs text-gray-500 whitespace-nowrap flex-shrink-0">{batches.length} 个批次</span>
          )}
        </div>
        <div className="flex gap-2">
          <Button onClick={() => { setCreateType('REGULAR'); setShowCreateModal(true) }}>
            <Plus className="w-4 h-4 mr-1" />创建发薪批次
          </Button>
        </div>
      </div>

      {showCreateModal && (
        <Card>
          <h2 className="text-xs font-medium mb-3">创建发薪批次</h2>
          <div className="space-y-3">
            <div className="grid grid-cols-2 gap-3">
              <div>
                <Label>批次类型</Label>
                <Select value={createType} onChange={(e) => setCreateType(e.target.value as any)}>
                  <option value="REGULAR">常规发薪</option>
                  <option value="TERMINATION">离职结算</option>
                  <option value="BONUS">年终奖/奖金</option>
                </Select>
              </div>
              <div>
                <Label>数据初始化模式</Label>
                <Select value={createMode} onChange={(e) => { setCreateMode(e.target.value as any); setSourceBatchId('') }}>
                  <option value="copy_last">复制上月数据</option>
                  <option value="blank_employees">本月空白（拉入员工，金额为0）</option>
                  <option value="blank_all">全空白（不拉入员工）</option>
                  <option value="copy_batch">复制指定批次</option>
                </Select>
              </div>
            </div>
            {createMode === 'copy_batch' && (
              <div>
                <Label>选择源批次</Label>
                <Select value={sourceBatchId} onChange={(e) => setSourceBatchId(e.target.value)}>
                  <option value="">请选择已归档批次</option>
                  {archivedBatches?.map((b: any) => (
                    <option key={b.id} value={b.id}>{b.name}（{b.month} · {b.employeeCount}人 · 应发¥{fmt(b.totalPay)}）</option>
                  ))}
                </Select>
                {!archivedBatches?.length && (
                  <p className="text-xs text-gray-400 mt-1">暂无可复制的已归档批次</p>
                )}
              </div>
            )}
            <div className="text-xs text-gray-500 space-y-0.5">
              {createMode === 'copy_last' && <p>拉入在职员工，从上月工资条复制基本工资/津贴/扣款，自动计算社保个税</p>}
              {createMode === 'blank_employees' && <p>拉入在职员工，所有金额为0，需手动填写</p>}
              {createMode === 'blank_all' && <p>创建空批次，不拉入员工，后续手动添加人员和填写数据</p>}
              {createMode === 'copy_batch' && <p>从指定的已归档批次复制员工和薪资数据</p>}
            </div>
            <div className="flex gap-2">
              <Button
                onClick={() => createMutation.mutate({ month, type: createType, mode: createMode, sourceBatchId: sourceBatchId || undefined })}
                disabled={createMutation.isPending || (createMode === 'copy_batch' && !sourceBatchId)}
              >
                {createMutation.isPending ? '创建中...' : '确认创建'}
              </Button>
              <Button variant="secondary" onClick={() => setShowCreateModal(false)}>取消</Button>
            </div>
          </div>
        </Card>
      )}

      {isLoading ? (
        <div className="text-center py-8 text-gray-400">加载中...</div>
      ) : !batches || batches.length === 0 ? (
        <EmptyState title="本月暂无发薪批次" description="点击「创建发薪批次」开始" />
      ) : (
        <div className="space-y-3">
          <Pagination page={page} pageSize={pageSize} total={batches.length} onPageChange={setPage} onPageSizeChange={(s) => { setPageSize(s); setPage(1) }} />
          {batches.slice((page - 1) * pageSize, page * pageSize).map((batch: any) => (
            <Card key={batch.id} className="cursor-pointer hover:shadow-md transition-shadow" >
              <div className="flex items-center justify-between" onClick={() => setSelectedBatchId(batch.id)}>
                <div className="flex items-center gap-2">
                  <Layers className="w-4 h-4 text-primary flex-shrink-0" />
                  <div className="min-w-0">
                    <div className="text-xs font-medium">{batch.name}</div>
                    <div className="text-xs text-gray-500 mt-0.5">
                      {batch.employeeCount} 人 · 应发 ¥{fmt(batch.totalPay)} · 实发 ¥{fmt(batch.totalNetPay)}
                      {batch.type === 'BONUS' && ' · 单独计税'}
                      {batch.type === 'TERMINATION' && ' · 离职结算'}
                    </div>
                  </div>
                </div>
                <div className="flex items-center gap-2 flex-shrink-0">
                  {batch.status === 'ARCHIVED' ? (
                    <span className="px-2 py-0.5 rounded text-xs bg-green-50 text-safe flex items-center gap-1">
                      <Archive className="w-3 h-3" />已归档
                    </span>
                  ) : (
                    <>
                      <span className="px-2 py-0.5 rounded text-xs bg-amber-50 text-warning">草稿</span>
                      <button
                        onClick={(e) => {
                          e.stopPropagation()
                          if (confirm(`确认删除批次「${batch.name}」？此操作不可撤销。`)) {
                            deleteBatchMutation.mutate(batch.id)
                          }
                        }}
                        disabled={deleteBatchMutation.isPending}
                        className="p-1 rounded hover:bg-red-50 text-gray-400 hover:text-danger transition-colors"
                        title="删除批次"
                      >
                        <Trash2 className="w-3.5 h-3.5" />
                      </button>
                    </>
                  )}
                </div>
              </div>
            </Card>
          ))}
        </div>
      )}
    </div>
  )
}

function BatchDetail({ batchId, onBack }: { batchId: string; onBack: () => void }) {
  const queryClient = useQueryClient()
  const [editCell, setEditCell] = useState<{ employeeId: string; field: string } | null>(null)
  const [editValue, setEditValue] = useState<string>('')
  const [page, setPage] = useState(1)
  const [pageSize, setPageSize] = useState(10)
  const [showAddEmployee, setShowAddEmployee] = useState(false)

  const { data: batch, isLoading } = useQuery<any>({
    queryKey: ['batch-detail', batchId],
    queryFn: async () => {
      const res = await api.get(`/payroll2/batches/${batchId}`) as any
      return res.data
    },
  })

  const updateEntryMutation = useMutation({
    mutationFn: ({ employeeId, data }: { employeeId: string; data: any }) =>
      api.put(`/payroll2/batches/${batchId}/entries/${employeeId}`, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['batch-detail'] })
    },
  })

  const removeEmployeeMutation = useMutation({
    mutationFn: (employeeId: string) => api.delete(`/payroll2/batches/${batchId}/employees/${employeeId}`),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['batch-detail'] }),
  })

  const archiveMutation = useMutation({
    mutationFn: () => api.post(`/payroll2/batches/${batchId}/archive`),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['batch-detail'] })
      queryClient.invalidateQueries({ queryKey: ['batches'] })
      queryClient.invalidateQueries({ queryKey: ['batch-check'] })
      queryClient.invalidateQueries({ queryKey: ['dashboard'] })
      alert('批次已归档。归档后批次锁定不可编辑。可前往「工资条管理」生成工资条。')
    },
  })

  const importOvertimeMutation = useMutation({
    mutationFn: () => api.post(`/payroll/overtime/import-to-batch/${batchId}`),
    onSuccess: (res: any) => {
      queryClient.invalidateQueries({ queryKey: ['batch-detail'] })
      queryClient.invalidateQueries({ queryKey: ['overtime-records'] })
      if (res.data?.imported > 0) {
        alert(`成功导入 ${res.data.imported} 条加班费记录`)
      } else {
        alert(res.data?.message || '没有可导入的加班记录')
      }
    },
    onError: () => {
      alert('导入失败，请重试')
    },
  })

  const deleteBatchMutation = useMutation({
    mutationFn: () => api.delete(`/payroll2/batches/${batchId}`),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['batches'] })
      queryClient.invalidateQueries({ queryKey: ['batch-check'] })
      onBack()
    },
  })

  if (isLoading) return <div className="text-center py-8 text-gray-400">加载中...</div>
  if (!batch) return <div className="text-center py-8 text-gray-400">批次不存在</div>

  const isArchived = batch.status === 'ARCHIVED'
  const isBonus = batch.type === 'BONUS'

  // 可编辑的输入项字段
  const editableFields = isBonus
    ? ['bonus']
    : ['baseSalary', 'overtimePay', 'allowance', 'deduction', 'bonus', 'socialEmp', 'housingEmp', 'socialOrg', 'housingOrg']

  // 点击单元格进入编辑
  const startEdit = (employeeId: string, field: string, currentValue: number) => {
    if (isArchived || !editableFields.includes(field)) return
    setEditCell({ employeeId, field })
    setEditValue(currentValue.toFixed(2))
  }

  // 保存编辑
  const saveEdit = () => {
    if (!editCell) return
    const { employeeId, field } = editCell
    const numValue = Number(editValue) || 0
    const entry = batch.entries.find((e: any) => e.employeeId === employeeId)
    if (!entry) { setEditCell(null); return }
    const data: any = {}
    // 输入项字段一起提交
    const inputFields = isBonus ? ['bonus'] : ['baseSalary', 'overtimePay', 'allowance', 'deduction', 'bonus']
    inputFields.forEach(f => {
      data[f] = f === field ? numValue : entry[f]
    })
    // 社保公积金字段：编辑哪个提交哪个
    const socialFields = ['socialEmp', 'housingEmp', 'socialOrg', 'housingOrg']
    if (socialFields.includes(field)) {
      data[field] = numValue
    }
    updateEntryMutation.mutate({ employeeId, data })
    setEditCell(null)
  }

  // 失焦保存
  const handleBlur = () => saveEdit()

  // Enter 保存，Esc 取消
  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter') { e.preventDefault(); saveEdit() }
    if (e.key === 'Escape') setEditCell(null)
  }

  // 渲染可编辑单元格
  const renderCell = (entry: any, field: string, className: string = '') => {
    const isEditing = editCell?.employeeId === entry.employeeId && editCell?.field === field
    const canEdit = !isArchived && editableFields.includes(field)

    const value = entry[field] || 0
    const displayValue = field === 'deduction' && value > 0 ? '-' + fmt(value) : fmt(value)

    if (isEditing) {
      return (
        <td className="py-1 px-1 text-right" key={field}>
          <input
            type="text"
            inputMode="decimal"
            autoFocus
            className="w-24 text-right border-b-2 border-primary bg-transparent px-1 py-0.5 text-xs focus:outline-none [appearance:none]"
            value={editValue}
            onChange={(e) => setEditValue(e.target.value)}
            onBlur={handleBlur}
            onKeyDown={handleKeyDown}
          />
        </td>
      )
    }

    return (
      <td
        key={field}
        className={`py-2 px-2 text-right ${className} ${canEdit ? 'cursor-text' : ''}`}
        onClick={() => canEdit && startEdit(entry.employeeId, field, value)}
      >
        {canEdit ? (
          <span className={`border-b border-dashed border-gray-300 hover:border-primary ${field === 'deduction' && value > 0 ? 'text-danger' : ''}`}>
            {displayValue}
          </span>
        ) : field === 'deduction' && value > 0 ? (
          <span className="text-danger">{displayValue}</span>
        ) : (
          displayValue
        )}
      </td>
    )
  }

  return (
    <div className="space-y-3">
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          <button onClick={onBack} className="text-gray-400 hover:text-gray-600 text-xs">← 返回</button>
          <h2 className="text-xs font-medium">{batch.name}</h2>
          {isArchived ? (
            <span className="px-2 py-0.5 rounded text-xs bg-green-50 text-safe">已归档</span>
          ) : (
            <span className="px-2 py-0.5 rounded text-xs bg-amber-50 text-warning">草稿</span>
          )}
        </div>
        {!isArchived && (
          <div className="flex gap-2">
            <Button variant="secondary" size="sm" onClick={() => setShowAddEmployee(!showAddEmployee)}>
              <Plus className="w-4 h-4 mr-1" />添加人员
            </Button>
            <Button
              variant="secondary"
              size="sm"
              onClick={() => importOvertimeMutation.mutate()}
              disabled={importOvertimeMutation.isPending}
            >
              <Calculator className="w-4 h-4 mr-1" />
              {importOvertimeMutation.isPending ? '导入中...' : '导入加班费'}
            </Button>
            <Button
              size="sm"
              onClick={() => {
                if (confirm('确认归档？归档后批次将锁定不可编辑。工资条需在「工资条管理」中单独生成。')) {
                  archiveMutation.mutate()
                }
              }}
              disabled={archiveMutation.isPending}
            >
              <Archive className="w-4 h-4 mr-1" />
              {archiveMutation.isPending ? '归档中...' : '归档'}
            </Button>
            <Button
              variant="danger"
              size="sm"
              onClick={() => {
                if (confirm(`确认删除批次「${batch.name}」？此操作不可撤销。`)) {
                  deleteBatchMutation.mutate()
                }
              }}
              disabled={deleteBatchMutation.isPending}
            >
              <Trash2 className="w-4 h-4 mr-1" />
              {deleteBatchMutation.isPending ? '删除中...' : '删除'}
            </Button>
          </div>
        )}
        {isArchived && (
          <a href={`/api/v1/payroll2/batches/${batchId}/export?format=csv`} download>
            <Button variant="secondary" size="sm">
              <Download className="w-4 h-4 mr-1" />银行代发文件
            </Button>
          </a>
        )}
      </div>

      {/* 批次汇总 */}
      <div className="grid grid-cols-2 md:grid-cols-4 gap-3">
        <Card className="flex items-center gap-3">
          <div>
            <div className="text-lg font-bold">{batch.employeeCount}</div>
            <div className="text-xs text-gray-500">人数</div>
          </div>
        </Card>
        <Card className="flex items-center gap-3">
          <div>
            <div className="text-lg font-bold text-primary">¥{fmt(batch.totalPay)}</div>
            <div className="text-xs text-gray-500">应发合计</div>
          </div>
        </Card>
        <Card className="flex items-center gap-3">
          <div>
            <div className="text-lg font-bold text-danger">¥{fmt(batch.totalTax)}</div>
            <div className="text-xs text-gray-500">个税合计</div>
          </div>
        </Card>
        <Card className="flex items-center gap-3">
          <div>
            <div className="text-lg font-bold text-safe">¥{fmt(batch.totalNetPay)}</div>
            <div className="text-xs text-gray-500">实发合计</div>
          </div>
        </Card>
      </div>

      {/* 添加人员 */}
      {showAddEmployee && !isArchived && (
        <AddEmployeeToBatch batchId={batchId} onClose={() => setShowAddEmployee(false)} />
      )}

      {/* 提示 */}
      {!isArchived && (
        <div className="text-xs text-gray-400 flex items-center gap-1">
          <Info className="w-3.5 h-3.5" />
          带下划线的单元格可直接点击编辑，失焦自动保存。社保/公积金可手动覆盖，个税和实发自动计算。
        </div>
      )}

      {/* 人员表格 */}
      <Card>
        {batch.entries.length > 0 && (
          <Pagination page={page} pageSize={pageSize} total={batch.entries.length} onPageChange={setPage} onPageSizeChange={(s) => { setPageSize(s); setPage(1) }} />
        )}
        <div className="overflow-x-auto">
          <table className="w-full text-xs">
            <thead>
              <tr className="border-b text-left text-gray-500">
                <th className="py-2 px-2">员工</th>
                <th className="py-2 px-2 text-right">基本工资</th>
                <th className="py-2 px-2 text-right">加班费</th>
                <th className="py-2 px-2 text-right">津贴</th>
                {isBonus && <th className="py-2 px-2 text-right">奖金</th>}
                {!isBonus && <th className="py-2 px-2 text-right">奖金</th>}
                <th className="py-2 px-2 text-right">扣款</th>
                <th className="py-2 px-2 text-right text-gray-400">应发</th>
                <th className="py-2 px-2 text-right">社保(个人)</th>
                <th className="py-2 px-2 text-right">公积金(个人)</th>
                <th className="py-2 px-2 text-right text-gray-400">个税</th>
                <th className="py-2 px-2 text-right text-gray-400">实发</th>
                <th className="py-2 px-2">风险</th>
                {!isArchived && <th className="py-2 px-2">操作</th>}
              </tr>
            </thead>
            <tbody>
              {batch.entries.slice((page - 1) * pageSize, page * pageSize).map((entry: any) => (
                <tr key={entry.id} className="border-b last:border-0 hover:bg-gray-25">
                  <td className="py-2 px-2">
                    <div className="text-xs font-medium">{entry.employee.name}</div>
                    <div className="text-xs text-gray-400">{entry.employee.department}</div>
                    {entry.employee.status === 'RESIGNED' && (
                      <span className="text-xs text-danger">已离职</span>
                    )}
                  </td>
                  {renderCell(entry, 'baseSalary')}
                  {renderCell(entry, 'overtimePay')}
                  {renderCell(entry, 'allowance')}
                  {renderCell(entry, 'bonus')}
                  {renderCell(entry, 'deduction')}
                  {/* 计算项 - 灰显 */}
                  <td className="py-2 px-2 text-right font-medium text-gray-600">{fmt(entry.totalPay)}</td>
                  {renderCell(entry, 'socialEmp')}
                  {renderCell(entry, 'housingEmp')}
                  <td className="py-2 px-2 text-right text-gray-400">{fmt(entry.tax)}</td>
                  <td className="py-2 px-2 text-right font-bold text-safe">{fmt(entry.netPay)}</td>
                  <td className="py-2 px-2">
                    {entry.riskWarnings && entry.riskWarnings.length > 0 ? (
                      <span className="text-danger cursor-help" title={entry.riskWarnings.join('\n')}>
                        <AlertTriangle className="w-4 h-4" />
                      </span>
                    ) : (
                      <span className="text-gray-300">—</span>
                    )}
                  </td>
                  {!isArchived && (
                    <td className="py-2 px-2">
                      <button
                        onClick={() => removeEmployeeMutation.mutate(entry.employeeId)}
                        className="text-gray-400 hover:text-danger p-1"
                        title="移除"
                      >
                        <Trash2 className="w-3.5 h-3.5" />
                      </button>
                    </td>
                  )}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </Card>
    </div>
  )
}

function AddEmployeeToBatch({ batchId, onClose }: { batchId: string; onClose: () => void }) {
  const queryClient = useQueryClient()
  const [selected, setSelected] = useState<string[]>([])

  const { data: employees } = useQuery<any>({
    queryKey: ['employees-for-batch'],
    queryFn: async () => {
      const res = await api.get('/employees', { params: { pageSize: 100 } }) as any
      return res.data
    },
  })

  const addMutation = useMutation({
    mutationFn: (employeeIds: string[]) => api.post(`/payroll2/batches/${batchId}/employees`, { employeeIds }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['batch-detail'] })
      onClose()
    },
  })

  return (
    <Card>
      <div className="flex items-center justify-between mb-3">
        <h3 className="text-xs font-medium">添加人员到批次</h3>
        <button onClick={onClose} className="text-gray-400">✕</button>
      </div>
      <div className="max-h-60 overflow-y-auto space-y-1">
        {employees?.items?.map((emp: any) => (
          <label key={emp.id} className="flex items-center gap-2 p-2 hover:bg-gray-50 rounded cursor-pointer">
            <input
              type="checkbox"
              checked={selected.includes(emp.id)}
              onChange={(e) => {
                if (e.target.checked) setSelected([...selected, emp.id])
                else setSelected(selected.filter(id => id !== emp.id))
              }}
            />
            <span className="text-xs">{emp.name} - {emp.department}</span>
          </label>
        ))}
      </div>
      <div className="mt-3 flex gap-2">
        <Button size="sm" onClick={() => addMutation.mutate(selected)} disabled={selected.length === 0 || addMutation.isPending}>
          {addMutation.isPending ? '添加中...' : `添加 ${selected.length} 人`}
        </Button>
        <Button size="sm" variant="secondary" onClick={onClose}>取消</Button>
      </div>
    </Card>
  )
}

// ========== 薪酬模版管理 ==========

function TemplateManager() {
  const queryClient = useQueryClient()
  const { data: items, isLoading } = useQuery<any[]>({
    queryKey: ['payslip-template'],
    queryFn: async () => {
      const res = await api.get('/payroll2/template') as any
      return res.data
    },
  })

  const updateMutation = useMutation({
    mutationFn: ({ id, data }: { id: string; data: any }) => api.put(`/payroll2/template/${id}`, data),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['payslip-template'] }),
  })

  const deleteMutation = useMutation({
    mutationFn: (id: string) => api.delete(`/payroll2/template/${id}`),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['payslip-template'] }),
  })

  return (
    <div className="space-y-3">
      <Card>
        <div className="flex items-center justify-between mb-4">
          <h2 className="text-xs font-medium">薪酬结构模版</h2>
          <span className="text-xs text-gray-400">定义薪酬项和计算关系</span>
        </div>
        {isLoading ? (
          <div className="text-center py-4 text-gray-400">加载中...</div>
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full text-xs">
              <thead>
                <tr className="border-b text-left text-gray-500">
                  <th className="py-2 px-2">序号</th>
                  <th className="py-2 px-2">名称</th>
                  <th className="py-2 px-2">字段代码</th>
                  <th className="py-2 px-2">类型</th>
                  <th className="py-2 px-2">计算公式</th>
                  <th className="py-2 px-2">可编辑</th>
                  <th className="py-2 px-2">操作</th>
                </tr>
              </thead>
              <tbody>
                {items?.map((item: any) => (
                  <tr key={item.id} className="border-b last:border-0">
                    <td className="py-2 px-2 text-gray-400">{item.order}</td>
                    <td className="py-2 px-2 text-xs font-medium">{item.name}</td>
                    <td className="py-2 px-2 text-gray-500 font-mono text-xs">{item.code}</td>
                    <td className="py-2 px-2">
                      <span className={`px-2 py-0.5 rounded text-xs ${item.type === 'INPUT' ? 'bg-blue-50 text-blue-600' : 'bg-purple-50 text-purple-600'}`}>
                        {item.type === 'INPUT' ? '输入项' : '计算项'}
                      </span>
                    </td>
                    <td className="py-2 px-2 text-gray-500 text-xs font-mono">{item.formula || '—'}</td>
                    <td className="py-2 px-2">
                      <span className={`text-xs ${item.isEditable ? 'text-safe' : 'text-gray-400'}`}>
                        {item.isEditable ? '可编辑' : '不可编辑'}
                      </span>
                    </td>
                    <td className="py-2 px-2">
                      {!item.isDefault && (
                        <button
                          onClick={() => deleteMutation.mutate(item.id)}
                          className="text-xs text-gray-400 hover:text-danger"
                        >
                          删除
                        </button>
                      )}
                      {item.isDefault && <span className="text-xs text-gray-300">预置</span>}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
        <p className="text-xs text-gray-400 mt-3">
          预置项为系统默认薪酬结构，不可删除。计算项的公式支持引用其他字段进行自动计算。
        </p>
      </Card>
    </div>
  )
}

function OvertimeCalculator() {
  const queryClient = useQueryClient()
  const [step, setStep] = useState<1 | 2 | 3>(1)
  const [month, setMonth] = useState(new Date().toISOString().slice(0, 7))
  const fileInputRef = useRef<HTMLInputElement>(null)
  const [previewData, setPreviewData] = useState<any[]>([])

  // 加班费规则配置
  const { data: config, isLoading: configLoading } = useQuery<any>({
    queryKey: ['overtime-config'],
    queryFn: async () => {
      const res = await api.get('/payroll/overtime/config') as any
      return res.data
    },
  })

  const saveConfigMutation = useMutation({
    mutationFn: (data: any) => api.post('/payroll/overtime/config', data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['overtime-config'] })
    },
  })

  // 员工列表
  const { data: employees } = useQuery<{ items: { id: string; name: string; department: string }[] }>({
    queryKey: ['employees-for-overtime'],
    queryFn: async () => {
      const res = await api.get('/employees', { params: { pageSize: 100 } }) as any
      return res.data
    },
  })

  // 加班记录
  const { data: overtimeRecords, refetch } = useQuery<any[]>({
    queryKey: ['overtime-records', month],
    queryFn: async () => {
      const res = await api.get('/payroll/overtime', { params: { month } }) as any
      return res.data
    },
    enabled: step === 3,
  })

  const batchImportMutation = useMutation({
    mutationFn: (data: any[]) => api.post('/payroll/overtime/batch', data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['overtime-records'] })
      setPreviewData([])
      setStep(3)
    },
  })

  const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (!file) return
    const reader = new FileReader()
    reader.onload = (event) => {
      const text = event.target?.result as string
      const lines = text.split('\n').filter(l => l.trim())
      const items: any[] = []
      const empList = employees?.items || []
      for (let i = 1; i < lines.length; i++) {
        const cols = lines[i].split(',').map(c => c.trim())
        const empName = cols[0]
        const emp = empList.find(e => e.name === empName)
        if (!emp) continue
        items.push({
          employeeId: emp.id,
          employeeName: emp.name,
          department: emp.department,
          month: cols[4] || month,
          weekdayHours: Number(cols[1]) || 0,
          weekendHours: Number(cols[2]) || 0,
          holidayHours: Number(cols[3]) || 0,
        })
      }
      if (items.length > 0) {
        setPreviewData(items)
      } else {
        alert('未匹配到员工，请确保CSV第一列为员工姓名')
      }
    }
    reader.readAsText(file)
  }

  const confirmImport = () => {
    const payload = previewData.map(d => ({
      employeeId: d.employeeId,
      month: d.month,
      weekdayHours: d.weekdayHours,
      weekendHours: d.weekendHours,
      holidayHours: d.holidayHours,
    }))
    batchImportMutation.mutate(payload)
  }

  const cfg = config || { weekdayRate: 1.5, weekendRate: 2.0, holidayRate: 3.0, monthlyDays: 21.75, dailyHours: 8 }

  return (
    <div className="space-y-4">
      {/* 步骤指示器 */}
      <div className="flex items-center gap-2">
        {[
          { n: 1, label: '设定计算规则' },
          { n: 2, label: '导入考勤数据' },
          { n: 3, label: '查看加班记录' },
        ].map((s) => (
          <div key={s.n} className="flex items-center gap-2">
            <button
              onClick={() => setStep(s.n as 1 | 2 | 3)}
              className={`px-3 py-1.5 rounded text-xs flex items-center gap-1.5 transition-colors ${
                step === s.n ? 'bg-primary text-white' : 'bg-gray-100 text-gray-500 hover:bg-gray-200'
              }`}
            >
              <span className={`w-4 h-4 rounded-full flex items-center justify-center text-xs ${
                step === s.n ? 'bg-white/20' : step > s.n ? 'bg-safe text-white' : 'bg-gray-300 text-white'
              }`}>{step > s.n ? '✓' : s.n}</span>
              {s.label}
            </button>
            {s.n < 3 && <div className="w-4 h-px bg-gray-300" />}
          </div>
        ))}
      </div>

      {/* Step 1: 设定计算规则 */}
      {step === 1 && (
        <Card>
          <h2 className="text-xs font-medium mb-3 flex items-center gap-2"><SettingsIcon className="w-4 h-4" />加班费计算规则</h2>
          {configLoading ? (
            <div className="text-center py-8 text-gray-400">加载中...</div>
          ) : (
            <div className="space-y-4">
              <div className="grid md:grid-cols-3 gap-4">
                <div>
                  <Label>工作日加班倍率</Label>
                  <Input type="number" step="0.1" defaultValue={cfg.weekdayRate} onBlur={(e) => saveConfigMutation.mutate({ ...cfg, weekdayRate: Number(e.target.value) })} />
                  <p className="text-xs text-gray-400 mt-1">平时加班按小时工资的倍率</p>
                </div>
                <div>
                  <Label>休息日加班倍率</Label>
                  <Input type="number" step="0.1" defaultValue={cfg.weekendRate} onBlur={(e) => saveConfigMutation.mutate({ ...cfg, weekendRate: Number(e.target.value) })} />
                  <p className="text-xs text-gray-400 mt-1">周末加班按小时工资的倍率</p>
                </div>
                <div>
                  <Label>法定节假日加班倍率</Label>
                  <Input type="number" step="0.1" defaultValue={cfg.holidayRate} onBlur={(e) => saveConfigMutation.mutate({ ...cfg, holidayRate: Number(e.target.value) })} />
                  <p className="text-xs text-gray-400 mt-1">法定节假日加班按小时工资的倍率</p>
                </div>
              </div>
              <div className="grid md:grid-cols-2 gap-4">
                <div>
                  <Label>月计薪天数</Label>
                  <Input type="number" step="0.01" defaultValue={cfg.monthlyDays} onBlur={(e) => saveConfigMutation.mutate({ ...cfg, monthlyDays: Number(e.target.value) })} />
                  <p className="text-xs text-gray-400 mt-1">用于折算日工资/小时工资（默认21.75天）</p>
                </div>
                <div>
                  <Label>每日工时（小时）</Label>
                  <Input type="number" step="0.5" defaultValue={cfg.dailyHours} onBlur={(e) => saveConfigMutation.mutate({ ...cfg, dailyHours: Number(e.target.value) })} />
                  <p className="text-xs text-gray-400 mt-1">用于折算小时工资（默认8小时）</p>
                </div>
              </div>
              <div className="bg-blue-50 text-blue-700 text-xs px-3 py-2 rounded-md flex items-start gap-2">
                <Info className="w-4 h-4 mt-0.5 shrink-0" />
                <div>
                  <p>计算公式：小时工资 = 月工资 ÷ 月计薪天数 ÷ 每日工时</p>
                  <p>加班费 = 小时工资 × 倍率 × 加班工时</p>
                  <p className="mt-1 text-gray-500">实际金额在发薪批次中根据员工月工资自动计算，此处只配置倍率规则。</p>
                </div>
              </div>
              {saveConfigMutation.isSuccess && (
                <div className="text-xs text-safe flex items-center gap-1"><Check className="w-3.5 h-3.5" />规则已保存</div>
              )}
              <div className="flex justify-end">
                <Button onClick={() => setStep(2)}>下一步：导入考勤数据 →</Button>
              </div>
            </div>
          )}
        </Card>
      )}

      {/* Step 2: 导入考勤数据 */}
      {step === 2 && (
        <Card>
          <h2 className="text-xs font-medium mb-3 flex items-center gap-2"><Upload className="w-4 h-4" />导入加班工时</h2>
          <div className="space-y-4">
            <div>
              <Label>月份</Label>
              <Input type="month" value={month} onChange={(e) => setMonth(e.target.value)} className="w-48" />
            </div>
            <div className="border-t pt-3">
              <input ref={fileInputRef} type="file" accept=".csv" className="hidden" onChange={handleFileUpload} />
              <Button variant="secondary" onClick={() => fileInputRef.current?.click()} disabled={batchImportMutation.isPending}>
                <Upload className="w-4 h-4 mr-1" />
                {batchImportMutation.isPending ? '导入中...' : '选择CSV文件'}
              </Button>
              <div className="text-xs text-gray-400 mt-2">
                CSV格式：姓名,工作日加班(h),休息日加班(h),节假日加班(h),月份(可选)
              </div>
            </div>

            {previewData.length > 0 && (
              <div className="border-t pt-3 space-y-3">
                <div className="text-xs font-medium text-gray-700">预览（{previewData.length}条）</div>
                <div className="overflow-x-auto">
                  <table className="w-full text-xs">
                    <thead>
                      <tr className="border-b text-gray-500">
                        <th className="py-2 text-left">员工</th>
                        <th className="py-2 text-left">部门</th>
                        <th className="py-2 text-right">工作日(h)</th>
                        <th className="py-2 text-right">休息日(h)</th>
                        <th className="py-2 text-right">节假日(h)</th>
                        <th className="py-2 text-left">月份</th>
                      </tr>
                    </thead>
                    <tbody>
                      {previewData.map((d, i) => (
                        <tr key={i} className="border-b last:border-0">
                          <td className="py-2">{d.employeeName}</td>
                          <td className="py-2 text-gray-500">{d.department}</td>
                          <td className="py-2 text-right">{d.weekdayHours}</td>
                          <td className="py-2 text-right">{d.weekendHours}</td>
                          <td className="py-2 text-right">{d.holidayHours}</td>
                          <td className="py-2 text-gray-500">{d.month}</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
                <div className="flex gap-2">
                  <Button onClick={confirmImport} disabled={batchImportMutation.isPending}>
                    {batchImportMutation.isPending ? '保存中...' : '确认导入'}
                  </Button>
                  <Button variant="secondary" onClick={() => setPreviewData([])}>取消</Button>
                </div>
              </div>
            )}

            <div className="flex justify-between border-t pt-3">
              <Button variant="secondary" onClick={() => setStep(1)}>← 上一步</Button>
              <Button onClick={() => setStep(3)}>下一步：查看加班记录 →</Button>
            </div>
          </div>
        </Card>
      )}

      {/* Step 3: 查看加班记录 */}
      {step === 3 && (
        <Card>
          <div className="flex items-center justify-between mb-3">
            <h2 className="text-xs font-medium flex items-center gap-2"><FileText className="w-4 h-4" />加班记录（{month}）</h2>
            <div className="flex items-center gap-2">
              <Input type="month" value={month} onChange={(e) => setMonth(e.target.value)} className="w-32" />
              <Button variant="secondary" size="sm" onClick={() => refetch()}>刷新</Button>
            </div>
          </div>
          {!overtimeRecords || overtimeRecords.length === 0 ? (
            <div className="text-center py-8 text-gray-400">该月暂无加班记录，请先导入考勤数据</div>
          ) : (
            <div className="overflow-x-auto">
              <table className="w-full text-xs">
                <thead>
                  <tr className="border-b text-gray-500">
                    <th className="py-2 text-left">员工</th>
                    <th className="py-2 text-left">部门</th>
                    <th className="py-2 text-right">工作日(h)</th>
                    <th className="py-2 text-right">休息日(h)</th>
                    <th className="py-2 text-right">节假日(h)</th>
                    <th className="py-2 text-right">加班费</th>
                    <th className="py-2 text-center">状态</th>
                  </tr>
                </thead>
                <tbody>
                  {overtimeRecords.map((r: any) => (
                    <tr key={r.id} className="border-b last:border-0 hover:bg-gray-50">
                      <td className="py-2">{r.employee?.name}</td>
                      <td className="py-2 text-gray-500">{r.employee?.department}</td>
                      <td className="py-2 text-right">{r.weekdayHours || '-'}</td>
                      <td className="py-2 text-right">{r.weekendHours || '-'}</td>
                      <td className="py-2 text-right">{r.holidayHours || '-'}</td>
                      <td className="py-2 text-right font-medium text-gray-700">
                        {r.totalPay > 0 ? `¥${fmt(r.totalPay)}` : <span className="text-gray-400">待计算</span>}
                      </td>
                      <td className="py-2 text-center">
                        {r.batchId ? (
                          <span className="px-2 py-0.5 rounded bg-green-50 text-safe text-xs">已入批次</span>
                        ) : (
                          <span className="px-2 py-0.5 rounded bg-amber-50 text-amber-600 text-xs">未入批次</span>
                        )}
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
          <div className="flex justify-between border-t pt-3 mt-3">
            <Button variant="secondary" onClick={() => setStep(2)}>← 上一步</Button>
            <div className="text-xs text-gray-400 flex items-center gap-1">
              <Info className="w-3.5 h-3.5" />
              加班费金额在发薪批次中「导入加班费」时自动计算
            </div>
          </div>
        </Card>
      )}
    </div>
  )
}

function ResultRow({ label, value }: { label: string; value: number }) {
  return (
    <div className="flex items-center justify-between text-xs">
      <span className="text-gray-600">{label}</span>
      <span className="font-medium">¥{fmt(value)}</span>
    </div>
  )
}

function PayslipManager() {
  const queryClient = useQueryClient()
  const [month, setMonth] = useState(new Date().toISOString().slice(0, 7))
  const [page, setPage] = useState(1)
  const [pageSize, setPageSize] = useState(10)

  const { data: payslips, isLoading } = useQuery<any[]>({
    queryKey: ['payslips', month],
    queryFn: async () => {
      const res = await api.get('/payroll/payslip', { params: { month } }) as any
      return res.data
    },
  })

  const deleteMutation = useMutation({
    mutationFn: (id: string) => api.delete(`/payroll/payslip/${id}`),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['payslips'] }),
  })

  const generateFromBatchMutation = useMutation({
    mutationFn: (data: any) => api.post('/payroll2/payslips/generate', data),
    onSuccess: (res: any) => {
      queryClient.invalidateQueries({ queryKey: ['payslips'] })
      queryClient.invalidateQueries({ queryKey: ['dashboard'] })
      const n = res?.data?.generated || 0
      alert(`已从归档批次汇总生成 ${n} 条工资条并发布。`)
    },
  })

  const confirmedCount = payslips?.filter((p: any) => p.confirmedAt).length || 0
  const unconfirmedCount = payslips ? payslips.length - confirmedCount : 0

  return (
    <div className="space-y-3">
      <div className="flex items-center justify-between gap-2">
        <div className="flex items-center gap-3">
          <Input type="month" value={month} onChange={(e) => setMonth(e.target.value)} className="w-48" />
          {payslips && payslips.length > 0 && (
            <div className="flex gap-2 text-xs">
              <span className="px-2 py-0.5 rounded bg-gray-100 text-gray-600">共 {payslips.length} 条</span>
              <span className="px-2 py-0.5 rounded bg-green-50 text-safe">已确认 {confirmedCount}</span>
              <span className="px-2 py-0.5 rounded bg-amber-50 text-warning">未确认 {unconfirmedCount}</span>
            </div>
          )}
        </div>
        <div className="flex gap-2">
          <Button
            onClick={() => {
              if (confirm(`确认从 ${month} 已归档批次汇总生成工资条？这将覆盖已有的工资条数据。`)) {
                generateFromBatchMutation.mutate({ month })
              }
            }}
            disabled={generateFromBatchMutation.isPending}
          >
            <Layers className="w-4 h-4 mr-1" />
            {generateFromBatchMutation.isPending ? '生成中...' : '从批次汇总生成'}
          </Button>
        </div>
      </div>

      {isLoading ? (
        <div className="text-center py-8 text-gray-400">加载中...</div>
      ) : !payslips || payslips.length === 0 ? (
        <Card><div className="text-center py-8 text-gray-400">该月份暂无工资条记录</div></Card>
      ) : (
        <Card>
          <Pagination page={page} pageSize={pageSize} total={payslips.length} onPageChange={setPage} onPageSizeChange={(s) => { setPageSize(s); setPage(1) }} />
          <div className="overflow-x-auto">
            <table className="w-full text-xs">
              <thead>
                <tr className="border-b text-left text-gray-500">
                  <th className="py-2">员工</th>
                  <th className="py-2">部门</th>
                  <th className="py-2 text-right">基本工资</th>
                  <th className="py-2 text-right">加班费</th>
                  <th className="py-2 text-right">津贴</th>
                  <th className="py-2 text-right">扣款</th>
                  <th className="py-2 text-right">应发合计</th>
                  <th className="py-2 text-center">确认状态</th>
                  <th className="py-2"></th>
                </tr>
              </thead>
              <tbody>
                {payslips.slice((page - 1) * pageSize, page * pageSize).map((p: any) => (
                  <tr key={p.id} className="border-b last:border-0">
                    <td className="py-2">{p.employee?.name}</td>
                    <td className="py-2 text-gray-500">{p.employee?.department}</td>
                    <td className="py-2 text-right">¥{fmt(p.baseSalary)}</td>
                    <td className="py-2 text-right">¥{fmt(p.overtimePay)}</td>
                    <td className="py-2 text-right">¥{fmt(p.allowance)}</td>
                    <td className="py-2 text-right text-danger">{p.deduction > 0 ? '-¥' + fmt(p.deduction) : '¥0'}</td>
                    <td className="py-2 text-right font-bold">¥{fmt(p.totalPay)}</td>
                    <td className="py-2 text-center">
                      {p.confirmedAt ? (
                        <span className="inline-flex items-center gap-1 text-safe text-xs">
                          <Check className="w-3 h-3" />已确认
                        </span>
                      ) : (
                        <span className="text-warning text-xs">未确认</span>
                      )}
                    </td>
                    <td className="py-2">
                      <button
                        onClick={() => deleteMutation.mutate(p.id)}
                        className="text-xs text-gray-400 hover:text-danger"
                      >
                        删除
                      </button>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </Card>
      )}
    </div>
  )
}
