import { useState } from 'react'
import { useSearchParams } from 'react-router-dom'
import { api } from '../api/client'
import { Spinner } from '../components/Spinner'
import { Layout } from '../components/Layout'
import type { AbsenceOut, AbsenceSpan, VacationBalanceOut } from '../types/absence'
import {
  MONTHS, MONTHS_SHORT, STATUS_LABELS, STATUS_COLORS, MANAGER_ROLES,
} from '../utils/calendar'
import { useAbsences } from '../hooks/useAbsences'
import { PayoutRequestCard } from '../components/PayoutRequestCard'
import { usePlanerView } from '../hooks/usePlanerView'
import {
  BalanceEditModal,
  EditAbsenceModal,
  CreateAbsenceModal,
  QuickSickModal,
} from '../components/absences/AbsenceModals'
import { AbsenceCommentsModal } from '../components/absences/AbsenceCommentsModal'

// ── Component ─────────────────────────────────────────────────────────────────
export function AbsencesPage() {
  const [searchParams, setSearchParams] = useSearchParams()
  const [showCreate, setShowCreate] = useState(false)
  const [showQuickSick, setShowQuickSick] = useState(false)
  const todayIso = new Date().toISOString().slice(0, 10)
  const [quickSickForm, setQuickSickForm] = useState({ start_date: todayIso, end_date: todayIso })
  const [quickSubmitting, setQuickSubmitting] = useState(false)
  const [quickError, setQuickError] = useState('')
  const [showReject, setShowReject] = useState<string | null>(null)
  const [rejectReason, setRejectReason] = useState('')
  const [showCancelReq, setShowCancelReq] = useState<string | null>(null)
  const [cancelReason, setCancelReason] = useState('')
  const [commentsFor, setCommentsFor] = useState<AbsenceOut | null>(null)
  const [statusFilter, setStatusFilter] = useState<string>(searchParams.get('status') ?? '')
  const [submitting, setSubmitting] = useState(false)
  const [showBalanceEdit, setShowBalanceEdit] = useState(false)
  const [balanceForm, setBalanceForm] = useState({ entitled_days: 0, special_days: 0, carried_over: 0 })
  const [balanceSaving, setBalanceSaving] = useState(false)
  const [editAbsence, setEditAbsence] = useState<AbsenceOut | null>(null)
  const [editForm, setEditForm] = useState({
    type_id: '', start_date: '', end_date: '',
    half_day_start: false, half_day_end: false,
    note: '', correction_note: '',
  })
  const [form, setForm] = useState({
    type_id: '', start_date: '', end_date: '',
    half_day_start: false, half_day_end: false,
    note: '', for_user_id: '', substitute_id: '',
  })
  const [fzaMode, setFzaMode] = useState<'days' | 'hours'>('days')
  const [fzaHours, setFzaHours] = useState<number>(4)

  const year = new Date().getFullYear()

  const {
    user, types, absences, total, balance, overtimeBalance,
    loading, error, setError, colleagues, colleagueMap,
    createAbsence, approve, reject, saveEdit, cancel, requestCancellation,
    loadColleaguesIfNeeded, typeName, typeColor, updateBalance, load,
  } = useAbsences(year, statusFilter)

  const isSickType = (typeId: string) => types.find(t => t.id === typeId)?.category === 'sick'
  // HR/COMPANY_ADMIN/SUPER_ADMIN dürfen Attest-Eingang markieren – MANAGER nicht.
  const canMarkCertificate = !!user && ['HR', 'COMPANY_ADMIN', 'SUPER_ADMIN'].includes(user.role)
  const todayDate = todayIso

  const handleQuickSick = async () => {
    setQuickSubmitting(true)
    setQuickError('')
    try {
      await api.post('/absences/quick-sick', quickSickForm)
      setShowQuickSick(false)
      setQuickSickForm({ start_date: todayIso, end_date: todayIso })
      await load()
    } catch (e: any) {
      setQuickError(e?.message ?? 'Krankmeldung fehlgeschlagen.')
    } finally {
      setQuickSubmitting(false)
    }
  }

  const markCertificate = async (absenceId: string) => {
    try {
      await api.patch(`/absences/${absenceId}/certificate`, {})
      await load()
    } catch (e: any) {
      setError(e?.message ?? 'Attest konnte nicht markiert werden.')
    }
  }

  const {
    viewMode, setViewMode, planMonth, setPlanMonth,
    colleagueBalances, showYearGrid, setShowYearGrid,
  } = usePlanerView(user, colleagues, year)

  const isManager = user ? MANAGER_ROLES.includes(user.role) : false

  const openEdit = (a: AbsenceOut) => {
    setEditAbsence(a)
    setEditForm({
      type_id: a.type_id,
      start_date: a.start_date,
      end_date: a.end_date,
      half_day_start: a.half_day_start,
      half_day_end: a.half_day_end,
      note: a.note ?? '',
      correction_note: '',
    })
    setError('')
  }

  const openCreate = async () => {
    setShowCreate(true)
    setError('')
    setForm({ type_id: '', start_date: '', end_date: '', half_day_start: false, half_day_end: false, note: '', for_user_id: '', substitute_id: '' })
    setFzaMode('days')
    setFzaHours(4)
    if (isManager) await loadColleaguesIfNeeded()
  }

  const handleReject = async (id: string) => {
    await reject(id, rejectReason, () => { setShowReject(null); setRejectReason('') })
  }

  const handleSaveEdit = async () => {
    if (!editAbsence) return
    await saveEdit(editAbsence, editForm, isManager, () => setEditAbsence(null), setSubmitting)
  }

  const isFzaType = (typeId: string) => {
    const t = types.find(t => t.id === typeId)
    if (!t) return false
    const lower = t.name?.toLowerCase() ?? ''
    return lower.includes('fza') || lower.includes('freizeitausgleich')
  }

  const handleCreate = async () => {
    const useFzaHours = isFzaType(form.type_id) && fzaMode === 'hours'
    await createAbsence(form, () => {
      setShowCreate(false)
      setForm({ type_id: '', start_date: '', end_date: '', half_day_start: false, half_day_end: false, note: '', for_user_id: '', substitute_id: '' })
      setFzaMode('days')
      setFzaHours(4)
    }, setSubmitting, useFzaHours ? fzaHours : undefined)
  }

  const handleSaveBalance = async () => {
    if (!balance) return
    setBalanceSaving(true)
    try {
      const updated = await api.patch<VacationBalanceOut>(`/absences/balance/${balance.user_id}?year=${year}`, balanceForm)
      updateBalance(updated)
      setShowBalanceEdit(false)
    } catch { /* ignore */ }
    finally { setBalanceSaving(false) }
  }

  // Build absence spans from local data
  const absenceSpans: AbsenceSpan[] = absences.map(a => ({
    id: a.id,
    userId: a.user_id,
    userName: colleagueMap[a.user_id] ?? (user?.id === a.user_id ? `${user.first_name} ${user.last_name}` : a.user_id),
    typeName: typeName(a.type_id),
    color: typeColor(a.type_id),
    start: new Date(a.start_date),
    end: new Date(a.end_date),
    status: a.status,
    isHalfStart: a.half_day_start,
    isHalfEnd: a.half_day_end,
  }))

  const absencesInMonth = (month: number) => {
    const first = new Date(year, month, 1)
    const last = new Date(year, month + 1, 0)
    return absences.filter(a => new Date(a.start_date) <= last && new Date(a.end_date) >= first)
  }

  const buildAbsenceListHtml = () => {
    const sorted = [...absences]
      .filter(a => a.status !== 'cancelled')
      .sort((a, b) => a.start_date.localeCompare(b.start_date))

    const userName = user ? `${user.first_name} ${user.last_name}` : ''
    const managerHeader = isManager ? '<th>Mitarbeiter</th>' : ''

    const balanceRow = balance ? `
      <div style="display:flex;gap:24px;margin-bottom:20px;padding:12px 16px;background:#f9fafb;border-radius:8px;font-size:13px">
        <div><span style="color:#6b7280">Grundurlaub:</span> <strong>${balance.entitled_days} Tage</strong></div>
        ${balance.special_days > 0 ? `<div><span style="color:#6b7280">Sondertage:</span> <strong>+${balance.special_days} Tage</strong></div>` : ''}
        ${balance.carried_over > 0 ? `<div><span style="color:#6b7280">Resturlaub ${year - 1}:</span> <strong>+${balance.carried_over} Tage</strong></div>` : ''}
        <div><span style="color:#6b7280">Gesamt:</span> <strong>${balance.total_days} Tage</strong></div>
        <div><span style="color:#6b7280">Verbleibend:</span> <strong style="color:${balance.remaining_days > 5 ? '#16a34a' : balance.remaining_days > 0 ? '#d97706' : '#dc2626'}">${balance.remaining_days} Tage</strong></div>
      </div>` : ''

    const rows = sorted.map(a => {
      const name = isManager ? `<td>${colleagueMap[a.user_id] ?? '–'}</td>` : ''
      const statusColor = a.status === 'approved' ? '#16a34a' : a.status === 'pending' ? '#d97706' : '#dc2626'
      return `<tr>
        ${name}
        <td><span style="display:inline-block;width:10px;height:10px;border-radius:50%;background:${typeColor(a.type_id)};margin-right:6px;vertical-align:middle"></span>${typeName(a.type_id)}</td>
        <td>${new Date(a.start_date).toLocaleDateString('de-DE')}</td>
        <td>${new Date(a.end_date).toLocaleDateString('de-DE')}</td>
        <td style="text-align:right">${a.working_days}</td>
        <td style="color:${statusColor}">${STATUS_LABELS[a.status] ?? a.status}</td>
        ${a.note ? `<td style="color:#6b7280;font-size:12px">${a.note}</td>` : '<td></td>'}
      </tr>`
    }).join('')

    const html = `<!DOCTYPE html><html><head>
      <meta charset="UTF-8">
      <title>Urlaubsliste ${userName} ${year}</title>
      <style>
        body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; padding: 28px; color: #111; }
        h1 { font-size: 20px; margin: 0 0 2px; }
        p.meta { font-size: 12px; color: #888; margin: 0 0 16px; }
        table { width: 100%; border-collapse: collapse; font-size: 13px; }
        th { background: #f3f4f6; padding: 8px 12px; text-align: left; font-weight: 600; border-top: 2px solid #e5e7eb; border-bottom: 2px solid #e5e7eb; }
        td { padding: 7px 12px; border-bottom: 1px solid #f0f0f0; vertical-align: middle; }
        @media print { body { padding: 10px; } }
      </style>
    </head><body>
      <h1>Urlaubsliste ${year}${!isManager ? ` – ${userName}` : ''}</h1>
      <p class="meta">Stand: ${new Date().toLocaleDateString('de-DE', { day: '2-digit', month: 'long', year: 'numeric' })}</p>
      ${!isManager ? balanceRow : ''}
      ${sorted.length === 0
        ? '<p style="color:#9ca3af;text-align:center;padding:32px">Keine Einträge.</p>'
        : `<table>
            <thead><tr>${managerHeader}<th>Abwesenheitsart</th><th>Von</th><th>Bis</th><th style="text-align:right">Tage</th><th>Status</th><th>Notiz</th></tr></thead>
            <tbody>${rows}</tbody>
           </table>`}
    </body></html>`

    return html
  }

  const buildMonthHtml = () => {
    const list = absencesInMonth(planMonth)
      .filter(a => a.status !== 'cancelled' && a.status !== 'rejected')
      .sort((a, b) => a.start_date.localeCompare(b.start_date))
    const monthName = MONTHS[planMonth]
    const managerHeader = isManager ? '<th>Mitarbeiter</th>' : ''
    const remainingHeader = isManager ? '<th style="text-align:right">Resturlaub</th>' : ''
    const rows = list.map(a => {
      const name = isManager ? `<td>${colleagueMap[a.user_id] ?? '–'}</td>` : ''
      const bal = colleagueBalances[a.user_id]
      const remaining = isManager
        ? `<td style="text-align:right;${bal && bal.remaining_days <= 0 ? 'color:#dc2626;font-weight:700' : ''}">${bal != null ? bal.remaining_days + ' Tage' : '–'}</td>`
        : ''
      const statusColor = a.status === 'approved' ? '#16a34a' : '#d97706'
      return `<tr>${name}<td><span style="display:inline-block;width:10px;height:10px;border-radius:50%;background:${typeColor(a.type_id)};margin-right:6px;vertical-align:middle"></span>${typeName(a.type_id)}</td><td>${new Date(a.start_date).toLocaleDateString('de-DE')}</td><td>${new Date(a.end_date).toLocaleDateString('de-DE')}</td><td style="text-align:right">${a.working_days}</td><td style="color:${statusColor}">${STATUS_LABELS[a.status] ?? a.status}</td>${remaining}</tr>`
    }).join('')
    return `<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Urlaubsplaner ${monthName} ${year}</title><style>body{font-family:-apple-system,sans-serif;padding:28px;color:#111}h1{font-size:22px;margin:0 0 4px}p.meta{font-size:12px;color:#888;margin:0 0 20px}table{width:100%;border-collapse:collapse;font-size:13px}th{background:#f3f4f6;padding:8px 12px;text-align:left;font-weight:600;border-top:2px solid #e5e7eb;border-bottom:2px solid #e5e7eb}td{padding:7px 12px;border-bottom:1px solid #f0f0f0;vertical-align:middle}@media print{body{padding:10px}}</style></head><body><h1>Urlaubsplaner – ${monthName} ${year}</h1><p class="meta">Stand: ${new Date().toLocaleDateString('de-DE', { day: '2-digit', month: 'long', year: 'numeric' })}</p>${list.length === 0 ? '<p style="color:#9ca3af;text-align:center;padding:32px">Keine Abwesenheiten in diesem Monat.</p>' : `<table><thead><tr>${managerHeader}<th>Abwesenheitsart</th><th>Von</th><th>Bis</th><th style="text-align:right">Tage</th><th>Status</th>${remainingHeader}</tr></thead><tbody>${rows}</tbody></table>`}</body></html>`
  }

  const openPdf = (html: string) => {
    const w = window.open('', '_blank', 'width=960,height=720')
    if (w) { w.document.write(html); w.document.close() }
  }

  const openPrint = (html: string) => {
    const w = window.open('', '_blank', 'width=960,height=720')
    if (w) { w.document.write(html); w.document.close(); setTimeout(() => { w.focus(); w.print() }, 250) }
  }

  if (loading) return (
    <Layout userRole='' userName=''>
      <div className='flex justify-center py-20'><Spinner /></div>
    </Layout>
  )
  if (!user) return null

  const today = new Date()
  const todayStr = today.toDateString()

  return (
    <Layout userRole={user.role} userName={`${user.first_name} ${user.last_name}`}>
      <div className='space-y-6'>

        {/* Header */}
        <div className='flex items-center justify-between'>
          <h1 className='text-2xl font-bold text-gray-900'>Abwesenheiten</h1>
          <div className='flex gap-2'>
            <button
              onClick={() => { setQuickError(''); setShowQuickSick(true) }}
              className='px-4 py-2 bg-orange-600 text-white rounded-lg text-sm font-medium hover:bg-orange-700 transition-colors'
            >
              🤒 Krank melden
            </button>
            <button onClick={openCreate} className='px-4 py-2 bg-blue-600 text-white rounded-lg text-sm font-medium hover:bg-blue-700 transition-colors'>
              + Antrag stellen
            </button>
          </div>
        </div>

        {/* Tabs */}
        <div className='flex items-center gap-3 flex-wrap'>
          <div className='flex gap-1 bg-gray-100 rounded-lg p-1 w-fit'>
            {(['liste', 'planer'] as const).map(v => (
              <button key={v} onClick={() => setViewMode(v)}
                className={`px-4 py-1.5 rounded-md text-sm font-medium transition-colors ${viewMode === v ? 'bg-white text-gray-900 shadow-sm' : 'text-gray-500 hover:text-gray-700'}`}>
                {v === 'liste' ? 'Liste' : 'Jahresplaner'}
              </button>
            ))}
          </div>
          {viewMode === 'planer' && isManager && (
            <button
              onClick={() => setShowYearGrid(v => !v)}
              className={`flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-sm border transition-colors ${
                showYearGrid
                  ? 'bg-blue-50 border-blue-200 text-blue-700 hover:bg-blue-100'
                  : 'bg-white border-gray-200 text-gray-500 hover:bg-gray-50'
              }`}
              title={showYearGrid ? 'Jahresübersicht ausblenden' : 'Jahresübersicht einblenden'}
            >
              <svg className='w-4 h-4' fill='none' viewBox='0 0 24 24' stroke='currentColor'>
                {showYearGrid
                  ? <path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M3 10h18M3 14h18M10 3v18M14 3v18' />
                  : <path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M4 6h16M4 12h16M4 18h16' />
                }
              </svg>
              {showYearGrid ? 'Jahresübersicht' : 'Jahresübersicht'}
            </button>
          )}
        </div>

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

        {/* ─── LISTE ─────────────────────────────────────────────────────────── */}
        {viewMode === 'liste' && (<>
          {balance && (
            <div className='bg-white rounded-xl shadow-sm border border-gray-200 p-5'>
              <div className='flex items-center justify-between mb-4'>
                <h2 className='text-sm font-semibold text-gray-500 uppercase tracking-wide'>Urlaubskonto {year}</h2>
                {isManager && (
                  <button onClick={() => { setBalanceForm({ entitled_days: balance.entitled_days, special_days: balance.special_days, carried_over: balance.carried_over }); setShowBalanceEdit(true) }}
                    className='text-xs text-blue-600 hover:underline'>Bearbeiten</button>
                )}
              </div>
              <div className='mb-4 p-3 bg-gray-50 rounded-lg space-y-1.5'>
                <div className='flex justify-between text-sm'><span className='text-gray-500'>Grundurlaub</span><span className='font-medium text-gray-800'>{balance.entitled_days} Tage</span></div>
                {balance.special_days > 0 && <div className='flex justify-between text-sm'><span className='text-gray-500'>Sondertage</span><span className='font-medium text-blue-700'>+{balance.special_days} Tage</span></div>}
                {balance.carried_over > 0 && (
                  <div className='space-y-0.5'>
                    <div className='flex justify-between text-sm'>
                      <span className={balance.carried_over_expired ? 'text-red-500 line-through' : 'text-gray-500'}>
                        Resturlaub {year - 1}
                      </span>
                      <span className={`font-medium ${balance.carried_over_expired ? 'text-red-400 line-through' : 'text-purple-700'}`}>
                        +{balance.carried_over} Tage
                      </span>
                    </div>
                    {balance.carried_over_expires_at && (
                      <div className={`text-xs px-2 py-0.5 rounded ${balance.carried_over_expired ? 'bg-red-50 text-red-600' : 'bg-amber-50 text-amber-700'}`}>
                        {balance.carried_over_expired
                          ? `Verfallen am ${new Date(balance.carried_over_expires_at).toLocaleDateString('de-DE')}`
                          : `Verfällt am ${new Date(balance.carried_over_expires_at).toLocaleDateString('de-DE')}`}
                      </div>
                    )}
                  </div>
                )}
                <div className='flex justify-between text-sm border-t border-gray-200 pt-1.5'><span className='font-medium text-gray-700'>Gesamt</span><span className='font-bold text-gray-900'>{balance.total_days} Tage</span></div>
              </div>
              <div className='mb-4'>
                <div className='flex justify-between text-xs text-gray-500 mb-1'>
                  <span>{balance.used_days} genommen{balance.pending_days > 0 ? ` · ${balance.pending_days} beantragt` : ''}</span>
                  <span>{balance.total_days} gesamt</span>
                </div>
                <div className='h-2 bg-gray-100 rounded-full overflow-hidden flex'>
                  <div className='h-full bg-green-500' style={{ width: `${Math.min(100, balance.used_days / balance.total_days * 100)}%` }} />
                  {balance.pending_days > 0 && <div className='h-full bg-yellow-400' style={{ width: `${Math.min(100 - balance.used_days / balance.total_days * 100, balance.pending_days / balance.total_days * 100)}%` }} />}
                </div>
              </div>
              <div className='grid grid-cols-3 gap-3'>
                <div><p className='text-xs text-gray-500'>Genommen</p><p className='text-xl font-bold text-gray-800'>{balance.used_days}</p></div>
                {balance.pending_days > 0 && <div><p className='text-xs text-gray-500'>Beantragt</p><p className='text-xl font-bold text-yellow-600'>{balance.pending_days}</p></div>}
                <div>
                  <p className='text-xs text-gray-500'>Verfügbar</p>
                  <p className={`text-xl font-bold ${balance.available_days > 5 ? 'text-green-600' : balance.available_days > 0 ? 'text-yellow-600' : 'text-red-600'}`}>{balance.available_days}</p>
                  {balance.carried_over_expired && balance.carried_over > 0 && (
                    <p className='text-[11px] text-red-500'>Resturlaub verfallen</p>
                  )}
                </div>
              </div>
            </div>
          )}

          {overtimeBalance !== null && overtimeBalance.total_hours > 0 && (
            <div className='bg-white rounded-xl shadow-sm border border-gray-200 p-5'>
              <h2 className='text-sm font-semibold text-gray-500 uppercase tracking-wide mb-3'>Überstunden-Konto</h2>
              <div className='grid grid-cols-3 gap-4'>
                <div><p className='text-xs text-gray-500'>Angesammelt</p><p className='text-2xl font-bold text-gray-800'>{overtimeBalance.total_hours.toFixed(1)} <span className='text-sm font-normal text-gray-500'>h</span></p></div>
                <div><p className='text-xs text-gray-500'>Genommen</p><p className='text-2xl font-bold text-gray-800'>{overtimeBalance.taken_hours.toFixed(1)} <span className='text-sm font-normal text-gray-500'>h</span></p></div>
                <div><p className='text-xs text-gray-500'>Verfügbar</p><p className={`text-2xl font-bold ${overtimeBalance.available_hours > 0 ? 'text-green-600' : 'text-red-600'}`}>{overtimeBalance.available_hours.toFixed(1)} <span className='text-sm font-normal text-gray-500'>h</span></p></div>
              </div>
            </div>
          )}

          <PayoutRequestCard availableHours={overtimeBalance?.available_hours ?? 0} />

          <div className='flex gap-2 flex-wrap'>
            {[['', 'Alle'], ['pending', 'Ausstehend'], ['approved', 'Genehmigt'], ['rejected', 'Abgelehnt']].map(([val, label]) => (
              <button key={val} onClick={() => { setStatusFilter(val); if (val) setSearchParams({ status: val }); else setSearchParams({}) }}
                className={`px-3 py-1.5 rounded-lg text-sm font-medium transition-colors ${statusFilter === val ? 'bg-blue-600 text-white' : 'bg-white border border-gray-200 text-gray-600 hover:bg-gray-50'}`}>
                {label}
              </button>
            ))}
          </div>

          <div className='bg-white rounded-xl shadow-sm border border-gray-200'>
            <div className='px-6 py-4 border-b border-gray-100 flex items-center justify-between'>
              <h2 className='text-lg font-semibold text-gray-800'>Anträge {year}</h2>
              <div className='flex items-center gap-3'>
                <span className='text-sm text-gray-400'>{total} gesamt</span>
                <button onClick={() => openPrint(buildAbsenceListHtml())}
                  className='flex items-center gap-1.5 px-3 py-1.5 border border-gray-200 text-gray-600 rounded-lg text-xs hover:bg-gray-50 transition-colors'
                  title='Drucken'>
                  <svg className='w-3.5 h-3.5' fill='none' viewBox='0 0 24 24' stroke='currentColor'>
                    <path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z' />
                  </svg>
                  Drucken
                </button>
                <button onClick={() => openPdf(buildAbsenceListHtml())}
                  className='flex items-center gap-1.5 px-3 py-1.5 border border-gray-200 text-gray-600 rounded-lg text-xs hover:bg-gray-50 transition-colors'
                  title='Als PDF speichern'>
                  <svg className='w-3.5 h-3.5' fill='none' viewBox='0 0 24 24' stroke='currentColor'>
                    <path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z' />
                  </svg>
                  PDF
                </button>
              </div>
            </div>
            <div className='divide-y divide-gray-50'>
              {absences.length === 0 ? (
                <p className='text-center text-gray-400 py-8 text-sm'>Keine Einträge</p>
              ) : absences.map(a => (
                <div key={a.id} className='px-6 py-4'>
                  <div className='flex items-start justify-between gap-4'>
                    <div className='flex items-start gap-3'>
                      <div className='w-3 h-3 rounded-full mt-1.5 flex-shrink-0' style={{ backgroundColor: typeColor(a.type_id) }} />
                      <div>
                        <p className='text-sm font-medium text-gray-800'>{typeName(a.type_id)}</p>
                        {isManager && a.user_id !== user?.id && <p className='text-xs font-medium text-blue-600 mb-0.5'>{colleagueMap[a.user_id] ?? a.user_id}</p>}
                        <p className='text-xs text-gray-500'>
                          {new Date(a.start_date).toLocaleDateString('de-DE')} – {new Date(a.end_date).toLocaleDateString('de-DE')}
                          {' · '}{a.working_days} Arbeitstag{a.working_days !== 1 ? 'e' : ''}
                        </p>
                        {a.note && <p className='text-xs text-gray-400 mt-0.5'>{a.note}</p>}
                        {a.substitute_id && <p className='text-xs text-gray-500 mt-0.5'>🔁 Vertretung: {colleagueMap[a.substitute_id] ?? '—'}</p>}
                        {a.correction_note && <p className='text-xs text-orange-500 mt-0.5'>✏️ {a.correction_note}</p>}
                        {a.rejection_reason && <p className='text-xs text-red-500 mt-0.5'>Abgelehnt: {a.rejection_reason}</p>}
                      </div>
                    </div>
                    <div className='flex items-center gap-2 flex-shrink-0'>
                      {isSickType(a.type_id) && a.certificate_received_at && (
                        <span className='text-xs px-2 py-0.5 rounded-full font-medium bg-green-100 text-green-700' title={`Eingegangen am ${new Date(a.certificate_received_at).toLocaleDateString('de-DE')}`}>
                          Attest ✓
                        </span>
                      )}
                      {isSickType(a.type_id) && !a.certificate_received_at && a.certificate_required_by && a.certificate_required_by < todayDate && (
                        <span className='text-xs px-2 py-0.5 rounded-full font-medium bg-orange-100 text-orange-700' title={`Fällig seit ${new Date(a.certificate_required_by).toLocaleDateString('de-DE')}`}>
                          AU überfällig
                        </span>
                      )}
                      <span className={`text-xs px-2 py-0.5 rounded-full font-medium ${STATUS_COLORS[a.status] ?? 'bg-gray-100 text-gray-500'}`}>{STATUS_LABELS[a.status] ?? a.status}</span>
                      {canMarkCertificate && isSickType(a.type_id) && !a.certificate_received_at && (
                        <button
                          onClick={() => markCertificate(a.id)}
                          className='text-xs px-2 py-1 border border-green-300 text-green-700 rounded hover:bg-green-50'
                          title='Attest als eingegangen markieren'
                        >
                          Attest erhalten
                        </button>
                      )}
                      {(a.status === 'pending' || a.status === 'approved') && (isManager || a.user_id === user.id) && (
                        <button onClick={() => openEdit(a)} className={`text-xs px-2 py-1 border rounded ${a.status === 'approved' && !isManager ? 'border-orange-300 text-orange-600 hover:bg-orange-50' : 'border-blue-300 text-blue-600 hover:bg-blue-50'}`}>✏️</button>
                      )}
                      <button onClick={() => setCommentsFor(a)} title='Kommentare' className='text-xs px-2 py-1 border border-gray-300 text-gray-600 rounded hover:bg-gray-50'>💬</button>
                      {isManager && a.status === 'pending' && (<>
                        <button onClick={() => approve(a.id)} className='text-xs px-2 py-1 bg-green-600 text-white rounded hover:bg-green-700'>Genehmigen</button>
                        <button onClick={() => { setShowReject(a.id); setRejectReason('') }} className='text-xs px-2 py-1 bg-red-600 text-white rounded hover:bg-red-700'>Ablehnen</button>
                      </>)}
                      {a.status === 'first_approved'
                        && ['HR', 'COMPANY_ADMIN', 'SUPER_ADMIN'].includes(user.role)
                        && a.first_approved_by !== user.id && (<>
                        <button onClick={() => approve(a.id)} className='text-xs px-2 py-1 bg-green-600 text-white rounded hover:bg-green-700' title='Finale Genehmigung'>Endgültig genehmigen</button>
                        <button onClick={() => { setShowReject(a.id); setRejectReason('') }} className='text-xs px-2 py-1 bg-red-600 text-white rounded hover:bg-red-700'>Ablehnen</button>
                      </>)}
                      {isManager && a.status === 'cancellation_requested' && (<>
                        <button onClick={() => approve(a.id)} className='text-xs px-2 py-1 bg-green-600 text-white rounded hover:bg-green-700' title='Stornierung genehmigen'>Storno ✓</button>
                        <button onClick={() => { setShowReject(a.id); setRejectReason('') }} className='text-xs px-2 py-1 bg-red-600 text-white rounded hover:bg-red-700' title='Stornierung ablehnen'>Storno ✗</button>
                      </>)}
                      {!isManager && a.status === 'pending' && a.user_id === user.id && (
                        <button onClick={() => cancel(a.id)} className='text-xs px-2 py-1 border border-gray-300 text-gray-600 rounded hover:bg-gray-50'>Stornieren</button>
                      )}
                      {!isManager && a.status === 'approved' && a.user_id === user.id && (
                        <button onClick={() => { setShowCancelReq(a.id); setCancelReason('') }} className='text-xs px-2 py-1 border border-orange-300 text-orange-600 rounded hover:bg-orange-50'>Storno beantragen</button>
                      )}
                    </div>
                  </div>
                  {showReject === a.id && (
                    <div className='mt-3 flex gap-2'>
                      <input type='text' placeholder='Begründung (Pflicht)' value={rejectReason} onChange={e => setRejectReason(e.target.value)}
                        className='flex-1 border border-gray-300 rounded px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-red-400' />
                      <button onClick={() => handleReject(a.id)} disabled={!rejectReason.trim()} className='px-3 py-1.5 bg-red-600 text-white text-sm rounded disabled:opacity-50'>Senden</button>
                      <button onClick={() => setShowReject(null)} className='px-3 py-1.5 border border-gray-300 text-gray-600 text-sm rounded'>Abbrechen</button>
                    </div>
                  )}
                  {showCancelReq === a.id && (
                    <div className='mt-3 flex gap-2'>
                      <input type='text' placeholder='Grund der Stornierung (optional)' value={cancelReason} onChange={e => setCancelReason(e.target.value)}
                        className='flex-1 border border-gray-300 rounded px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-orange-400' />
                      <button onClick={() => { requestCancellation(a.id, cancelReason); setShowCancelReq(null) }} className='px-3 py-1.5 bg-orange-600 text-white text-sm rounded'>Storno beantragen</button>
                      <button onClick={() => setShowCancelReq(null)} className='px-3 py-1.5 border border-gray-300 text-gray-600 text-sm rounded'>Abbrechen</button>
                    </div>
                  )}
                </div>
              ))}
            </div>
          </div>
        </>)}

        {/* ─── JAHRESPLANER ──────────────────────────────────────────────────── */}
        {viewMode === 'planer' && (
          <div className='space-y-4'>

            {/* Jahresleiste */}
            {(showYearGrid || !isManager) && (() => {
              const allYearSpans = absenceSpans.filter(s => s.status !== 'cancelled' && s.status !== 'rejected')
              const yearUserIds = isManager
                ? [...new Set([user!.id, ...allYearSpans.map(s => s.userId)])]
                : [user!.id]
              const sortedUserIds = [...yearUserIds].sort((a, b) => {
                if (a === user!.id) return -1
                if (b === user!.id) return 1
                return (colleagueMap[a] ?? '').localeCompare(colleagueMap[b] ?? '', 'de')
              })

              return (
                <div className='bg-white rounded-xl shadow-sm border border-gray-200 p-4'>
                  <p className='text-xs font-semibold text-gray-400 uppercase tracking-wide mb-3'>Jahresübersicht {year}</p>
                  <div className='overflow-x-auto'>
                    <table className='w-full text-sm border-collapse'>
                      <thead>
                        <tr>
                          <th className='sticky left-0 bg-white z-10 w-28 min-w-28 text-left py-2 px-3 text-xs font-semibold text-gray-400 border-b border-gray-100'>
                            {year}
                          </th>
                          {MONTHS_SHORT.map((m, idx) => (
                            <th key={idx}
                              onClick={() => setPlanMonth(idx)}
                              className={`cursor-pointer py-2 px-1 text-center text-xs font-semibold border-b border-gray-100 min-w-[52px] transition-colors select-none
                                ${idx === planMonth ? 'text-blue-600 bg-blue-50' : 'text-gray-500 hover:text-gray-700 hover:bg-gray-50'}
                                ${idx === today.getMonth() && idx !== planMonth ? 'underline decoration-dotted decoration-blue-400' : ''}
                              `}>
                              {m}
                            </th>
                          ))}
                        </tr>
                      </thead>
                      <tbody>
                        {sortedUserIds.map(uid => {
                          const name = uid === user!.id
                            ? `${user!.first_name} ${user!.last_name}`
                            : (colleagueMap[uid] ?? uid)
                          const firstName = name.split(' ')[0]
                          const lastName = name.split(' ').slice(1).join(' ')

                          return (
                            <tr key={uid} className='border-b border-gray-50 hover:bg-gray-50/50'>
                              <td className='sticky left-0 bg-white z-10 py-2 px-3 border-r border-gray-100'>
                                <div className='text-sm font-medium text-gray-800 truncate max-w-[100px]'>
                                  {firstName}
                                  {lastName && <span className='text-gray-400 font-normal ml-1 text-xs'>{lastName.charAt(0)}.</span>}
                                </div>
                              </td>

                              {Array.from({ length: 12 }, (_, monthIdx) => {
                                const cellAbsences = absenceSpans.filter(s => {
                                  const first = new Date(year, monthIdx, 1)
                                  const last = new Date(year, monthIdx + 1, 0)
                                  return s.userId === uid && s.start <= last && s.end >= first
                                    && s.status !== 'cancelled' && s.status !== 'rejected'
                                })
                                const isActiveMonth = monthIdx === planMonth
                                const totalDays = cellAbsences.reduce((sum, s) => {
                                  const first = new Date(year, monthIdx, 1)
                                  const last = new Date(year, monthIdx + 1, 0)
                                  const cs = s.start < first ? first : s.start
                                  const ce = s.end > last ? last : s.end
                                  return sum + Math.round((ce.getTime() - cs.getTime()) / 86400000) + 1
                                }, 0)

                                return (
                                  <td key={monthIdx}
                                    onClick={() => setPlanMonth(monthIdx)}
                                    className={`py-1.5 px-1 text-center cursor-pointer transition-colors ${isActiveMonth ? 'bg-blue-50' : 'hover:bg-gray-50'}`}>
                                    {cellAbsences.length === 0 ? (
                                      <span className='text-gray-200 text-xs'>·</span>
                                    ) : (
                                      <div className='flex flex-col items-center gap-0.5'>
                                        <div className='flex gap-0.5 justify-center flex-wrap'>
                                          {[...new Map(cellAbsences.map(s => [s.color, s])).values()].slice(0, 4).map(s => (
                                            <span key={s.color} className='w-2 h-2 rounded-full flex-shrink-0'
                                              style={{ backgroundColor: s.color,
                                                opacity: cellAbsences.every(a => a.status === 'pending') ? 0.5 : 1 }} />
                                          ))}
                                        </div>
                                        <span className='text-[10px] text-gray-500 leading-none'>{totalDays}d</span>
                                      </div>
                                    )}
                                  </td>
                                )
                              })}
                            </tr>
                          )
                        })}
                      </tbody>
                    </table>
                  </div>
                </div>
              )
            })()}

            {/* Monatskalender */}
            <div className='bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden'>

              {/* Header */}
              <div className='px-5 py-3.5 border-b border-gray-100 flex items-center justify-between'>
                <div className='flex items-center gap-2'>
                  <button onClick={() => setPlanMonth(m => (m - 1 + 12) % 12)}
                    className='p-1.5 rounded-md hover:bg-gray-100 text-gray-500 transition-colors'>
                    <svg className='w-4 h-4' fill='none' viewBox='0 0 24 24' stroke='currentColor'><path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M15 19l-7-7 7-7' /></svg>
                  </button>
                  <h2 className='text-base font-semibold text-gray-800 w-44 text-center'>
                    {MONTHS[planMonth]} {year}
                  </h2>
                  <button onClick={() => setPlanMonth(m => (m + 1) % 12)}
                    className='p-1.5 rounded-md hover:bg-gray-100 text-gray-500 transition-colors'>
                    <svg className='w-4 h-4' fill='none' viewBox='0 0 24 24' stroke='currentColor'><path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M9 5l7 7-7 7' /></svg>
                  </button>
                  <button onClick={() => setPlanMonth(today.getMonth())}
                    className='ml-1 px-2.5 py-1 text-xs border border-gray-200 text-gray-600 rounded-md hover:bg-gray-50 transition-colors'>
                    Heute
                  </button>
                </div>
                <button onClick={() => openPrint(buildMonthHtml())}
                  className='flex items-center gap-1.5 px-3 py-1.5 border border-gray-200 text-gray-600 rounded-lg text-xs hover:bg-gray-50 transition-colors'
                  title='Drucken'>
                  <svg className='w-3.5 h-3.5' fill='none' viewBox='0 0 24 24' stroke='currentColor'><path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z' /></svg>
                  Drucken
                </button>
                <button onClick={() => openPdf(buildMonthHtml())}
                  className='flex items-center gap-1.5 px-3 py-1.5 border border-gray-200 text-gray-600 rounded-lg text-xs hover:bg-gray-50 transition-colors'
                  title='Als PDF speichern'>
                  <svg className='w-3.5 h-3.5' fill='none' viewBox='0 0 24 24' stroke='currentColor'><path strokeLinecap='round' strokeLinejoin='round' strokeWidth={2} d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z' /></svg>
                  PDF
                </button>
              </div>

              {/* Resource-Timeline (Gantt) */}
              {(() => {
                const CELL_W = 36
                const daysInMonth = new Date(year, planMonth + 1, 0).getDate()
                const monthDays = Array.from({ length: daysInMonth }, (_, i) => new Date(year, planMonth, i + 1))
                const monthAbsenceSpans = absenceSpans.filter(s => {
                  const first = new Date(year, planMonth, 1)
                  const last = new Date(year, planMonth + 1, 0)
                  return s.start <= last && s.end >= first && s.status !== 'cancelled' && s.status !== 'rejected'
                })
                const visibleUserIds = isManager
                  ? [...new Set([user!.id, ...monthAbsenceSpans.map(s => s.userId)])]
                  : [user!.id]
                const sortedUserIds = [...visibleUserIds].sort((a, b) => {
                  if (a === user!.id) return -1
                  if (b === user!.id) return 1
                  return (colleagueMap[a] ?? '').localeCompare(colleagueMap[b] ?? '', 'de')
                })

                if (monthAbsenceSpans.length === 0) {
                  return (
                    <p className='text-center text-gray-400 py-10 text-sm'>Keine Abwesenheiten im {MONTHS[planMonth]}</p>
                  )
                }

                return (
                  <div className='overflow-x-auto'>
                    <div style={{ minWidth: 120 + CELL_W * daysInMonth }}>
                      {/* Header row */}
                      <div className='flex border-b border-gray-100 bg-gray-50'>
                        <div style={{ width: 120, minWidth: 120, flexShrink: 0 }} className='sticky left-0 z-10 bg-gray-50 border-r border-gray-200' />
                        {monthDays.map((day, idx) => {
                          const wd = (day.getDay() + 6) % 7
                          const isWeekend = wd >= 5
                          const isToday = day.toDateString() === todayStr
                          const dayLabel = ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'][wd]
                          return (
                            <div key={idx} style={{ width: CELL_W, minWidth: CELL_W, flexShrink: 0 }}
                              className={`flex flex-col items-center justify-center border-r border-gray-100 last:border-r-0 py-1 ${isWeekend ? 'bg-gray-50' : ''}`}>
                              <span className='text-[10px] text-gray-400 leading-none mb-0.5'>{dayLabel}</span>
                              {isToday ? (
                                <span className='inline-flex items-center justify-center w-5 h-5 bg-blue-600 text-white rounded-full text-[11px] font-bold leading-none'>
                                  {day.getDate()}
                                </span>
                              ) : (
                                <span className={`text-[12px] font-medium leading-none ${isWeekend ? 'text-gray-400' : 'text-gray-700'}`}>
                                  {day.getDate()}
                                </span>
                              )}
                            </div>
                          )
                        })}
                      </div>

                      {/* User rows */}
                      {sortedUserIds.map(uid => {
                        const fullName = uid === user!.id
                          ? `${user!.first_name} ${user!.last_name}`
                          : (colleagueMap[uid] ?? uid)
                        const firstName = fullName.split(' ')[0]
                        const bal = colleagueBalances[uid]
                        const userSpans = monthAbsenceSpans.filter(s => s.userId === uid)
                        const first = new Date(year, planMonth, 1)
                        const last = new Date(year, planMonth + 1, 0)

                        return (
                          <div key={uid} className='flex border-b border-gray-100 last:border-b-0' style={{ height: 40 }}>
                            <div style={{ width: 120, minWidth: 120, flexShrink: 0 }}
                              className='sticky left-0 z-10 bg-white/95 backdrop-blur border-r border-gray-200 flex flex-col justify-center px-3'>
                              <span className='text-sm font-medium text-gray-800 truncate leading-tight'>{firstName}</span>
                              {isManager && bal != null && (
                                <span className={`text-[10px] font-medium leading-tight ${bal.remaining_days <= 0 ? 'text-red-500' : bal.remaining_days <= 5 ? 'text-yellow-600' : 'text-green-600'}`}>
                                  {bal.remaining_days} Tage
                                </span>
                              )}
                            </div>
                            <div className='relative flex-1' style={{ width: CELL_W * daysInMonth }}>
                              {monthDays.map((day, idx) => {
                                const wd = (day.getDay() + 6) % 7
                                const isWeekend = wd >= 5
                                return (
                                  <div key={idx}
                                    className={`absolute top-0 bottom-0 border-r border-gray-100 last:border-r-0 ${isWeekend ? 'bg-gray-50/60' : ''}`}
                                    style={{ left: idx * CELL_W, width: CELL_W }}
                                  />
                                )
                              })}
                              {userSpans.map(span => {
                                const clampedStart = span.start < first ? first : span.start
                                const clampedEnd = span.end > last ? last : span.end
                                const startIdx = clampedStart.getDate() - 1
                                const endIdx = clampedEnd.getDate() - 1
                                const spanDays = endIdx - startIdx + 1
                                const isContinuedLeft = span.start < first
                                const isContinuedRight = span.end > last
                                const leftOffset = startIdx * CELL_W + (isContinuedLeft ? 0 : 2)
                                const barWidth = spanDays * CELL_W - (isContinuedLeft ? 0 : 2) - (isContinuedRight ? 0 : 2)
                                const borderRadius = `${isContinuedLeft ? 0 : 4}px ${isContinuedRight ? 0 : 4}px ${isContinuedRight ? 0 : 4}px ${isContinuedLeft ? 0 : 4}px`

                                return (
                                  <div key={span.id}
                                    className='absolute flex items-center overflow-hidden'
                                    style={{
                                      top: 4, bottom: 4, left: leftOffset, width: barWidth,
                                      backgroundColor: span.color,
                                      opacity: span.status === 'pending' ? 0.65 : 1,
                                      borderRadius,
                                      borderLeft: isContinuedLeft ? '3px solid rgba(0,0,0,0.15)' : undefined,
                                    }}>
                                    <span className='px-1.5 text-white text-[11px] font-medium truncate leading-none select-none'>
                                      {span.typeName}
                                      {span.status === 'pending' && <span className='opacity-75 ml-0.5 text-[10px]'>?</span>}
                                    </span>
                                  </div>
                                )
                              })}
                            </div>
                          </div>
                        )
                      })}
                    </div>
                  </div>
                )
              })()}
            </div>
          </div>
        )}

        {/* ─── Modals ──────────────────────────────────────────────────────── */}

        {showBalanceEdit && balance && (
          <BalanceEditModal
            year={year}
            balance={balance}
            balanceForm={balanceForm}
            setBalanceForm={setBalanceForm}
            balanceSaving={balanceSaving}
            onSave={handleSaveBalance}
            onClose={() => setShowBalanceEdit(false)}
          />
        )}

        {editAbsence && (
          <EditAbsenceModal
            editAbsence={editAbsence}
            editForm={editForm}
            setEditForm={setEditForm}
            types={types}
            isManager={isManager}
            submitting={submitting}
            error={error}
            onSave={handleSaveEdit}
            onClose={() => { setEditAbsence(null); setError('') }}
          />
        )}

        {showCreate && (
          <CreateAbsenceModal
            form={form}
            setForm={setForm}
            types={types}
            colleagues={colleagues}
            isManager={isManager}
            submitting={submitting}
            error={error}
            overtimeBalance={overtimeBalance}
            fzaMode={fzaMode}
            setFzaMode={setFzaMode}
            fzaHours={fzaHours}
            setFzaHours={setFzaHours}
            isFzaType={isFzaType}
            onCreate={handleCreate}
            onClose={() => {
              setShowCreate(false)
              setError('')
              setForm({ type_id: '', start_date: '', end_date: '', half_day_start: false, half_day_end: false, note: '', for_user_id: '', substitute_id: '' })
              setFzaMode('days')
              setFzaHours(4)
            }}
          />
        )}

        {showQuickSick && (
          <QuickSickModal
            form={quickSickForm}
            setForm={setQuickSickForm}
            submitting={quickSubmitting}
            error={quickError}
            onSubmit={handleQuickSick}
            onClose={() => { setShowQuickSick(false); setQuickError('') }}
          />
        )}

        {commentsFor && (
          <AbsenceCommentsModal
            absenceId={commentsFor.id}
            onClose={() => setCommentsFor(null)}
          />
        )}

      </div>
    </Layout>
  )
}
