import { useEffect, useState } from 'react'
import { api } from '../api/client'
import { Spinner } from '../components/Spinner'
import { Layout } from '../components/Layout'
import type { PayrollAssignmentReport } from '../types/specialAssignment'

interface UserOut {
  id: string; first_name: string; last_name: string; email: string; role: string
}
interface UserListItem { id: string; full_name: string; email: string }

// ── Backend shapes ──────────────────────────────────────────────────────────
interface HoursBreakdown {
  normal_hours: number
  night_25_hours: number
  night_40_hours: number
  sunday_hours: number
  holiday_125_hours: number
  holiday_150_hours: number
  holiday_name: string | null
}

interface TimeReportRow {
  date: string; user_id: string; user_name: string; personnel_number: string | null; department: string | null
  start_time: string; end_time: string | null; break_minutes: number
  worked_hours: number | null; status: string; source: string; note: string | null
  breakdown: HoursBreakdown | null
}
interface TimeReport { date_from: string; date_to: string; total_rows: number; total_hours: number; rows: TimeReportRow[] }

interface AbsenceReportRow {
  user_id: string; user_name: string; personnel_number: string | null; department: string | null
  absence_type: string; start_date: string; end_date: string
  working_days: number; status: string; note: string | null
}
interface AbsenceReport { date_from: string; date_to: string; total_rows: number; total_days: number; rows: AbsenceReportRow[] }

interface OvertimeReportRow {
  user_id: string; user_name: string; personnel_number: string | null; department: string | null
  hours_worked: number; hours_expected: number; overtime_hours: number
}
interface OvertimeReport { date_from: string; date_to: string; total_employees: number; total_overtime: number; rows: OvertimeReportRow[] }

interface DayEntry {
  start_time: string; end_time: string; break_minutes: number
  hours_worked: number; status: string; arbzg_warnings: string[]
  breakdown: HoursBreakdown | null
}
interface OvertimeDay {
  date: string; weekday: string
  hours_worked: number; hours_expected: number; overtime: number
  entries: DayEntry[]
}
interface OvertimeWeek {
  week_nr: number; week_start: string; week_end: string
  hours_worked: number; hours_expected: number; overtime: number
  days: OvertimeDay[]
}
interface OvertimeReportRowDetailed extends OvertimeReportRow {
  weeks: OvertimeWeek[]
  arbzg_violation_days: number
  special_hours_total: HoursBreakdown | null
}
interface OvertimeReportDetailed { date_from: string; date_to: string; total_employees: number; total_overtime: number; rows: OvertimeReportRowDetailed[] }

interface SickStatsRow {
  user_id: string; user_name: string; personnel_number: string | null
  episodes: number; total_days: number; bradford_factor: number; certificates_overdue: number
}

// ── Helpers ─────────────────────────────────────────────────────────────────
type ReportType = 'time' | 'absences' | 'overtime' | 'sick' | 'special'
const MANAGER_ROLES = ['COMPANY_ADMIN', 'SUPER_ADMIN', 'HR', 'MANAGER']

const STATUS_DE: Record<string, string> = {
  open: 'Offen', pending: 'Prüfung', approved: 'Genehmigt',
  rejected: 'Abgelehnt', auto: 'Auto', cancelled: 'Storniert',
}
const STATUS_COLORS: Record<string, string> = {
  open: 'bg-yellow-100 text-yellow-700', pending: 'bg-blue-100 text-blue-700',
  approved: 'bg-green-100 text-green-700', rejected: 'bg-red-100 text-red-700',
  auto: 'bg-gray-100 text-gray-600', cancelled: 'bg-gray-100 text-gray-400',
}

