import { useEffect, useState } from 'react'
import { api } from '../api/client'
import { Spinner } from '../components/Spinner'
import { Layout } from '../components/Layout'
import { Modal } from '../components/Modal'

interface UserOut {
  id: string
  email: string
  first_name: string
  last_name: string
  full_name: string
  role: string
  is_active: boolean
  auth_provider: string
  department_id: string | null
  work_schedule_id: string | null
  kuerzel: string | null
  personnel_number: string | null
  can_manual_time_entry: boolean
  entry_date: string | null
  exit_date: string | null
  anonymized_at: string | null
  last_login: string | null
  created_at: string
}

interface CompanyOut {
  id: string
  personnel_number_required: boolean
  personnel_number_mode: 'manual' | 'auto'
  personnel_number_next: number
}

interface WorkScheduleOut {
  id: string
  name: string
  mon_h: number
  tue_h: number
  wed_h: number
  thu_h: number
  fri_h: number
  sat_h: number
  sun_h: number
}

interface Me {
  first_name: string
  last_name: string
  role: string
}

interface UserListResponse {
  total: number
  items: UserOut[]
}

const ROLES = ['EMPLOYEE', 'MANAGER', 'HR', 'COMPANY_ADMIN']
const ROLE_LABELS: Record<string, string> = {
  COMPANY_ADMIN: 'Administrator',
  HR: 'HR',
  MANAGER: 'Manager',
  EMPLOYEE: 'Mitarbeiter',
}
const ROLE_DESCRIPTIONS: Record<string, string> = {
  EMPLOYEE:      'Kann eigene Zeiten erfassen, Abwesenheiten beantragen und den eigenen Kalender einsehen.',
  MANAGER:       'Wie Mitarbeiter, zusätzlich: kann Abwesenheiten seines Teams genehmigen oder ablehnen und Berichte einsehen.',
  HR:            'Wie Manager, zusätzlich: kann Mitarbeiter verwalten, alle Abwesenheiten bearbeiten und Berichte für alle einsehen.',
  COMPANY_ADMIN: 'Vollzugriff: alle Einstellungen, Mitarbeiterverwaltung, Arbeitspläne, LDAP, SMTP und CalDAV konfigurieren.',
}

function Badge({ text, color }: { text: string; color: string }) {
  return (
    <span className={`inline-block text-xs px-2 py-0.5 rounded-full font-medium ${color}`}>
      {text}
    </span>
  )
}

interface InviteForm {
  email: string
  first_name: string
  last_name: string
  role: string
  personnel_number: string
  initial_password: string
}

const EMPTY_INVITE: InviteForm = { email: '', first_name: '', last_name: '', role: 'EMPLOYEE', personnel_number: '', initial_password: '' }

interface ImportRowResult {
  row: number
  email: string
  personnel_number: string | null
  action: string
  message: string | null
}

interface ImportResult {
  total_rows: number
  created: number
  reactivated: number
  errors: number
  items: ImportRowResult[]
}

export function UsersPage() {
  const [me, setMe]           = useState<Me | null>(null)
  const [users, setUsers]     = useState<UserOut[]>([])
  const [total, setTotal]     = useState(0)
  const [loading, setLoading] = useState(true)
  const [error, setError]     = useState('')
  const [search, setSearch]   = useState('')

  // Invite modal
  const [showInvite, setShowInvite]   = useState(false)
  const [invite, setInvite]           = useState<InviteForm>(EMPTY_INVITE)
  const [inviteLoading, setInviteLoading] = useState(false)
  const [inviteError, setInviteError] = useState('')
  const [inviteSuccess, setInviteSuccess] = useState('')

  // Work schedules
  const [workSchedules, setWorkSchedules] = useState<WorkScheduleOut[]>([])

  // Edit role modal
  const [editUser, setEditUser]         = useState<UserOut | null>(null)
  const [editRole, setEditRole]         = useState('')
  const [editScheduleId, setEditScheduleId] = useState<string | null>(null)
  const [editKuerzel, setEditKuerzel]   = useState<string>('')
  const [editPersonnelNr, setEditPersonnelNr] = useState<string>('')
  const [editCanManual, setEditCanManual] = useState(false)
  const [editEntryDate, setEditEntryDate] = useState<string>('')
  const [editExitDate, setEditExitDate] = useState<string>('')
  const [editLoading, setEditLoading]   = useState(false)

  // Personalnummer-Verfügbarkeitsprüfung
  const [personnelCheck, setPersonnelCheck] = useState<'idle' | 'checking' | 'free' | 'taken' | 'invalid'>('idle')

  // Company-Settings (für Auto-Modus / Pflicht-Anzeige)
  const [company, setCompany] = useState<CompanyOut | null>(null)

  // CSV-Import modal
  const [showImport, setShowImport]         = useState(false)
  const [importFile, setImportFile]         = useState<File | null>(null)
  const [importPreview, setImportPreview]   = useState<ImportResult | null>(null)
  const [importLoading, setImportLoading]   = useState(false)
  const [importError, setImportError]       = useState('')
  const [importSuccess, setImportSuccess]   = useState('')

  async function load() {
    try {
      const [meData, listData, schedulesData] = await Promise.all([
        api.get<Me>('/auth/me'),
        api.get<UserListResponse>('/users'),
        api.get<WorkScheduleOut[]>('/time/schedules').catch(() => [] as WorkScheduleOut[]),
      ])
      setMe(meData)
      setUsers(listData.items)
      setTotal(listData.total)
      setWorkSchedules(schedulesData)
      // Company-Settings laden (für Auto-Modus + Pflicht)
      try {
        const meFull = await api.get<{ company_id: string }>('/users/me')
        if (meFull.company_id) {
          const c = await api.get<CompanyOut>(`/companies/${meFull.company_id}`)
          setCompany(c)
        }
      } catch { /* nicht kritisch */ }
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : 'Fehler beim Laden')
    } finally {
      setLoading(false)
    }
  }

  function weeklyHours(s: WorkScheduleOut): number {
    return Number(s.mon_h) + Number(s.tue_h) + Number(s.wed_h) + Number(s.thu_h) + Number(s.fri_h) + Number(s.sat_h) + Number(s.sun_h)
  }

  useEffect(() => { load() }, [])

  async function handleInvite() {
    setInviteError('')
    setInviteSuccess('')
    if (!invite.email || !invite.first_name || !invite.last_name) {
      setInviteError('Alle Felder sind erforderlich.')
      return
    }
    setInviteLoading(true)
    try {
      const payload = { ...invite, initial_password: invite.initial_password || undefined }
      await api.post('/users/invite', payload)
      const msg = invite.initial_password
        ? `Benutzer ${invite.email} wurde direkt angelegt und ist sofort aktiv.`
        : `Einladung an ${invite.email} gesendet.`
      setInviteSuccess(msg)
      setInvite(EMPTY_INVITE)
      load()
    } catch (e: unknown) {
      setInviteError(e instanceof Error ? e.message : 'Fehler')
    } finally {
      setInviteLoading(false)
    }
  }

  async function handleDeactivate(user: UserOut) {
    if (!confirm(`${user.full_name} wirklich deaktivieren?`)) return
    try {
      await api.patch(`/users/${user.id}`, { is_active: false })
      load()
    } catch (e: unknown) {
      alert(e instanceof Error ? e.message : 'Fehler')
    }
  }

  async function handleReactivate(user: UserOut) {
    try {
      await api.patch(`/users/${user.id}`, { is_active: true })
      load()
    } catch (e: unknown) {
      alert(e instanceof Error ? e.message : 'Fehler')
    }
  }

  async function handleAnonymize(user: UserOut) {
    if (!confirm(
      `DSGVO-Anonymisierung von ${user.full_name}?\n\n` +
      `Name und E-Mail werden unwiderruflich entfernt, das Konto wird deaktiviert. ` +
      `Zeit-, Abwesenheits- und Auszahlungsdaten bleiben (gesetzliche Aufbewahrung), ` +
      `aber ohne Personenbezug. Nicht umkehrbar.`
    )) return
    try {
      await api.post(`/users/${user.id}/anonymize`, {})
      load()
    } catch (e: unknown) {
      alert(e instanceof Error ? e.message : 'Fehler')
    }
  }

  async function handleEditRole() {
    if (!editUser) return
    setEditLoading(true)
    try {
      const payload: Record<string, unknown> = {
        role: editRole,
        work_schedule_id: editScheduleId || null,
        kuerzel: editKuerzel.trim() || null,
        can_manual_time_entry: editCanManual,
        entry_date: editEntryDate || null,
        exit_date: editExitDate || null,
      }
      // Personalnr. nur senden wenn geändert
      const newPn = editPersonnelNr.trim()
      if (newPn && newPn !== (editUser.personnel_number || '')) {
        payload.personnel_number = newPn
      }
      await api.patch(`/users/${editUser.id}`, payload)
      setEditUser(null)
      load()
    } catch (e: unknown) {
      alert(e instanceof Error ? e.message : 'Fehler')
    } finally {
      setEditLoading(false)
    }
  }

  async function suggestPersonnelNumber(target: 'invite' | 'edit') {
    try {
      const r = await api.get<{ next: string }>('/users/next-personnel-number')
      if (target === 'invite') setInvite(f => ({ ...f, personnel_number: r.next }))
      else setEditPersonnelNr(r.next)
    } catch (e: unknown) {
      alert(e instanceof Error ? e.message : 'Fehler')
    }
  }

  // Debounced Live-Verfügbarkeitsprüfung
  function checkPersonnelNumber(value: string, currentUserId?: string) {
    setPersonnelCheck('idle')
    const v = value.trim()
    if (!v) return
    if (!/^[0-9]+$/.test(v)) {
      setPersonnelCheck('invalid')
      return
    }
    setPersonnelCheck('checking')
    const handle = setTimeout(async () => {
      try {
        const u = await api.get<UserOut>(`/users/by-personnel/${encodeURIComponent(v)}`)
        if (u.id === currentUserId) setPersonnelCheck('free')
        else setPersonnelCheck('taken')
      } catch {
        // 404 = frei
        setPersonnelCheck('free')
      }
    }, 400)
    return () => clearTimeout(handle)
  }

  async function handleImportPreview() {
    if (!importFile) return
    setImportLoading(true)
    setImportError('')
    setImportPreview(null)
    try {
      const form = new FormData()
      form.append('file', importFile)
      const result = await api.postForm<ImportResult>('/users/import/preview', form)
      setImportPreview(result)
    } catch (e: unknown) {
      setImportError(e instanceof Error ? e.message : 'Fehler beim Prüfen')
    } finally {
      setImportLoading(false)
    }
  }

  async function handleImportApply() {
    if (!importFile) return
    setImportLoading(true)
    setImportError('')
    setImportSuccess('')
    try {
      const form = new FormData()
      form.append('file', importFile)
      const result = await api.postForm<ImportResult>('/users/import/apply', form)
      setImportSuccess(`Import abgeschlossen: ${result.created} angelegt, ${result.reactivated} reaktiviert, ${result.errors} Fehler.`)
      setImportPreview(result)
      setImportFile(null)
      load()
    } catch (e: unknown) {
      setImportError(e instanceof Error ? e.message : 'Fehler beim Import')
    } finally {
      setImportLoading(false)
    }
  }

  function openImportModal() {
    setShowImport(true)
    setImportFile(null)
    setImportPreview(null)
    setImportError('')
    setImportSuccess('')
  }

  const filtered = users.filter(u =>
    `${u.full_name} ${u.email} ${u.personnel_number ?? ''}`.toLowerCase().includes(search.toLowerCase())
  )

  const inputClass = 'w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent'

  if (loading) return (
    <div className='min-h-screen bg-gray-50 flex items-center justify-center'><Spinner /></div>
  )
  if (error) return (
    <div className='min-h-screen bg-gray-50 flex items-center justify-center'>
      <p className='text-red-600'>{error}</p>
    </div>
  )

  return (
    <Layout userRole={me?.role ?? ''} userName={`${me?.first_name} ${me?.last_name}`}>
      <div className='space-y-6'>
        {/* Header */}
        <div className='flex items-center justify-between'>
          <div>
            <h1 className='text-xl font-bold text-gray-800'>Mitarbeiterverwaltung</h1>
            <p className='text-sm text-gray-500 mt-0.5'>{total} Mitarbeiter gesamt</p>
          </div>
          <div className='flex gap-2'>
            <button
              onClick={openImportModal}
              className='px-4 py-2 bg-gray-100 text-gray-700 text-sm font-semibold rounded-lg hover:bg-gray-200 transition-colors border border-gray-200'
            >
              CSV Import
            </button>
            <button
              onClick={() => { setShowInvite(true); setInviteSuccess(''); setInviteError('') }}
              className='px-4 py-2 bg-blue-600 text-white text-sm font-semibold rounded-lg hover:bg-blue-700 transition-colors'
            >
              + Einladen
            </button>
          </div>
        </div>

        {/* Search */}
        <input
          type='text'
          placeholder='Name oder E-Mail suchen…'
          value={search}
          onChange={e => setSearch(e.target.value)}
          className={inputClass}
        />

        {/* Table */}
        <div className='bg-white rounded-xl border border-gray-100 shadow-sm overflow-hidden'>
          <div className='overflow-x-auto'>
            <table className='w-full text-sm'>
              <thead className='bg-gray-50 text-gray-500 text-xs uppercase'>
                <tr>
                  {['Name', 'Pers.-Nr.', 'E-Mail', 'Rolle', 'Auth', 'Status', 'Letzter Login', ''].map(h => (
                    <th key={h} className='px-4 py-3 text-left font-medium'>{h}</th>
                  ))}
                </tr>
              </thead>
              <tbody className='divide-y divide-gray-100'>
                {filtered.map(u => (
                  <tr key={u.id} className='hover:bg-gray-50 transition-colors'>
                    <td className='px-4 py-3'>
                      <div className='font-medium text-gray-800'>{u.full_name}</div>
                      {u.work_schedule_id && (
                        <div className='text-xs text-gray-400 mt-0.5'>
                          {workSchedules.find(s => s.id === u.work_schedule_id)
                            ? `${workSchedules.find(s => s.id === u.work_schedule_id)!.name} (${weeklyHours(workSchedules.find(s => s.id === u.work_schedule_id)!)}h/Wo.)`
                            : ''}
                        </div>
                      )}
                    </td>
                    <td className='px-4 py-3 text-gray-600 font-mono text-xs'>{u.personnel_number || '—'}</td>
                    <td className='px-4 py-3 text-gray-600'>{u.email}</td>
                    <td className='px-4 py-3'>
                      <Badge
                        text={ROLE_LABELS[u.role] ?? u.role}
                        color={u.role === 'COMPANY_ADMIN' ? 'bg-purple-100 text-purple-700' : 'bg-gray-100 text-gray-600'}
                      />
                    </td>
                    <td className='px-4 py-3'>
                      <Badge
                        text={u.auth_provider === 'ldap' ? 'LDAP' : 'Lokal'}
                        color={u.auth_provider === 'ldap' ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 text-gray-500'}
                      />
                    </td>
                    <td className='px-4 py-3'>
                      <Badge
                        text={u.anonymized_at ? 'Anonymisiert' : u.is_active ? 'Aktiv' : 'Inaktiv'}
                        color={u.anonymized_at ? 'bg-gray-200 text-gray-500' : u.is_active ? 'bg-green-100 text-green-700' : 'bg-red-100 text-red-600'}
                      />
                    </td>
                    <td className='px-4 py-3 text-gray-500'>
                      {u.last_login ? new Date(u.last_login).toLocaleDateString('de-DE') : '—'}
                    </td>
                    <td className='px-4 py-3'>
                      {u.anonymized_at ? (
                        <div className='flex justify-end text-xs text-gray-400 italic'>
                          anonymisiert am {new Date(u.anonymized_at).toLocaleDateString('de-DE')}
                        </div>
                      ) : (
                      <div className='flex gap-2 justify-end'>
                        <button
                          onClick={() => {
                            setEditUser(u); setEditRole(u.role); setEditScheduleId(u.work_schedule_id)
                            setEditKuerzel(u.kuerzel ?? ''); setEditPersonnelNr(u.personnel_number ?? '')
                            setEditCanManual(u.can_manual_time_entry); setPersonnelCheck('idle')
                            setEditEntryDate(u.entry_date ?? ''); setEditExitDate(u.exit_date ?? '')
                          }}
                          className='text-xs text-blue-600 hover:underline'
                        >
                          Bearbeiten
                        </button>
                        {u.is_active ? (
                          <button
                            onClick={() => handleDeactivate(u)}
                            className='text-xs text-red-500 hover:underline'
                          >
                            Deaktivieren
                          </button>
                        ) : (
                          <button
                            onClick={() => handleReactivate(u)}
                            className='text-xs text-green-600 hover:underline'
                          >
                            Reaktivieren
                          </button>
                        )}
                        <button
                          onClick={() => handleAnonymize(u)}
                          className='text-xs text-gray-400 hover:text-red-600 hover:underline'
                          title='DSGVO Art. 17 – Personenbezug entfernen (nicht umkehrbar)'
                        >
                          Anonymisieren
                        </button>
                      </div>
                      )}
                    </td>
                  </tr>
                ))}
                {filtered.length === 0 && (
                  <tr>
                    <td colSpan={8} className='px-4 py-8 text-center text-gray-400'>
                      Keine Mitarbeiter gefunden.
                    </td>
                  </tr>
                )}
              </tbody>
            </table>
          </div>
        </div>
      </div>

      {/* Invite Modal */}
      {showInvite && (
        <Modal title='Mitarbeiter einladen' onClose={() => setShowInvite(false)}>
          <div className='space-y-3'>
            <div className='flex gap-3'>
              <label className='block flex-1'>
                <span className='text-xs font-medium text-gray-700'>Vorname *</span>
                <input value={invite.first_name} onChange={e => setInvite(f => ({ ...f, first_name: e.target.value }))} className={inputClass} placeholder='Max' />
              </label>
              <label className='block flex-1'>
                <span className='text-xs font-medium text-gray-700'>Nachname *</span>
                <input value={invite.last_name} onChange={e => setInvite(f => ({ ...f, last_name: e.target.value }))} className={inputClass} placeholder='Mustermann' />
              </label>
            </div>
            <label className='block'>
              <span className='text-xs font-medium text-gray-700'>E-Mail *</span>
              <input type='email' value={invite.email} onChange={e => setInvite(f => ({ ...f, email: e.target.value }))} className={inputClass} placeholder='max@firma.de' />
            </label>
            <label className='block'>
              <span className='text-xs font-medium text-gray-700'>Rolle</span>
              <select value={invite.role} onChange={e => setInvite(f => ({ ...f, role: e.target.value }))} className={inputClass}>
                {ROLES.map(r => <option key={r} value={r}>{ROLE_LABELS[r] ?? r}</option>)}
              </select>
              {ROLE_DESCRIPTIONS[invite.role] && (
                <p className='mt-1.5 text-xs text-gray-500 bg-gray-50 border border-gray-100 rounded-lg px-3 py-2 leading-relaxed'>
                  {ROLE_DESCRIPTIONS[invite.role]}
                </p>
              )}
            </label>
            <label className='block'>
              <span className='text-xs font-medium text-gray-700'>
                Personalnummer {company?.personnel_number_required && <span className='text-red-500'>*</span>}
                <span className='ml-1 font-normal text-gray-400'>(nur Ziffern)</span>
              </span>
              <div className='flex gap-2 items-stretch'>
                <input
                  type='text'
                  inputMode='numeric'
                  value={invite.personnel_number}
                  onChange={e => {
                    const v = e.target.value.replace(/[^0-9]/g, '')
                    setInvite(f => ({ ...f, personnel_number: v }))
                    checkPersonnelNumber(v)
                  }}
                  className={inputClass}
                  placeholder={company?.personnel_number_mode === 'auto' ? 'Leer = Auto-Vergabe' : 'z.B. 1042'}
                  maxLength={50}
                />
                <button
                  type='button'
                  onClick={() => suggestPersonnelNumber('invite')}
                  className='px-3 py-2 text-xs font-medium text-blue-600 border border-blue-200 rounded-lg hover:bg-blue-50 whitespace-nowrap'
                >
                  Vorschlagen
                </button>
              </div>
              {invite.personnel_number && (
                <p className={`mt-1 text-xs ${
                  personnelCheck === 'taken' ? 'text-red-600' :
                  personnelCheck === 'invalid' ? 'text-red-600' :
                  personnelCheck === 'free' ? 'text-green-600' :
                  'text-gray-400'
                }`}>
                  {personnelCheck === 'checking' && 'Prüfe Verfügbarkeit…'}
                  {personnelCheck === 'free' && '✓ Personalnr. frei'}
                  {personnelCheck === 'taken' && '✗ Personalnr. bereits vergeben'}
                  {personnelCheck === 'invalid' && 'Nur Ziffern erlaubt'}
                </p>
              )}
            </label>
            <label className='block'>
              <span className='text-xs font-medium text-gray-700'>
                Passwort direkt setzen
                <span className='ml-1 font-normal text-gray-400'>(optional – leer = E-Mail-Einladung)</span>
              </span>
              <input
                type='password'
                value={invite.initial_password}
                onChange={e => setInvite(f => ({ ...f, initial_password: e.target.value }))}
                className={inputClass}
                placeholder='Min. 8 Zeichen, 1 Großbuchstabe, 1 Zahl'
                autoComplete='new-password'
              />
              {invite.initial_password && (
                <p className='mt-1 text-xs text-blue-600'>
                  Benutzer wird sofort aktiv angelegt, kein E-Mail-Versand nötig.
                </p>
              )}
            </label>
            {inviteError && <p className='text-sm text-red-600 bg-red-50 border border-red-200 rounded px-3 py-2'>{inviteError}</p>}
            {inviteSuccess && <p className='text-sm text-green-700 bg-green-50 border border-green-200 rounded px-3 py-2'>{inviteSuccess}</p>}
            <div className='flex justify-end gap-2 pt-2'>
              <button onClick={() => setShowInvite(false)} className='px-4 py-2 text-sm text-gray-600 border border-gray-300 rounded-lg hover:bg-gray-50'>Abbrechen</button>
              <button onClick={handleInvite} disabled={inviteLoading} className='px-4 py-2 text-sm font-semibold text-white bg-blue-600 rounded-lg hover:bg-blue-700 disabled:opacity-50'>
                {inviteLoading ? 'Sende…' : 'Einladen'}
              </button>
            </div>
          </div>
        </Modal>
      )}

      {/* CSV Import Modal */}
      {showImport && (
        <Modal title='Mitarbeiter per CSV importieren' onClose={() => setShowImport(false)}>
          <div className='space-y-4'>
            <div className='flex items-center justify-between bg-blue-50 border border-blue-100 rounded-lg px-3 py-2'>
              <span className='text-xs text-blue-700'>Vorlage mit Pflicht- und Optionalspalten herunterladen</span>
              <a
                href='/api/v1/users/import-template.csv'
                download='import-vorlage.csv'
                className='text-xs font-semibold text-blue-600 hover:underline ml-4 whitespace-nowrap'
              >
                Vorlage herunterladen
              </a>
            </div>

            <div>
              <label className='block text-xs font-medium text-gray-700 mb-1'>CSV-Datei auswählen</label>
              <input
                type='file'
                accept='.csv,text/csv'
                onChange={e => {
                  setImportFile(e.target.files?.[0] ?? null)
                  setImportPreview(null)
                  setImportError('')
                  setImportSuccess('')
                }}
                className='block w-full text-sm text-gray-600 file:mr-3 file:py-1.5 file:px-3 file:rounded file:border-0 file:text-xs file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100'
              />
            </div>

            {importError && <p className='text-sm text-red-600 bg-red-50 border border-red-200 rounded px-3 py-2'>{importError}</p>}
            {importSuccess && <p className='text-sm text-green-700 bg-green-50 border border-green-200 rounded px-3 py-2'>{importSuccess}</p>}

            {importPreview && (
              <div className='space-y-2'>
                <div className='flex gap-4 text-sm'>
                  <span className='text-green-700 font-medium'>{importPreview.created} neu</span>
                  <span className='text-blue-700 font-medium'>{importPreview.reactivated} reaktiviert</span>
                  <span className='text-red-600 font-medium'>{importPreview.errors} Fehler</span>
                  <span className='text-gray-500'>{importPreview.total_rows} Zeilen gesamt</span>
                </div>
                <div className='max-h-56 overflow-y-auto border border-gray-200 rounded-lg'>
                  <table className='w-full text-xs'>
                    <thead className='bg-gray-50 text-gray-500 sticky top-0'>
                      <tr>
                        {['Zeile', 'E-Mail', 'Pers.-Nr.', 'Aktion', 'Meldung'].map(h => (
                          <th key={h} className='px-3 py-2 text-left font-medium'>{h}</th>
                        ))}
                      </tr>
                    </thead>
                    <tbody className='divide-y divide-gray-100'>
                      {importPreview.items.map((it, i) => (
                        <tr key={i} className={it.action === 'error' ? 'bg-red-50' : it.action === 'reactivated' ? 'bg-blue-50' : ''}>
                          <td className='px-3 py-1.5 text-gray-500'>{it.row || '—'}</td>
                          <td className='px-3 py-1.5 font-mono'>{it.email || '—'}</td>
                          <td className='px-3 py-1.5 font-mono'>{it.personnel_number || '—'}</td>
                          <td className='px-3 py-1.5'>
                            <span className={`font-semibold ${
                              it.action === 'error' ? 'text-red-600' :
                              it.action === 'reactivated' ? 'text-blue-600' :
                              'text-green-600'
                            }`}>
                              {it.action === 'error' ? 'Fehler' : it.action === 'reactivated' ? 'Reaktiviert' : 'Neu'}
                            </span>
                          </td>
                          <td className='px-3 py-1.5 text-gray-500'>{it.message || ''}</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              </div>
            )}

            <div className='flex justify-end gap-2 pt-1'>
              <button onClick={() => setShowImport(false)} className='px-4 py-2 text-sm text-gray-600 border border-gray-300 rounded-lg hover:bg-gray-50'>Schließen</button>
              <button
                onClick={handleImportPreview}
                disabled={!importFile || importLoading}
                className='px-4 py-2 text-sm font-semibold text-white bg-gray-600 rounded-lg hover:bg-gray-700 disabled:opacity-50'
              >
                {importLoading && !importPreview ? 'Prüfe…' : 'Vorschau prüfen'}
              </button>
              {importPreview && importPreview.errors === 0 && !importSuccess && (
                <button
                  onClick={handleImportApply}
                  disabled={importLoading}
                  className='px-4 py-2 text-sm font-semibold text-white bg-green-600 rounded-lg hover:bg-green-700 disabled:opacity-50'
                >
                  {importLoading ? 'Importiere…' : `${importPreview.created + importPreview.reactivated} Benutzer importieren`}
                </button>
              )}
            </div>
          </div>
        </Modal>
      )}

      {/* Edit User Modal */}
      {editUser && (
        <Modal title={`Mitarbeiter bearbeiten – ${editUser.full_name}`} onClose={() => setEditUser(null)}>
          <div className='space-y-3'>
            <label className='block'>
              <span className='text-xs font-medium text-gray-700'>Rolle</span>
              <select value={editRole} onChange={e => setEditRole(e.target.value)} className={inputClass}>
                {ROLES.map(r => <option key={r} value={r}>{ROLE_LABELS[r] ?? r}</option>)}
              </select>
              {ROLE_DESCRIPTIONS[editRole] && (
                <p className='mt-1.5 text-xs text-gray-500 bg-gray-50 border border-gray-100 rounded-lg px-3 py-2 leading-relaxed'>
                  {ROLE_DESCRIPTIONS[editRole]}
                </p>
              )}
            </label>
            <div>
              <label className='block text-xs font-medium text-gray-700 mb-1'>Arbeitszeitmodell</label>
              <select
                value={editScheduleId ?? ''}
                onChange={e => setEditScheduleId(e.target.value || null)}
                className={inputClass}
              >
                <option value=''>— Kein Modell zugewiesen —</option>
                {workSchedules.map(s => (
                  <option key={s.id} value={s.id}>
                    {s.name} ({weeklyHours(s)}h/Woche)
                  </option>
                ))}
              </select>
              {workSchedules.length === 0 && (
                <p className='mt-1 text-xs text-gray-400'>Noch keine Arbeitszeitmodelle angelegt.</p>
              )}
            </div>
            <div className='grid grid-cols-2 gap-3'>
              <div>
                <label className='block text-xs font-medium text-gray-700 mb-1'>Eintrittsdatum</label>
                <input type='date' value={editEntryDate} onChange={e => setEditEntryDate(e.target.value)} className={inputClass} />
              </div>
              <div>
                <label className='block text-xs font-medium text-gray-700 mb-1'>Austrittsdatum</label>
                <input type='date' value={editExitDate} onChange={e => setEditExitDate(e.target.value)} className={inputClass} />
              </div>
              <p className='col-span-2 -mt-1 text-xs text-gray-400'>Basis für anteilige Urlaubsberechnung (Zwölftel-Regel).</p>
            </div>
            <div>
              <label className='block text-xs font-medium text-gray-700 mb-1'>
                Kürzel
                <span className='ml-1 font-normal text-gray-400'>(für CalDAV-Kalender, Platzhalter $kuerzel)</span>
              </label>
              <input
                type='text'
                value={editKuerzel}
                onChange={e => setEditKuerzel(e.target.value)}
                placeholder={`${editUser?.first_name?.[0] ?? ''}${editUser?.last_name?.[0] ?? ''}`}
                maxLength={20}
                className={inputClass}
              />
              <p className='mt-1 text-xs text-gray-400'>
                Frei wählbar, z.B. "PP" oder "PatP". Leer = Initialen werden automatisch verwendet.
              </p>
            </div>
            <div>
              <label className='block text-xs font-medium text-gray-700 mb-1'>
                Personalnummer
                <span className='ml-1 font-normal text-gray-400'>(nur Ziffern, eindeutig pro Firma)</span>
              </label>
              <div className='flex gap-2 items-stretch'>
                <input
                  type='text'
                  inputMode='numeric'
                  value={editPersonnelNr}
                  onChange={e => {
                    const v = e.target.value.replace(/[^0-9]/g, '')
                    setEditPersonnelNr(v)
                    checkPersonnelNumber(v, editUser?.id)
                  }}
                  className={inputClass}
                  maxLength={50}
                />
                <button
                  type='button'
                  onClick={() => suggestPersonnelNumber('edit')}
                  className='px-3 py-2 text-xs font-medium text-blue-600 border border-blue-200 rounded-lg hover:bg-blue-50 whitespace-nowrap'
                >
                  Vorschlagen
                </button>
              </div>
              {editPersonnelNr && editPersonnelNr !== (editUser?.personnel_number ?? '') && (
                <p className={`mt-1 text-xs ${
                  personnelCheck === 'taken' ? 'text-red-600' :
                  personnelCheck === 'invalid' ? 'text-red-600' :
                  personnelCheck === 'free' ? 'text-green-600' :
                  'text-gray-400'
                }`}>
                  {personnelCheck === 'checking' && 'Prüfe Verfügbarkeit…'}
                  {personnelCheck === 'free' && '✓ Personalnr. frei'}
                  {personnelCheck === 'taken' && '✗ Personalnr. bereits vergeben'}
                  {personnelCheck === 'invalid' && 'Nur Ziffern erlaubt'}
                </p>
              )}
              {editUser?.personnel_number && (
                <p className='mt-1 text-xs text-gray-400'>
                  Aktuelle Nr.: {editUser.personnel_number} (bleibt nach Deaktivierung reserviert)
                </p>
              )}
            </div>
            <div className='border-t border-gray-100 pt-3'>
              <label className='flex items-center gap-3 cursor-pointer select-none'>
                <input
                  type='checkbox'
                  checked={editCanManual}
                  onChange={e => setEditCanManual(e.target.checked)}
                  className='w-4 h-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500'
                />
                <div>
                  <span className='text-sm font-medium text-gray-800'>Manuelle Zeiterfassung erlaubt</span>
                  <p className='text-xs text-gray-400 mt-0.5'>Mitarbeiter kann eigene Zeiteinträge manuell anlegen (nicht nur stempeln).</p>
                </div>
              </label>
            </div>
            <div className='flex justify-end gap-2 pt-2'>
              <button onClick={() => setEditUser(null)} className='px-4 py-2 text-sm text-gray-600 border border-gray-300 rounded-lg hover:bg-gray-50'>Abbrechen</button>
              <button onClick={handleEditRole} disabled={editLoading} className='px-4 py-2 text-sm font-semibold text-white bg-blue-600 rounded-lg hover:bg-blue-700 disabled:opacity-50'>
                {editLoading ? 'Speichere…' : 'Speichern'}
              </button>
            </div>
          </div>
        </Modal>
      )}
    </Layout>
  )
}