function fmt(t: string | null): string {
  if (!t) return '–'
  if (/^\d{2}:\d{2}(:\d{2})?$/.test(t)) return t.slice(0, 5)
  const d = new Date(t)
  return isNaN(d.getTime()) ? t.slice(0, 5) : d.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' })
}
function fmtDate(s: string) { return new Date(s + 'T00:00:00').toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' }) }
function fmtH(h: number) {
  const hrs = Math.floor(Math.abs(h)); const min = Math.round((Math.abs(h) - hrs) * 60)
  return `${h < 0 ? '-' : ''}${hrs}h ${min.toString().padStart(2, '0')}m`
}

function monthRange(offset = 0): [string, string] {
  const d = new Date(); d.setMonth(d.getMonth() + offset, 1)
  const from = d.toISOString().slice(0, 8) + '01'
  const last = new Date(d.getFullYear(), d.getMonth() + 1, 0)
  return [from, last.toISOString().slice(0, 10)]
}
function quarterRange(): [string, string] {
  const d = new Date(); const q = Math.floor(d.getMonth() / 3)
  const from = new Date(d.getFullYear(), q * 3, 1).toISOString().slice(0, 10)
  const to   = new Date(d.getFullYear(), q * 3 + 3, 0).toISOString().slice(0, 10)
  return [from, to]
}

// Group rows by user
function groupBy<T extends { user_id: string; user_name: string }>(rows: T[]): Map<string, T[]> {
  const m = new Map<string, T[]>()
  for (const r of rows) {
    if (!m.has(r.user_id)) m.set(r.user_id, [])
    m.get(r.user_id)!.push(r)
  }
  return m
}

export function ReportsPage() {
  const [user, setUser]             = useState<UserOut | null>(null)
  const [colleagues, setColleagues] = useState<UserListItem[]>([])
  const [type, setType]             = useState<ReportType>('time')
  const [dateFrom, setDateFrom]     = useState(monthRange()[0])
  const [dateTo, setDateTo]         = useState(monthRange()[1])
  const [filterUser, setFilterUser] = useState('')

  const [timeReport,          setTimeReport]          = useState<TimeReport | null>(null)
  const [absenceReport,       setAbsenceReport]       = useState<AbsenceReport | null>(null)
  const [overtimeReport,      setOvertimeReport]      = useState<OvertimeReport | null>(null)
  const [overtimeDetail,      setOvertimeDetail]      = useState<OvertimeReportDetailed | null>(null)
  const [overtimeView,        setOvertimeView]        = useState<'simple' | 'detail'>('simple')
  const [expandedUsers,       setExpandedUsers]       = useState<Set<string>>(new Set())
  const [expandedWeeks,       setExpandedWeeks]       = useState<Set<string>>(new Set())
  const [sickStats,           setSickStats]           = useState<SickStatsRow[] | null>(null)
  const [payrollReport,       setPayrollReport]       = useState<PayrollAssignmentReport | null>(null)
  // für Sondervertretungs-Tab: Jahr/Monat-Auswahl
  const [specialYear,  setSpecialYear]  = useState(new Date().getFullYear())
  const [specialMonth, setSpecialMonth] = useState(new Date().getMonth() + 1)

  const [loading, setLoading] = useState(false)
  const [error,   setError]   = useState('')

  const isManager = MANAGER_ROLES.includes(user?.role ?? '')

  useEffect(() => {
    api.get<UserOut>('/auth/me').then(me => {
      setUser(me)
      if (MANAGER_ROLES.includes(me.role)) {
        api.get<{ items: UserListItem[] }>('/users/?limit=500').then(r => setColleagues(r.items)).catch(() => {})
      }
    }).catch(() => {})
  }, [])

  const run = async () => {
    setLoading(true); setError('')
    const p = `?date_from=${dateFrom}&date_to=${dateTo}${filterUser ? `&user_id=${filterUser}` : ''}`
    try {
      if (type === 'time') {
        setTimeReport(await api.get<TimeReport>(`/reports/time${p}`))
        setAbsenceReport(null); setOvertimeReport(null); setSickStats(null)
      } else if (type === 'absences') {
        setAbsenceReport(await api.get<AbsenceReport>(`/reports/absences${p}`))
        setTimeReport(null); setOvertimeReport(null); setSickStats(null)
      } else if (type === 'sick') {
        const params = filterUser ? `?user_id=${filterUser}` : ''
        const stats = await api.get<SickStatsRow[]>(`/absences/sick-stats${params}`)
        setSickStats(stats)
        setTimeReport(null); setAbsenceReport(null); setOvertimeReport(null)
      } else if (type === 'special') {
        const report = await api.get<PayrollAssignmentReport>(
          `/reports/special-assignments/payroll?year=${specialYear}&month=${specialMonth}`
        )
        setPayrollReport(report)
        setTimeReport(null); setAbsenceReport(null); setOvertimeReport(null); setSickStats(null)
      } else {
        const [simple, detail] = await Promise.all([
          api.get<OvertimeReport>(`/reports/overtime${p}`),
          api.get<OvertimeReportDetailed>(`/reports/overtime/detail${p}`),
        ])
        setOvertimeReport(simple)
        setOvertimeDetail(detail)
        setExpandedUsers(new Set())
        setExpandedWeeks(new Set())
        setTimeReport(null); setAbsenceReport(null); setSickStats(null); setPayrollReport(null)
      }
    } catch (e: unknown) { setError(e instanceof Error ? e.message : 'Fehler') }
    finally { setLoading(false) }
  }

  const download = async (format: 'csv' | 'xlsx' | 'pdf') => {
    if (type === 'special' || type === 'sick') return  // eigener Export in der Tabelle
    const p = `?date_from=${dateFrom}&date_to=${dateTo}${filterUser ? `&user_id=${filterUser}` : ''}&format=${format}`
    const ep = type === 'time' ? `/reports/time/export${p}` : type === 'absences' ? `/reports/absences/export${p}` : `/reports/overtime/export${p}`
    const token = localStorage.getItem('access_token')
    const res = await fetch(`/api/v1${ep}`, { headers: { Authorization: `Bearer ${token}` } })
    if (!res.ok) { setError('Export fehlgeschlagen'); return }
    const blob = await res.blob()
    const a = document.createElement('a'); a.href = URL.createObjectURL(blob)
    a.download = `${type}_${dateFrom}_${dateTo}.${format}`; a.click()
  }

  const downloadDatev = async () => {
    if (isManager && !filterUser) { setError('DATEV-Monatsblatt: bitte oben einen einzelnen Mitarbeiter auswählen.'); return }
    const uid = filterUser || user?.id
    if (!uid) { setError('Bitte einen Mitarbeiter auswählen.'); return }
    const d = new Date(dateFrom)
    const year = d.getFullYear()
    const month = d.getMonth() + 1
    const token = localStorage.getItem('access_token')
    const res = await fetch(
      `/api/v1/reports/datev-monthly/export?user_id=${uid}&year=${year}&month=${month}`,
      { headers: { Authorization: `Bearer ${token}` } }
    )
    if (!res.ok) { setError('DATEV-Export fehlgeschlagen'); return }
    const blob = await res.blob()
    const a = document.createElement('a'); a.href = URL.createObjectURL(blob)
    a.download = `datev_stundenaufzeichnung_${year}_${String(month).padStart(2, '0')}.pdf`; a.click()
  }

  const setQuick = (from: string, to: string) => { setDateFrom(from); setDateTo(to) }

  const hasResult = !!(timeReport || absenceReport || overtimeReport || sickStats || payrollReport)

  return (
    <Layout userRole={user?.role ?? ''} userName={user ? `${user.first_name} ${user.last_name}` : ''}>
      <style>{`@media print { header,nav,.no-print{display:none!important} body{font-size:11px} }`}</style>
      <div className='space-y-5'>

        <div className='flex items-center justify-between no-print'>
          <h1 className='text-2xl font-bold text-gray-900'>Berichte</h1>
        </div>

        {/* ── Controls ───────────────────────────────────────────────────── */}
        <div className='bg-white rounded-xl shadow-sm border border-gray-200 p-5 no-print space-y-4'>

          {/* Report type */}
          <div className='flex rounded-lg border border-gray-300 overflow-hidden w-fit'>
            {([['time','Zeiterfassung'],['absences','Abwesenheiten'],['overtime','Überstunden'],['sick','Krankmeldungen'],['special','Sondervertretungen']] as [ReportType,string][]).map(([v,l]) => (
              <button key={v} onClick={() => setType(v)}
                className={`px-4 py-2 text-sm font-medium transition-colors ${type===v ? 'bg-blue-600 text-white' : 'text-gray-600 hover:bg-gray-50'}`}>
                {l}
              </button>
            ))}
          </div>

          <div className='flex flex-wrap gap-3 items-end'>
            {type !== 'special' && (
              <>
                {/* Quick-select */}
                <div>
                  <p className='text-xs font-medium text-gray-500 mb-1'>Schnellauswahl</p>
                  <div className='flex gap-1.5'>
                    {[['Dieser Monat', monthRange()],['Letzter Monat', monthRange(-1)],['Quartal', quarterRange()]] .map(([l, [f, t]]) => (
                      <button key={l as string} onClick={() => setQuick(f as string, t as string)}
                        className='px-3 py-1.5 text-xs border border-gray-300 rounded-lg text-gray-600 hover:bg-gray-50'>
                        {l as string}
                      </button>
                    ))}
                  </div>
                </div>
                {/* Date range */}
                <div>
                  <p className='text-xs font-medium text-gray-500 mb-1'>Von</p>
                  <input type='date' value={dateFrom} onChange={e => setDateFrom(e.target.value)}
                    className='border border-gray-300 rounded-lg px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500' />
                </div>
                <div>
                  <p className='text-xs font-medium text-gray-500 mb-1'>Bis</p>
                  <input type='date' value={dateTo} min={dateFrom} onChange={e => setDateTo(e.target.value)}
                    className='border border-gray-300 rounded-lg px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500' />
                </div>
              </>
            )}

            {type === 'special' && (
              <>
                <div>
                  <p className='text-xs font-medium text-gray-500 mb-1'>Jahr</p>
                  <input type='number' value={specialYear} min={2020} max={2100}
                    onChange={e => setSpecialYear(parseInt(e.target.value))}
                    className='border border-gray-300 rounded-lg px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 w-28' />
                </div>
                <div>
                  <p className='text-xs font-medium text-gray-500 mb-1'>Monat</p>
                  <select value={specialMonth} onChange={e => setSpecialMonth(parseInt(e.target.value))}
                    className='border border-gray-300 rounded-lg px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500'>
                    {['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'].map((m, i) => (
                      <option key={i+1} value={i+1}>{m}</option>
                    ))}
                  </select>
                </div>
              </>
            )}

            {/* Employee filter (manager only) – nicht für special */}
            {isManager && colleagues.length > 0 && type !== 'special' && (
              <div>
                <p className='text-xs font-medium text-gray-500 mb-1'>Mitarbeiter</p>
                <select value={filterUser} onChange={e => setFilterUser(e.target.value)}
                  className='border border-gray-300 rounded-lg px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500'>
                  <option value=''>Alle</option>
                  {colleagues.map(c => <option key={c.id} value={c.id}>{c.full_name}</option>)}
                </select>
              </div>
            )}

            <button onClick={run} disabled={loading}
              className='px-5 py-2 bg-blue-600 text-white rounded-lg text-sm font-medium hover:bg-blue-700 disabled:opacity-50 flex items-center gap-2'>
              {loading && <Spinner />} Auswerten
            </button>
          </div>
        </div>

        {error && <div className='bg-red-50 border border-red-200 rounded-lg p-3 text-sm text-red-700 no-print'>{error}</div>}

        {/* ── Results ────────────────────────────────────────────────────── */}
        {hasResult && (
          <div className='bg-white rounded-xl shadow-sm border border-gray-200'>

            {/* Header */}
            <div className='px-6 py-4 border-b border-gray-100 flex items-center justify-between flex-wrap gap-3'>
              <div>
                <h2 className='font-semibold text-gray-800'>
                  {type === 'time' ? 'Zeiterfassung' : type === 'absences' ? 'Abwesenheiten' : type === 'overtime' ? 'Überstunden' : type === 'special' ? 'Sondervertretungen' : 'Krankmeldungen'}
                </h2>
                <p className='text-xs text-gray-400 mt-0.5'>
                  {type === 'sick' ? 'Rolling 12 Monate ab heute' : type === 'special' ? `${specialYear}, Monat ${specialMonth}` : `${fmtDate(dateFrom)} – ${fmtDate(dateTo)}`}
                </p>
              </div>
              <div className='flex gap-2 no-print'>
                <button onClick={() => window.print()} className='text-xs px-3 py-1.5 border border-gray-300 rounded-lg text-gray-600 hover:bg-gray-50'>Drucken</button>
                {type !== 'sick' && type !== 'special' && (<>
                  <button onClick={() => download('csv')} className='text-xs px-3 py-1.5 border border-gray-300 rounded-lg text-gray-600 hover:bg-gray-50'>CSV</button>
                  <button onClick={() => download('xlsx')} className='text-xs px-3 py-1.5 bg-green-600 text-white rounded-lg hover:bg-green-700'>Excel</button>
                  <button onClick={() => download('pdf')} className='text-xs px-3 py-1.5 bg-red-600 text-white rounded-lg hover:bg-red-700'>PDF</button>
                </>)}
                {type === 'time' && (
                  <button onClick={downloadDatev}
                    title='Stundenaufzeichnung im DATEV-Blanko-Layout, ein Blatt pro Mitarbeiter/Monat'
                    className='text-xs px-3 py-1.5 bg-purple-600 text-white rounded-lg hover:bg-purple-700'>
                    DATEV-Monatsblatt
                  </button>
                )}
              </div>
            </div>

            {/* ── KPI row ── */}
            {timeReport && (
              <div className='grid grid-cols-3 divide-x divide-gray-100 border-b border-gray-100'>
                <div className='px-6 py-4'><p className='text-xs text-gray-500'>Einträge</p><p className='text-2xl font-bold text-gray-800'>{timeReport.total_rows}</p></div>
                <div className='px-6 py-4'><p className='text-xs text-gray-500'>Gesamt-Stunden</p><p className='text-2xl font-bold text-blue-700'>{fmtH(timeReport.total_hours)}</p></div>
                <div className='px-6 py-4'><p className='text-xs text-gray-500'>Mitarbeiter</p><p className='text-2xl font-bold text-gray-800'>{new Set(timeReport.rows.map(r => r.user_id)).size}</p></div>
              </div>
            )}
            {absenceReport && (
              <div className='grid grid-cols-3 divide-x divide-gray-100 border-b border-gray-100'>
                <div className='px-6 py-4'><p className='text-xs text-gray-500'>Anträge</p><p className='text-2xl font-bold text-gray-800'>{absenceReport.total_rows}</p></div>
                <div className='px-6 py-4'><p className='text-xs text-gray-500'>Gesamt-Arbeitstage</p><p className='text-2xl font-bold text-orange-600'>{absenceReport.total_days}</p></div>
                <div className='px-6 py-4'><p className='text-xs text-gray-500'>Mitarbeiter betroffen</p><p className='text-2xl font-bold text-gray-800'>{new Set(absenceReport.rows.map(r => r.user_id)).size}</p></div>
              </div>
            )}
            {overtimeReport && (
              <div className='grid grid-cols-3 divide-x divide-gray-100 border-b border-gray-100'>
                <div className='px-6 py-4'><p className='text-xs text-gray-500'>Mitarbeiter</p><p className='text-2xl font-bold text-gray-800'>{overtimeReport.total_employees}</p></div>
                <div className='px-6 py-4'><p className='text-xs text-gray-500'>Gesamt-Überstunden</p>
                  <p className={`text-2xl font-bold ${overtimeReport.total_overtime >= 0 ? 'text-green-600' : 'text-red-600'}`}>{fmtH(overtimeReport.total_overtime)}</p>
                </div>
                <div className='px-6 py-4'><p className='text-xs text-gray-500'>Periode</p><p className='text-sm font-medium text-gray-700 mt-1'>{fmtDate(overtimeReport.date_from)} – {fmtDate(overtimeReport.date_to)}</p></div>
              </div>
            )}
            {sickStats && (() => {
              const totalDays = sickStats.reduce((s, r) => s + r.total_days, 0)
              const totalEpisodes = sickStats.reduce((s, r) => s + r.episodes, 0)
              const overdue = sickStats.reduce((s, r) => s + r.certificates_overdue, 0)
              const avgBradford = sickStats.length ? sickStats.reduce((s, r) => s + r.bradford_factor, 0) / sickStats.length : 0
              return (
                <div className='grid grid-cols-4 divide-x divide-gray-100 border-b border-gray-100'>
                  <div className='px-6 py-4'><p className='text-xs text-gray-500'>⌀ Bradford-Index</p><p className='text-2xl font-bold text-orange-600'>{avgBradford.toFixed(1)}</p></div>
                  <div className='px-6 py-4'><p className='text-xs text-gray-500'>Σ Kranktage</p><p className='text-2xl font-bold text-gray-800'>{totalDays.toFixed(1)}</p></div>
                  <div className='px-6 py-4'><p className='text-xs text-gray-500'>Σ Episoden</p><p className='text-2xl font-bold text-gray-800'>{totalEpisodes}</p></div>
                  <div className='px-6 py-4'><p className='text-xs text-gray-500'>AU überfällig</p><p className={`text-2xl font-bold ${overdue > 0 ? 'text-red-600' : 'text-gray-400'}`}>{overdue}</p></div>
                </div>
              )
            })()}

            {/* ── Time table (grouped by employee) ── */}
            {timeReport && (() => {
              const groups = groupBy(timeReport.rows)
              return (
                <div className='overflow-x-auto'>
                  <table className='w-full text-sm'>
                    <thead className='bg-gray-50 text-xs text-gray-500 uppercase tracking-wide sticky top-0'>
                      <tr>
                        <th className='px-4 py-3 text-left'>Datum</th>
                        {!filterUser && <th className='px-4 py-3 text-left'>Mitarbeiter</th>}
                        {isManager && <th className='px-4 py-3 text-left'>Abteilung</th>}
                        <th className='px-4 py-3 text-left'>Beginn</th>
                        <th className='px-4 py-3 text-left'>Ende</th>
                        <th className='px-4 py-3 text-right'>Pause</th>
                        <th className='px-4 py-3 text-right'>Netto</th>
                        <th className='px-4 py-3 text-left'>Status</th>
                        <th className='px-4 py-3 text-left'>Notiz</th>
                      </tr>
                    </thead>
                    <tbody>
                      {Array.from(groups.entries()).map(([uid, rows], gi) => {
                        const subtotal = rows.reduce((s, r) => s + (r.worked_hours ?? 0), 0)
                        return (
                          <>
                            {/* Employee header row */}
                            {!filterUser && (
                              <tr key={`hdr-${uid}`} className={`${gi > 0 ? 'border-t-2 border-gray-200' : ''} bg-gray-50`}>
                                <td colSpan={isManager ? 9 : 8} className='px-4 py-2'>
                                  <span className='font-semibold text-gray-700 text-sm'>{rows[0].user_name}</span>
                                  {rows[0].department && <span className='ml-2 text-xs text-gray-400'>{rows[0].department}</span>}
                                  <span className='ml-3 text-xs font-medium text-blue-600'>{fmtH(subtotal)} gesamt</span>
                                </td>
                              </tr>
                            )}
                            {rows.map((row, i) => {
                              const bd = row.breakdown
                              const hasSonder = bd && (
                                bd.night_25_hours > 0 || bd.night_40_hours > 0 ||
                                bd.sunday_hours > 0 || bd.holiday_125_hours > 0 || bd.holiday_150_hours > 0
                              )
                              const colSpan = (isManager ? 2 : 1) + (!filterUser ? 1 : 0) + 6
                              return (
                                <>
                                  <tr key={`${uid}-${i}`} className='border-t border-gray-50 hover:bg-gray-50/50'>
                                    <td className='px-4 py-2 text-gray-700 whitespace-nowrap'>
                                      {new Date(row.date + 'T00:00:00').toLocaleDateString('de-DE', { weekday: 'short', day: '2-digit', month: '2-digit' })}
                                    </td>
                                    {!filterUser && <td className='px-4 py-2 text-gray-600 text-xs'>{row.user_name}</td>}
                                    {isManager && <td className='px-4 py-2 text-gray-400 text-xs'>{row.department ?? '–'}</td>}
                                    <td className='px-4 py-2 text-gray-700'>{fmt(row.start_time)}</td>
                                    <td className='px-4 py-2 text-gray-700'>{fmt(row.end_time)}</td>
                                    <td className='px-4 py-2 text-right text-gray-600'>{row.break_minutes} min</td>
                                    <td className='px-4 py-2 text-right font-medium text-gray-800'>{row.worked_hours != null ? `${row.worked_hours.toFixed(2)}h` : '–'}</td>
                                    <td className='px-4 py-2'>
                                      <span className={`text-xs px-2 py-0.5 rounded-full font-medium ${STATUS_COLORS[row.status] ?? 'bg-gray-100 text-gray-600'}`}>
                                        {STATUS_DE[row.status] ?? row.status}
                                      </span>
                                    </td>
                                    <td className='px-4 py-2 text-gray-400 text-xs max-w-xs truncate'>{row.note ?? ''}</td>
                                  </tr>
                                  {hasSonder && bd && (
                                    <tr key={`${uid}-${i}-bd`} className='bg-amber-50 border-t border-amber-100'>
                                      <td colSpan={colSpan} className='px-6 py-1.5'>
                                        <div className='flex flex-wrap gap-x-5 gap-y-0.5 text-xs text-amber-800'>
                                          {bd.holiday_name && (
                                            <span className='font-semibold text-red-700'>🗓 {bd.holiday_name}</span>
                                          )}
                                          {bd.normal_hours > 0 && (
                                            <span>Normal: <strong>{bd.normal_hours.toFixed(2)}h</strong></span>
                                          )}
                                          {bd.night_25_hours > 0 && (
                                            <span className='text-blue-700'>Nacht 25%: <strong>{bd.night_25_hours.toFixed(2)}h</strong></span>
                                          )}
                                          {bd.night_40_hours > 0 && (
                                            <span className='text-blue-900 font-semibold'>Nacht 40%: <strong>{bd.night_40_hours.toFixed(2)}h</strong></span>
                                          )}
                                          {bd.sunday_hours > 0 && (
                                            <span className='text-purple-700'>Sonntag 50%: <strong>{bd.sunday_hours.toFixed(2)}h</strong></span>
                                          )}
                                          {bd.holiday_125_hours > 0 && (
                                            <span className='text-red-700'>Feiertag 125%: <strong>{bd.holiday_125_hours.toFixed(2)}h</strong></span>
                                          )}
                                          {bd.holiday_150_hours > 0 && (
                                            <span className='text-red-700 font-semibold'>Feiertag 150%: <strong>{bd.holiday_150_hours.toFixed(2)}h</strong></span>
                                          )}
                                        </div>
                                      </td>
                                    </tr>
                                  )}
                                </>
                              )
                            })}
                          </>
                        )
                      })}
                    </tbody>
                    <tfoot className='bg-gray-50 border-t-2 border-gray-200 font-semibold'>
                      <tr>
                        <td colSpan={isManager ? (filterUser ? 4 : 5) : (filterUser ? 3 : 4)} className='px-4 py-3 text-right text-gray-700'>Gesamt:</td>
                        <td className='px-4 py-3 text-right text-gray-900'>{fmtH(timeReport.total_hours)}</td>
                        <td colSpan={2} />
                      </tr>
                    </tfoot>
                  </table>
                </div>
              )
            })()}

            {/* ── Absence table (grouped by employee) ── */}
            {absenceReport && (() => {
              const groups = groupBy(absenceReport.rows)
              return (
                <div className='overflow-x-auto'>
                  <table className='w-full text-sm'>
                    <thead className='bg-gray-50 text-xs text-gray-500 uppercase tracking-wide'>
                      <tr>
                        {!filterUser && <th className='px-4 py-3 text-left'>Mitarbeiter</th>}
                        {isManager && <th className='px-4 py-3 text-left'>Abteilung</th>}
                        <th className='px-4 py-3 text-left'>Art</th>
                        <th className='px-4 py-3 text-left'>Von</th>
                        <th className='px-4 py-3 text-left'>Bis</th>
                        <th className='px-4 py-3 text-right'>Tage</th>
                        <th className='px-4 py-3 text-left'>Status</th>
                        <th className='px-4 py-3 text-left'>Notiz</th>
                      </tr>
                    </thead>
                    <tbody>
                      {Array.from(groups.entries()).map(([uid, rows], gi) => {
                        const subtotal = rows.reduce((s, r) => s + r.working_days, 0)
                        return (
                          <>
                            {!filterUser && (
                              <tr key={`hdr-${uid}`} className={`${gi > 0 ? 'border-t-2 border-gray-200' : ''} bg-gray-50`}>
                                <td colSpan={isManager ? 8 : 7} className='px-4 py-2'>
                                  <span className='font-semibold text-gray-700 text-sm'>{rows[0].user_name}</span>
                                  {rows[0].department && <span className='ml-2 text-xs text-gray-400'>{rows[0].department}</span>}
                                  <span className='ml-3 text-xs font-medium text-orange-600'>{subtotal} Tage gesamt</span>
                                </td>
                              </tr>
                            )}
                            {rows.map((row, i) => (
                              <tr key={`${uid}-${i}`} className='border-t border-gray-50 hover:bg-gray-50/50'>
                                {!filterUser && <td className='px-4 py-2 text-gray-600 text-xs'>{row.user_name}</td>}
                                {isManager && <td className='px-4 py-2 text-gray-400 text-xs'>{row.department ?? '–'}</td>}
                                <td className='px-4 py-2 font-medium text-gray-800'>{row.absence_type}</td>
                                <td className='px-4 py-2 text-gray-700 whitespace-nowrap'>{fmtDate(row.start_date)}</td>
                                <td className='px-4 py-2 text-gray-700 whitespace-nowrap'>{fmtDate(row.end_date)}</td>
                                <td className='px-4 py-2 text-right font-medium text-gray-800'>{row.working_days}</td>
                                <td className='px-4 py-2'>
                                  <span className={`text-xs px-2 py-0.5 rounded-full font-medium ${STATUS_COLORS[row.status] ?? 'bg-gray-100 text-gray-600'}`}>
                                    {STATUS_DE[row.status] ?? row.status}
                                  </span>
                                </td>
                                <td className='px-4 py-2 text-gray-400 text-xs'>{row.note ?? ''}</td>
                              </tr>
                            ))}
                          </>
                        )
                      })}
                    </tbody>
                    <tfoot className='bg-gray-50 border-t-2 border-gray-200 font-semibold'>
                      <tr>
                        <td colSpan={isManager ? (filterUser ? 4 : 5) : (filterUser ? 3 : 4)} className='px-4 py-3 text-right text-gray-700'>Gesamt Arbeitstage:</td>
                        <td className='px-4 py-3 text-right text-gray-900'>{absenceReport.total_days}</td>
                        <td colSpan={2} />
                      </tr>
                    </tfoot>
                  </table>
                </div>
              )
            })()}

            {/* ── Overtime table ── */}
            {overtimeReport && (
              <div>
                {/* Einfach / Erweitert Toggle */}
                <div className='px-6 py-3 border-b border-gray-100 flex items-center gap-2 no-print'>
                  <span className='text-xs text-gray-500 font-medium'>Ansicht:</span>
                  <div className='flex rounded-lg border border-gray-300 overflow-hidden'>
                    <button onClick={() => setOvertimeView('simple')}
                      className={`px-3 py-1 text-xs font-medium transition-colors ${overtimeView === 'simple' ? 'bg-blue-600 text-white' : 'text-gray-600 hover:bg-gray-50'}`}>
                      Einfach
                    </button>
                    <button onClick={() => setOvertimeView('detail')}
                      className={`px-3 py-1 text-xs font-medium transition-colors ${overtimeView === 'detail' ? 'bg-blue-600 text-white' : 'text-gray-600 hover:bg-gray-50'}`}>
                      Erweitert
                    </button>
                  </div>
                </div>

                {/* Einfache Ansicht */}
                {overtimeView === 'simple' && (
                  <div className='overflow-x-auto'>
                    <table className='w-full text-sm'>
                      <thead className='bg-gray-50 text-xs text-gray-500 uppercase tracking-wide'>
                        <tr>
                          <th className='px-4 py-3 text-left'>Mitarbeiter</th>
                          {isManager && <th className='px-4 py-3 text-left'>Abteilung</th>}
                          <th className='px-4 py-3 text-right'>Soll</th>
                          <th className='px-4 py-3 text-right'>Ist</th>
                          <th className='px-4 py-3 text-right'>Überstunden</th>
                        </tr>
                      </thead>
                      <tbody className='divide-y divide-gray-50'>
                        {overtimeReport.rows.map((row, i) => (
                          <tr key={i} className='hover:bg-gray-50/50'>
                            <td className='px-4 py-3 font-medium text-gray-800'>{row.user_name}</td>
                            {isManager && <td className='px-4 py-3 text-gray-400 text-xs'>{row.department ?? '–'}</td>}
                            <td className='px-4 py-3 text-right text-gray-600'>{fmtH(row.hours_expected)}</td>
                            <td className='px-4 py-3 text-right text-gray-800 font-medium'>{fmtH(row.hours_worked)}</td>
                            <td className='px-4 py-3 text-right'>
                              <span className={`font-bold ${row.overtime_hours > 0 ? 'text-green-600' : row.overtime_hours < 0 ? 'text-red-600' : 'text-gray-500'}`}>
                                {row.overtime_hours > 0 ? '+' : ''}{fmtH(row.overtime_hours)}
                              </span>
                            </td>
                          </tr>
                        ))}
                      </tbody>
                      <tfoot className='bg-gray-50 border-t-2 border-gray-200 font-semibold'>
                        <tr>
                          <td colSpan={isManager ? 2 : 1} className='px-4 py-3'></td>
                          <td className='px-4 py-3 text-right text-gray-700'>{fmtH(overtimeReport.rows.reduce((s,r) => s + r.hours_expected, 0))}</td>
                          <td className='px-4 py-3 text-right text-gray-900'>{fmtH(overtimeReport.rows.reduce((s,r) => s + r.hours_worked, 0))}</td>
                          <td className={`px-4 py-3 text-right font-bold ${overtimeReport.total_overtime >= 0 ? 'text-green-700' : 'text-red-700'}`}>
                            {overtimeReport.total_overtime > 0 ? '+' : ''}{fmtH(overtimeReport.total_overtime)}
                          </td>
                        </tr>
                      </tfoot>
                    </table>
                  </div>
                )}

                {/* Erweiterte Ansicht */}
                {overtimeView === 'detail' && overtimeDetail && (
                  <div className='divide-y divide-gray-100'>
                    {overtimeDetail.rows.map(row => {
                      const userOpen = expandedUsers.has(row.user_id)
                      const toggleUser = () => setExpandedUsers(prev => {
                        const next = new Set(prev)
                        next.has(row.user_id) ? next.delete(row.user_id) : next.add(row.user_id)
                        return next
                      })
                      return (
                        <div key={row.user_id}>
                          {/* Mitarbeiter-Zeile (klickbar) */}
                          <div
                            onClick={toggleUser}
                            className='flex items-center gap-3 px-4 py-3 cursor-pointer hover:bg-gray-50 transition-colors select-none'
                          >
                            <span className={`text-gray-400 transition-transform text-xs ${userOpen ? 'rotate-90' : ''}`}>▶</span>
                            <span className='font-semibold text-gray-800 flex-1'>{row.user_name}</span>
                            {isManager && <span className='text-xs text-gray-400 w-28'>{row.department ?? '–'}</span>}
                            {row.arbzg_violation_days > 0 && (
                              <span className='text-xs bg-red-100 text-red-700 px-2 py-0.5 rounded-full font-medium'>
                                {row.arbzg_violation_days}× ArbZG
                              </span>
                            )}
                            <span className='text-xs text-gray-500 w-20 text-right'>Soll {fmtH(row.hours_expected)}</span>
                            <span className='text-xs text-gray-700 font-medium w-20 text-right'>Ist {fmtH(row.hours_worked)}</span>
                            <span className={`text-sm font-bold w-24 text-right ${row.overtime_hours > 0 ? 'text-green-600' : row.overtime_hours < 0 ? 'text-red-600' : 'text-gray-500'}`}>
                              {row.overtime_hours > 0 ? '+' : ''}{fmtH(row.overtime_hours)}
                            </span>
                          </div>

                          {/* Sonderstunden-Zusammenfassung */}
                          {userOpen && row.special_hours_total && (
                            (() => {
                              const s = row.special_hours_total
                              const hasSonder = s.night_25_hours > 0 || s.night_40_hours > 0 || s.sunday_hours > 0 || s.holiday_125_hours > 0 || s.holiday_150_hours > 0
                              return hasSonder ? (
                                <div className='mx-4 mb-2 bg-amber-50 border border-amber-200 rounded-lg px-4 py-2 flex flex-wrap gap-x-5 gap-y-1 text-xs text-amber-800'>
                                  <span className='font-semibold'>Sonderstunden gesamt:</span>
                                  {s.normal_hours > 0 && <span>Normal: <strong>{s.normal_hours.toFixed(1)}h</strong></span>}
                                  {s.night_25_hours > 0 && <span className='text-blue-700'>Nacht 25%: <strong>{s.night_25_hours.toFixed(1)}h</strong></span>}
                                  {s.night_40_hours > 0 && <span className='text-blue-900 font-semibold'>Nacht 40%: <strong>{s.night_40_hours.toFixed(1)}h</strong></span>}
                                  {s.sunday_hours > 0 && <span className='text-purple-700'>Sonntag 50%: <strong>{s.sunday_hours.toFixed(1)}h</strong></span>}
                                  {s.holiday_125_hours > 0 && <span className='text-red-700'>Feiertag 125%: <strong>{s.holiday_125_hours.toFixed(1)}h</strong></span>}
                                  {s.holiday_150_hours > 0 && <span className='text-red-700 font-semibold'>Feiertag 150%: <strong>{s.holiday_150_hours.toFixed(1)}h</strong></span>}
                                </div>
                              ) : null
                            })()
                          )}

                          {/* Wochen */}
                          {userOpen && row.weeks.map(week => {
                            const weekKey = `${row.user_id}-${week.week_nr}`
                            const weekOpen = expandedWeeks.has(weekKey)
                            const toggleWeek = (e: React.MouseEvent) => {
                              e.stopPropagation()
                              setExpandedWeeks(prev => {
                                const next = new Set(prev)
                                next.has(weekKey) ? next.delete(weekKey) : next.add(weekKey)
                                return next
                              })
                            }
                            return (
                              <div key={week.week_nr} className='ml-8 border-l-2 border-gray-100'>
                                {/* Wochen-Zeile */}
                                <div
                                  onClick={toggleWeek}
                                  className='flex items-center gap-3 px-4 py-2 cursor-pointer hover:bg-blue-50/40 transition-colors select-none'
                                >
                                  <span className={`text-gray-300 transition-transform text-xs ${weekOpen ? 'rotate-90' : ''}`}>▶</span>
                                  <span className='text-xs font-medium text-gray-600 flex-1'>
                                    KW {week.week_nr} &nbsp;·&nbsp;
                                    {new Date(week.week_start + 'T00:00:00').toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit' })} – {new Date(week.week_end + 'T00:00:00').toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit' })}
                                  </span>
                                  <span className='text-xs text-gray-400 w-20 text-right'>Soll {fmtH(week.hours_expected)}</span>
                                  <span className='text-xs text-gray-600 font-medium w-20 text-right'>Ist {fmtH(week.hours_worked)}</span>
                                  <span className={`text-xs font-bold w-24 text-right ${week.overtime > 0 ? 'text-green-600' : week.overtime < 0 ? 'text-red-500' : 'text-gray-400'}`}>
                                    {week.overtime > 0 ? '+' : ''}{fmtH(week.overtime)}
                                  </span>
                                </div>

                                {/* Tages-Tabelle */}
                                {weekOpen && (
                                  <div className='ml-4 mb-2 overflow-x-auto'>
                                    <table className='w-full text-xs'>
                                      <thead className='text-gray-400 uppercase tracking-wide'>
                                        <tr>
                                          <th className='px-3 py-1.5 text-left'>Tag</th>
                                          <th className='px-3 py-1.5 text-left'>Datum</th>
                                          <th className='px-3 py-1.5 text-right'>Beginn</th>
                                          <th className='px-3 py-1.5 text-right'>Ende</th>
                                          <th className='px-3 py-1.5 text-right'>Pause</th>
                                          <th className='px-3 py-1.5 text-right'>Ist</th>
                                          <th className='px-3 py-1.5 text-right'>Soll</th>
                                          <th className='px-3 py-1.5 text-right'>Diff</th>
                                          <th className='px-3 py-1.5 text-left'>Status</th>
                                        </tr>
                                      </thead>
                                      <tbody>
                                        {week.days.map((day, di) => {
                                          const isWeekend = ['Sa', 'So'].includes(day.weekday)
                                          const hasEntries = day.entries.length > 0
                                          const multiEntry = day.entries.length > 1
                                          const dateStr = new Date(day.date + 'T00:00:00').toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit' })
                                          return (
                                            <>
                                              {/* Tageszeile (Summary wenn mehrere Einträge, sonst direkt Daten) */}
                                              {(!hasEntries || multiEntry) && (
                                                <tr key={`day-${di}`} className={`border-t-2 border-gray-200 ${isWeekend ? 'bg-gray-50/50' : 'bg-gray-50/30'}`}>
                                                  <td className={`px-3 py-1.5 font-semibold ${isWeekend ? 'text-gray-400' : 'text-gray-700'}`}>{day.weekday}</td>
                                                  <td className='px-3 py-1.5 text-gray-500'>{dateStr}</td>
                                                  <td className='px-3 py-1.5 text-right text-gray-400 italic text-xs' colSpan={3}>{multiEntry ? `${day.entries.length} Einträge` : '–'}</td>
                                                  <td className='px-3 py-1.5 text-right font-semibold text-gray-700'>{hasEntries ? fmtH(day.hours_worked) : '–'}</td>
                                                  <td className='px-3 py-1.5 text-right text-gray-400'>{day.hours_expected > 0 ? fmtH(day.hours_expected) : '–'}</td>
                                                  <td className={`px-3 py-1.5 text-right font-bold ${day.overtime > 0 ? 'text-green-600' : day.overtime < 0 && day.hours_expected > 0 ? 'text-red-500' : 'text-gray-400'}`}>
                                                    {hasEntries || day.hours_expected > 0 ? (day.overtime > 0 ? '+' : '') + fmtH(day.overtime) : '–'}
                                                  </td>
                                                  <td />
                                                </tr>
                                              )}
                                              {/* Einzelne Einträge */}
                                              {day.entries.map((entry, ei) => {
                                                const hasWarnings = entry.arbzg_warnings.length > 0
                                                const hasSonder = entry.breakdown && (
                                                  entry.breakdown.night_25_hours > 0 || entry.breakdown.night_40_hours > 0 ||
                                                  entry.breakdown.sunday_hours > 0 || entry.breakdown.holiday_125_hours > 0 || entry.breakdown.holiday_150_hours > 0
                                                )
                                                return (
                                                  <>
                                                    <tr key={`${di}-${ei}`} className={`border-t border-gray-50 ${isWeekend ? 'bg-gray-50/40' : ''} ${hasWarnings ? 'bg-red-50/20' : ''} ${multiEntry ? 'pl-4' : ''}`}>
                                                      <td className={`px-3 py-1.5 font-medium ${isWeekend ? 'text-gray-400' : 'text-gray-600'}`}>
                                                        {!multiEntry ? day.weekday : <span className='text-gray-300 pl-2'>↳</span>}
                                                      </td>
                                                      <td className='px-3 py-1.5 text-gray-500'>{!multiEntry ? dateStr : ''}</td>
                                                      <td className='px-3 py-1.5 text-right text-gray-600'>{fmt(entry.start_time)}</td>
                                                      <td className='px-3 py-1.5 text-right text-gray-600'>{fmt(entry.end_time)}</td>
                                                      <td className='px-3 py-1.5 text-right text-gray-500'>{entry.break_minutes > 0 ? `${entry.break_minutes} min` : '–'}</td>
                                                      <td className='px-3 py-1.5 text-right font-medium text-gray-700'>{fmtH(entry.hours_worked)}</td>
                                                      {!multiEntry ? <>
                                                        <td className='px-3 py-1.5 text-right text-gray-400'>{day.hours_expected > 0 ? fmtH(day.hours_expected) : '–'}</td>
                                                        <td className={`px-3 py-1.5 text-right font-semibold ${day.overtime > 0 ? 'text-green-600' : day.overtime < 0 && day.hours_expected > 0 ? 'text-red-500' : 'text-gray-400'}`}>
                                                          {(day.overtime > 0 ? '+' : '') + fmtH(day.overtime)}
                                                        </td>
                                                      </> : <><td /><td /></>}
                                                      <td className='px-3 py-1.5'>
                                                        <span className={`px-1.5 py-0.5 rounded-full text-xs font-medium ${STATUS_COLORS[entry.status] ?? 'bg-gray-100 text-gray-600'}`}>
                                                          {STATUS_DE[entry.status] ?? entry.status}
                                                        </span>
                                                      </td>
                                                    </tr>
                                                    {(hasWarnings || hasSonder) && (
                                                      <tr key={`${di}-${ei}-meta`} className='bg-amber-50/60'>
                                                        <td colSpan={9} className='px-3 py-1 text-xs'>
                                                          {hasWarnings && (
                                                            <div className='flex flex-wrap gap-2 text-red-600 font-medium'>
                                                              {entry.arbzg_warnings.map((w, wi) => <span key={wi}>⚠ {w}</span>)}
                                                            </div>
                                                          )}
                                                          {hasSonder && entry.breakdown && (
                                                            <div className='flex flex-wrap gap-x-4 text-amber-700 mt-0.5'>
                                                              {entry.breakdown.night_25_hours > 0 && <span>Nacht 25%: {entry.breakdown.night_25_hours.toFixed(2)}h</span>}
                                                              {entry.breakdown.night_40_hours > 0 && <span>Nacht 40%: {entry.breakdown.night_40_hours.toFixed(2)}h</span>}
                                                              {entry.breakdown.sunday_hours > 0 && <span>Sonntag: {entry.breakdown.sunday_hours.toFixed(2)}h</span>}
                                                              {entry.breakdown.holiday_125_hours > 0 && <span>Feiertag 125%: {entry.breakdown.holiday_125_hours.toFixed(2)}h</span>}
                                                              {entry.breakdown.holiday_150_hours > 0 && <span>Feiertag 150%: {entry.breakdown.holiday_150_hours.toFixed(2)}h</span>}
                                                              {entry.breakdown.holiday_name && <span className='text-red-600 font-semibold'>{entry.breakdown.holiday_name}</span>}
                                                            </div>
                                                          )}
                                                        </td>
                                                      </tr>
                                                    )}
                                                  </>
                                                )
                                              })}
                                            </>
                                          )
                                        })}
                                      </tbody>
                                    </table>
                                  </div>
                                )}
                              </div>
                            )
                          })}
                        </div>
                      )
                    })}
                    {/* Footer */}
                    <div className='flex items-center px-4 py-3 bg-gray-50 font-semibold text-sm'>
                      <span className='flex-1 text-gray-700'>Gesamt</span>
                      {isManager && <span className='w-28'></span>}
                      <span className='text-gray-600 w-20 text-right'>{fmtH(overtimeDetail.rows.reduce((s,r) => s + r.hours_expected, 0))}</span>
                      <span className='text-gray-900 w-20 text-right'>{fmtH(overtimeDetail.rows.reduce((s,r) => s + r.hours_worked, 0))}</span>
                      <span className={`font-bold w-24 text-right ${overtimeDetail.total_overtime >= 0 ? 'text-green-700' : 'text-red-700'}`}>
                        {overtimeDetail.total_overtime > 0 ? '+' : ''}{fmtH(overtimeDetail.total_overtime)}
                      </span>
                    </div>
                  </div>
                )}
              </div>
            )}

            {/* ── Sondervertretungen Payroll-Report ── */}
            {payrollReport && (
              <div className='overflow-x-auto'>
                {payrollReport.rows.length === 0 ? (
                  <p className='text-center text-gray-400 py-12 text-sm'>
                    Keine Sondervertretungs-Zuweisungen in {payrollReport.month}/{payrollReport.year}.
                  </p>
                ) : (
                  <>
                    <div className='flex justify-end px-4 py-2 no-print'>
                      <button
                        onClick={() => {
                          const rows = payrollReport.rows.flatMap(r =>
                            r.assignments.map(a => [
                              r.user_name, r.personnel_number ?? '',
                              a.label ?? '', a.date_from, a.date_to,
                              a.factor, a.normal_hours, a.factor_hours, a.extra_hours
                            ])
                          )
                          const header = 'Mitarbeiter,Pers-Nr,Bezeichnung,Von,Bis,Faktor,Normal-Std,Faktor-Std,Extra-Std'
                          const csv = [header, ...rows.map(r => r.join(','))].join('\n')
                          const blob = new Blob([csv], { type: 'text/csv' })
                          const a = document.createElement('a'); a.href = URL.createObjectURL(blob)
                          a.download = `sondervertretung_${payrollReport.year}_${String(payrollReport.month).padStart(2,'0')}.csv`; a.click()
                        }}
                        className='px-3 py-1.5 text-xs border border-gray-300 rounded-lg text-gray-600 hover:bg-gray-50'
                      >
                        CSV Export
                      </button>
                    </div>
                    <table className='w-full text-sm'>
                      <thead className='bg-amber-50 text-xs text-amber-700 uppercase tracking-wide'>
                        <tr>
                          <th className='px-4 py-3 text-left'>Mitarbeiter</th>
                          <th className='px-4 py-3 text-left'>Pers.-Nr.</th>
                          <th className='px-4 py-3 text-left'>Bezeichnung</th>
                          <th className='px-4 py-3 text-left'>Zeitraum</th>
                          <th className='px-4 py-3 text-right'>Faktor</th>
                          <th className='px-4 py-3 text-right'>Normal-Std.</th>
                          <th className='px-4 py-3 text-right'>Faktor-Std.</th>
                          <th className='px-4 py-3 text-right font-bold'>Extra-Std.</th>
                        </tr>
                      </thead>
                      <tbody className='divide-y divide-gray-100'>
                        {payrollReport.rows.map(row => (
                          row.assignments.map((a, i) => (
                            <tr key={a.assignment_id} className='hover:bg-amber-50/30'>
                              {i === 0 && (
                                <>
                                  <td className='px-4 py-3 font-medium text-gray-800' rowSpan={row.assignments.length}>
                                    {row.user_name}
                                    {row.assignments.length > 1 && (
                                      <div className='text-xs text-gray-400 mt-0.5'>
                                        Gesamt: +{row.total_extra_hours.toFixed(1)}h
                                      </div>
                                    )}
                                  </td>
                                  <td className='px-4 py-3 text-gray-500 font-mono text-xs' rowSpan={row.assignments.length}>
                                    {row.personnel_number ?? '–'}
                                  </td>
                                </>
                              )}
                              <td className='px-4 py-3 text-gray-700'>{a.label ?? '–'}</td>
                              <td className='px-4 py-3 text-gray-600 text-xs'>{a.date_from} – {a.date_to}</td>
                              <td className='px-4 py-3 text-right font-semibold text-amber-700'>×{Number(a.factor).toFixed(2)}</td>
                              <td className='px-4 py-3 text-right text-gray-600'>{a.normal_hours.toFixed(1)}</td>
                              <td className='px-4 py-3 text-right text-gray-700'>{a.factor_hours.toFixed(1)}</td>
                              <td className='px-4 py-3 text-right font-semibold text-green-700'>+{a.extra_hours.toFixed(1)}</td>
                            </tr>
                          ))
                        ))}
                      </tbody>
                      <tfoot className='bg-gray-50 text-sm font-semibold'>
                        <tr>
                          <td colSpan={5} className='px-4 py-3 text-gray-700'>Gesamt</td>
                          <td className='px-4 py-3 text-right'>
                            {payrollReport.rows.reduce((s, r) => s + r.total_normal_hours, 0).toFixed(1)}
                          </td>
                          <td className='px-4 py-3 text-right'>
                            {payrollReport.rows.reduce((s, r) => s + r.total_factor_hours, 0).toFixed(1)}
                          </td>
                          <td className='px-4 py-3 text-right text-green-700'>
                            +{payrollReport.rows.reduce((s, r) => s + r.total_extra_hours, 0).toFixed(1)}
                          </td>
                        </tr>
                      </tfoot>
                    </table>
                  </>
                )}
                <p className='text-xs text-gray-400 px-4 py-3 border-t border-gray-100'>
                  Sondervertretungs-Faktor: Stunden × Faktor (z.B. ×1,5 für Schichtleiter-Vertretung). Extra-Stunden = Differenz zur Normarbeitszeit.
                </p>
              </div>
            )}

            {/* ── Sick stats table ── */}
            {sickStats && (
              <div className='overflow-x-auto'>
                {sickStats.length === 0 ? (
                  <p className='text-center text-gray-400 py-12 text-sm'>Keine Krankmeldungen im Zeitraum.</p>
                ) : (
                  <table className='w-full text-sm'>
                    <thead className='bg-gray-50 text-xs text-gray-500 uppercase tracking-wide'>
                      <tr>
                        <th className='px-4 py-3 text-left'>Mitarbeiter</th>
                        <th className='px-4 py-3 text-left'>Pers.-Nr.</th>
                        <th className='px-4 py-3 text-right'>Episoden</th>
                        <th className='px-4 py-3 text-right'>Tage</th>
                        <th className='px-4 py-3 text-right'>Bradford</th>
                        <th className='px-4 py-3 text-right'>AU offen</th>
                      </tr>
                    </thead>
                    <tbody className='divide-y divide-gray-100'>
                      {[...sickStats].sort((a, b) => b.bradford_factor - a.bradford_factor).map(r => (
                        <tr key={r.user_id} className='hover:bg-gray-50'>
                          <td className='px-4 py-3 font-medium text-gray-800'>{r.user_name}</td>
                          <td className='px-4 py-3 text-gray-500'>{r.personnel_number ?? '–'}</td>
                          <td className='px-4 py-3 text-right text-gray-700'>{r.episodes}</td>
                          <td className='px-4 py-3 text-right text-gray-700'>{r.total_days.toFixed(1)}</td>
                          <td className={`px-4 py-3 text-right font-semibold ${r.bradford_factor >= 200 ? 'text-red-600' : r.bradford_factor >= 50 ? 'text-orange-600' : 'text-gray-700'}`}>
                            {r.bradford_factor.toFixed(1)}
                          </td>
                          <td className={`px-4 py-3 text-right ${r.certificates_overdue > 0 ? 'text-red-600 font-bold' : 'text-gray-400'}`}>
                            {r.certificates_overdue}
                          </td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                )}
                <p className='text-xs text-gray-400 px-4 py-3 border-t border-gray-100'>
                  Bradford-Faktor: Episoden² × Tage. Stufen: ab 50 = Aufmerksamkeit, ab 200 = Handlungsbedarf.
                </p>
              </div>
            )}

          </div>
        )}
      </div>
    </Layout>
  )
}
