'use client'

import React, { useState, useEffect, useCallback, useRef } from 'react'

// =============================================================================
// TYPES
// =============================================================================

interface AssignmentOverview {
  id: string
  dsb_user_id: string
  tenant_id: string
  tenant_name: string
  tenant_slug: string
  status: string
  contract_start: string
  contract_end: string | null
  monthly_hours_budget: number
  notes: string
  compliance_score: number
  hours_this_month: number
  hours_budget: number
  open_task_count: number
  urgent_task_count: number
  next_deadline: string | null
  created_at: string
  updated_at: string
}

interface DSBDashboard {
  assignments: AssignmentOverview[]
  total_assignments: number
  active_assignments: number
  total_hours_this_month: number
  open_tasks: number
  urgent_tasks: number
  generated_at: string
}

interface HourEntry {
  id: string
  assignment_id: string
  date: string
  hours: number
  category: string
  description: string
  billable: boolean
  created_at: string
}

interface Task {
  id: string
  assignment_id: string
  title: string
  description: string
  category: string
  priority: string
  status: string
  due_date: string | null
  completed_at: string | null
  created_at: string
  updated_at: string
}

interface Communication {
  id: string
  assignment_id: string
  direction: string
  channel: string
  subject: string
  content: string
  participants: string
  created_at: string
}

interface HoursSummary {
  total_hours: number
  billable_hours: number
  by_category: Record<string, number>
  period: string
}

// =============================================================================
// CONSTANTS
// =============================================================================

const DSB_USER_ID = '00000000-0000-0000-0000-000000000001'

const TASK_CATEGORIES = [
  'DSFA-Pruefung',
  'Betroffenenanfrage',
  'Vorfall-Pruefung',
  'Audit-Vorbereitung',
  'Richtlinien-Pruefung',
  'Schulung',
  'Beratung',
  'Sonstiges',
]

const HOUR_CATEGORIES = [
  'DSFA-Pruefung',
  'Beratung',
  'Audit',
  'Schulung',
  'Vorfallreaktion',
  'Dokumentation',
  'Besprechung',
  'Sonstiges',
]

const COMM_CHANNELS = ['E-Mail', 'Telefon', 'Besprechung', 'Portal', 'Brief']

const PRIORITY_LABELS: Record<string, string> = {
  urgent: 'Dringend',
  high: 'Hoch',
  medium: 'Mittel',
  low: 'Niedrig',
}

const PRIORITY_COLORS: Record<string, string> = {
  urgent: 'bg-red-100 text-red-700 border-red-200',
  high: 'bg-orange-100 text-orange-700 border-orange-200',
  medium: 'bg-blue-100 text-blue-700 border-blue-200',
  low: 'bg-gray-100 text-gray-500 border-gray-200',
}

const TASK_STATUS_LABELS: Record<string, string> = {
  open: 'Offen',
  in_progress: 'In Bearbeitung',
  waiting: 'Wartend',
  completed: 'Erledigt',
  cancelled: 'Abgebrochen',
}

const TASK_STATUS_COLORS: Record<string, string> = {
  open: 'bg-blue-100 text-blue-700',
  in_progress: 'bg-yellow-100 text-yellow-700',
  waiting: 'bg-orange-100 text-orange-700',
  completed: 'bg-green-100 text-green-700',
  cancelled: 'bg-gray-100 text-gray-500',
}

const ASSIGNMENT_STATUS_COLORS: Record<string, string> = {
  active: 'bg-green-100 text-green-700 border-green-300',
  paused: 'bg-yellow-100 text-yellow-700 border-yellow-300',
  terminated: 'bg-red-100 text-red-700 border-red-300',
}

const ASSIGNMENT_STATUS_LABELS: Record<string, string> = {
  active: 'Aktiv',
  paused: 'Pausiert',
  terminated: 'Beendet',
}

// =============================================================================
// API HELPERS
// =============================================================================

async function apiFetch<T>(url: string, options?: RequestInit): Promise<T> {
  const res = await fetch(url, {
    ...options,
    headers: {
      'Content-Type': 'application/json',
      'X-User-ID': DSB_USER_ID,
      ...(options?.headers || {}),
    },
  })
  if (!res.ok) {
    const text = await res.text().catch(() => '')
    throw new Error(`API Error ${res.status}: ${text || res.statusText}`)
  }
  return res.json()
}

// =============================================================================
// TOAST COMPONENT
// =============================================================================

interface ToastMessage {
  id: number
  message: string
  type: 'success' | 'error'
}

let toastIdCounter = 0

function useToast() {
  const [toasts, setToasts] = useState<ToastMessage[]>([])

  const addToast = useCallback((message: string, type: 'success' | 'error' = 'success') => {
    const id = ++toastIdCounter
    setToasts((prev) => [...prev, { id, message, type }])
    setTimeout(() => {
      setToasts((prev) => prev.filter((t) => t.id !== id))
    }, 3500)
  }, [])

  return { toasts, addToast }
}

function ToastContainer({ toasts }: { toasts: ToastMessage[] }) {
  if (toasts.length === 0) return null
  return (
    <div className="fixed top-4 right-4 z-[100] flex flex-col gap-2">
      {toasts.map((t) => (
        <div
          key={t.id}
          className={`px-5 py-3 rounded-lg shadow-lg text-sm font-medium text-white transition-all animate-slide-in ${
            t.type === 'success' ? 'bg-green-600' : 'bg-red-600'
          }`}
        >
          {t.message}
        </div>
      ))}
    </div>
  )
}

// =============================================================================
// LOADING SKELETON
// =============================================================================

function Skeleton({ className = '' }: { className?: string }) {
  return <div className={`animate-pulse bg-gray-200 rounded ${className}`} />
}

function DashboardSkeleton() {
  return (
    <div className="space-y-6">
      <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
        {Array.from({ length: 4 }).map((_, i) => (
          <Skeleton key={i} className="h-28 rounded-xl" />
        ))}
      </div>
      <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6">
        {Array.from({ length: 3 }).map((_, i) => (
          <Skeleton key={i} className="h-64 rounded-xl" />
        ))}
      </div>
    </div>
  )
}

// =============================================================================
// MODAL COMPONENT
// =============================================================================

function Modal({
  open,
  onClose,
  title,
  children,
  maxWidth = 'max-w-lg',
}: {
  open: boolean
  onClose: () => void
  title: string
  children: React.ReactNode
  maxWidth?: string
}) {
  const overlayRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    if (!open) return
    const handleEsc = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose()
    }
    document.addEventListener('keydown', handleEsc)
    return () => document.removeEventListener('keydown', handleEsc)
  }, [open, onClose])

  if (!open) return null

  return (
    <div
      ref={overlayRef}
      className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm"
      onClick={(e) => {
        if (e.target === overlayRef.current) onClose()
      }}
    >
      <div className={`bg-white rounded-2xl shadow-2xl w-full ${maxWidth} mx-4 overflow-hidden`}>
        <div className="flex items-center justify-between px-6 py-4 border-b border-gray-200 bg-purple-50">
          <h3 className="text-lg font-semibold text-purple-900">{title}</h3>
          <button
            onClick={onClose}
            className="p-1 rounded-lg hover:bg-purple-100 transition-colors text-purple-600"
          >
            <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
            </svg>
          </button>
        </div>
        <div className="px-6 py-4 max-h-[70vh] overflow-y-auto">{children}</div>
      </div>
    </div>
  )
}

// =============================================================================
// STAT CARD
// =============================================================================

function StatCard({
  title,
  value,
  icon,
  accent = false,
}: {
  title: string
  value: string | number
  icon: React.ReactNode
  accent?: boolean
}) {
  return (
    <div
      className={`rounded-xl border p-5 transition-all ${
        accent
          ? 'bg-red-50 border-red-200'
          : 'bg-white border-gray-200 hover:border-purple-300'
      }`}
    >
      <div className="flex items-center gap-3">
        <div
          className={`w-10 h-10 rounded-lg flex items-center justify-center ${
            accent ? 'bg-red-100 text-red-600' : 'bg-purple-100 text-purple-600'
          }`}
        >
          {icon}
        </div>
        <div>
          <p className="text-sm text-gray-500">{title}</p>
          <p className={`text-2xl font-bold ${accent ? 'text-red-700' : 'text-gray-900'}`}>
            {value}
          </p>
        </div>
      </div>
    </div>
  )
}

// =============================================================================
// COMPLIANCE PROGRESS BAR
// =============================================================================

function ComplianceBar({ score }: { score: number }) {
  const color =
    score < 40 ? 'bg-red-500' : score < 70 ? 'bg-yellow-500' : 'bg-green-500'
  const textColor =
    score < 40 ? 'text-red-700' : score < 70 ? 'text-yellow-700' : 'text-green-700'
  return (
    <div className="flex items-center gap-2">
      <div className="flex-1 h-2.5 bg-gray-100 rounded-full overflow-hidden">
        <div
          className={`h-full rounded-full transition-all ${color}`}
          style={{ width: `${Math.min(score, 100)}%` }}
        />
      </div>
      <span className={`text-xs font-semibold min-w-[36px] text-right ${textColor}`}>
        {score}%
      </span>
    </div>
  )
}

// =============================================================================
// HOURS PROGRESS BAR
// =============================================================================

function HoursBar({ used, budget }: { used: number; budget: number }) {
  const pct = budget > 0 ? Math.min((used / budget) * 100, 100) : 0
  const over = used > budget
  return (
    <div className="flex items-center gap-2">
      <div className="flex-1 h-2.5 bg-gray-100 rounded-full overflow-hidden">
        <div
          className={`h-full rounded-full transition-all ${over ? 'bg-red-500' : 'bg-purple-500'}`}
          style={{ width: `${pct}%` }}
        />
      </div>
      <span className={`text-xs font-medium min-w-[60px] text-right ${over ? 'text-red-600' : 'text-gray-600'}`}>
        {used}h / {budget}h
      </span>
    </div>
  )
}

// =============================================================================
// BADGE
// =============================================================================

function Badge({ label, className = '' }: { label: string; className?: string }) {
  return (
    <span className={`inline-flex items-center px-2 py-0.5 text-xs font-medium rounded-full border ${className}`}>
      {label}
    </span>
  )
}

// =============================================================================
// FORM COMPONENTS
// =============================================================================

function FormLabel({ children, htmlFor }: { children: React.ReactNode; htmlFor?: string }) {
  return (
    <label htmlFor={htmlFor} className="block text-sm font-medium text-gray-700 mb-1">
      {children}
    </label>
  )
}

function FormInput({
  id,
  type = 'text',
  value,
  onChange,
  placeholder,
  required,
  min,
  max,
  step,
}: {
  id?: string
  type?: string
  value: string | number
  onChange: (val: string) => void
  placeholder?: string
  required?: boolean
  min?: string | number
  max?: string | number
  step?: string | number
}) {
  return (
    <input
      id={id}
      type={type}
      value={value}
      onChange={(e) => onChange(e.target.value)}
      placeholder={placeholder}
      required={required}
      min={min}
      max={max}
      step={step}
      className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-purple-500"
    />
  )
}

function FormTextarea({
  id,
  value,
  onChange,
  placeholder,
  rows = 3,
}: {
  id?: string
  value: string
  onChange: (val: string) => void
  placeholder?: string
  rows?: number
}) {
  return (
    <textarea
      id={id}
      value={value}
      onChange={(e) => onChange(e.target.value)}
      placeholder={placeholder}
      rows={rows}
      className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-purple-500 resize-none"
    />
  )
}

function FormSelect({
  id,
  value,
  onChange,
  options,
  placeholder,
}: {
  id?: string
  value: string
  onChange: (val: string) => void
  options: { value: string; label: string }[]
  placeholder?: string
}) {
  return (
    <select
      id={id}
      value={value}
      onChange={(e) => onChange(e.target.value)}
      className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-purple-500 bg-white"
    >
      {placeholder && (
        <option value="" disabled>
          {placeholder}
        </option>
      )}
      {options.map((o) => (
        <option key={o.value} value={o.value}>
          {o.label}
        </option>
      ))}
    </select>
  )
}

function PrimaryButton({
  onClick,
  disabled,
  children,
  type = 'button',
  className = '',
}: {
  onClick?: () => void
  disabled?: boolean
  children: React.ReactNode
  type?: 'button' | 'submit'
  className?: string
}) {
  return (
    <button
      type={type}
      onClick={onClick}
      disabled={disabled}
      className={`px-4 py-2 rounded-lg bg-purple-600 text-white text-sm font-medium hover:bg-purple-700 focus:ring-2 focus:ring-purple-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors ${className}`}
    >
      {children}
    </button>
  )
}

function SecondaryButton({
  onClick,
  disabled,
  children,
  type = 'button',
  className = '',
}: {
  onClick?: () => void
  disabled?: boolean
  children: React.ReactNode
  type?: 'button' | 'submit'
  className?: string
}) {
  return (
    <button
      type={type}
      onClick={onClick}
      disabled={disabled}
      className={`px-4 py-2 rounded-lg border border-gray-300 text-gray-700 text-sm font-medium hover:bg-gray-50 focus:ring-2 focus:ring-purple-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors ${className}`}
    >
      {children}
    </button>
  )
}

// =============================================================================
// ERROR STATE
// =============================================================================

function ErrorState({ message, onRetry }: { message: string; onRetry: () => void }) {
  return (
    <div className="flex flex-col items-center justify-center py-16 text-center">
      <div className="w-16 h-16 rounded-full bg-red-100 flex items-center justify-center mb-4">
        <svg className="w-8 h-8 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path
            strokeLinecap="round"
            strokeLinejoin="round"
            strokeWidth={2}
            d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z"
          />
        </svg>
      </div>
      <p className="text-gray-700 font-medium mb-1">Fehler beim Laden</p>
      <p className="text-sm text-gray-500 mb-4 max-w-md">{message}</p>
      <PrimaryButton onClick={onRetry}>Erneut versuchen</PrimaryButton>
    </div>
  )
}

// =============================================================================
// EMPTY STATE
// =============================================================================

function EmptyState({ icon, title, description }: { icon: React.ReactNode; title: string; description: string }) {
  return (
    <div className="flex flex-col items-center justify-center py-12 text-center">
      <div className="w-14 h-14 rounded-full bg-purple-50 flex items-center justify-center mb-3 text-purple-400">
        {icon}
      </div>
      <p className="text-gray-700 font-medium">{title}</p>
      <p className="text-sm text-gray-400 mt-1">{description}</p>
    </div>
  )
}

// =============================================================================
// ICONS (inline SVGs)
// =============================================================================

function IconUsers({ className = 'w-5 h-5' }: { className?: string }) {
  return (
    <svg className={className} fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
    </svg>
  )
}

function IconClock({ className = 'w-5 h-5' }: { className?: string }) {
  return (
    <svg className={className} fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
    </svg>
  )
}

function IconTask({ className = 'w-5 h-5' }: { className?: string }) {
  return (
    <svg className={className} fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4" />
    </svg>
  )
}

function IconAlert({ className = 'w-5 h-5' }: { className?: string }) {
  return (
    <svg className={className} fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z" />
    </svg>
  )
}

function IconBack({ className = 'w-5 h-5' }: { className?: string }) {
  return (
    <svg className={className} fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" />
    </svg>
  )
}

function IconPlus({ className = 'w-4 h-4' }: { className?: string }) {
  return (
    <svg className={className} fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
    </svg>
  )
}

function IconCheck({ className = 'w-4 h-4' }: { className?: string }) {
  return (
    <svg className={className} fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
    </svg>
  )
}

function IconMail({ className = 'w-5 h-5' }: { className?: string }) {
  return (
    <svg className={className} fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
    </svg>
  )
}

function IconSettings({ className = 'w-5 h-5' }: { className?: string }) {
  return (
    <svg className={className} fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.066 2.573c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.573 1.066c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.066-2.573c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
    </svg>
  )
}

function IconRefresh({ className = 'w-4 h-4' }: { className?: string }) {
  return (
    <svg className={className} fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
    </svg>
  )
}

function IconInbound({ className = 'w-4 h-4' }: { className?: string }) {
  return (
    <svg className={className} fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11 19l-7-7 7-7m8 14l-7-7 7-7" />
    </svg>
  )
}

function IconOutbound({ className = 'w-4 h-4' }: { className?: string }) {
  return (
    <svg className={className} fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 5l7 7-7 7M5 5l7 7-7 7" />
    </svg>
  )
}

function IconShield({ className = 'w-6 h-6' }: { className?: string }) {
  return (
    <svg className={className} fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
    </svg>
  )
}

function IconCalendar({ className = 'w-4 h-4' }: { className?: string }) {
  return (
    <svg className={className} fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
    </svg>
  )
}

// =============================================================================
// DATE HELPERS
// =============================================================================

function formatDate(dateStr: string | null): string {
  if (!dateStr) return '-'
  try {
    return new Date(dateStr).toLocaleDateString('de-DE', {
      day: '2-digit',
      month: '2-digit',
      year: 'numeric',
    })
  } catch {
    return dateStr
  }
}

function formatDateTime(dateStr: string | null): string {
  if (!dateStr) return '-'
  try {
    return new Date(dateStr).toLocaleDateString('de-DE', {
      day: '2-digit',
      month: '2-digit',
      year: 'numeric',
      hour: '2-digit',
      minute: '2-digit',
    })
  } catch {
    return dateStr
  }
}

function currentMonth(): string {
  const d = new Date()
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`
}

function monthLabel(ym: string): string {
  const [y, m] = ym.split('-')
  const months = [
    'Januar', 'Februar', 'Maerz', 'April', 'Mai', 'Juni',
    'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember',
  ]
  return `${months[parseInt(m, 10) - 1]} ${y}`
}

function prevMonth(ym: string): string {
  const [y, m] = ym.split('-').map(Number)
  if (m === 1) return `${y - 1}-12`
  return `${y}-${String(m - 1).padStart(2, '0')}`
}

function nextMonth(ym: string): string {
  const [y, m] = ym.split('-').map(Number)
  if (m === 12) return `${y + 1}-01`
  return `${y}-${String(m + 1).padStart(2, '0')}`
}

// =============================================================================
// MANDANT CARD (Dashboard)
// =============================================================================

function MandantCard({
  assignment,
  onClick,
}: {
  assignment: AssignmentOverview
  onClick: () => void
}) {
  return (
    <div
      onClick={onClick}
      className="bg-white rounded-xl border border-gray-200 p-5 hover:border-purple-400 hover:shadow-lg cursor-pointer transition-all group"
    >
      {/* Header */}
      <div className="flex items-start justify-between mb-3">
        <div className="min-w-0">
          <h3 className="font-semibold text-gray-900 truncate group-hover:text-purple-700 transition-colors">
            {assignment.tenant_name}
          </h3>
          <p className="text-xs text-gray-400 font-mono">{assignment.tenant_slug}</p>
        </div>
        <Badge
          label={ASSIGNMENT_STATUS_LABELS[assignment.status] || assignment.status}
          className={ASSIGNMENT_STATUS_COLORS[assignment.status] || 'bg-gray-100 text-gray-600'}
        />
      </div>

      {/* Compliance Score */}
      <div className="mb-3">
        <div className="flex items-center justify-between text-xs text-gray-500 mb-1">
          <span>Compliance-Score</span>
        </div>
        <ComplianceBar score={assignment.compliance_score} />
      </div>

      {/* Hours */}
      <div className="mb-3">
        <div className="flex items-center justify-between text-xs text-gray-500 mb-1">
          <span>Stunden diesen Monat</span>
        </div>
        <HoursBar used={assignment.hours_this_month} budget={assignment.hours_budget} />
      </div>

      {/* Footer: Tasks */}
      <div className="flex items-center justify-between pt-3 border-t border-gray-100">
        <div className="flex items-center gap-1 text-sm text-gray-600">
          <IconTask className="w-4 h-4" />
          <span>{assignment.open_task_count} offene Aufgaben</span>
        </div>
        {assignment.urgent_task_count > 0 && (
          <Badge
            label={`${assignment.urgent_task_count} dringend`}
            className="bg-red-100 text-red-700 border-red-200"
          />
        )}
      </div>

      {/* Next deadline */}
      {assignment.next_deadline && (
        <div className="flex items-center gap-1 mt-2 text-xs text-gray-400">
          <IconCalendar className="w-3 h-3" />
          <span>Naechste Frist: {formatDate(assignment.next_deadline)}</span>
        </div>
      )}
    </div>
  )
}

// =============================================================================
// AUFGABEN TAB
// =============================================================================

function AufgabenTab({
  assignmentId,
  addToast,
}: {
  assignmentId: string
  addToast: (msg: string, type?: 'success' | 'error') => void
}) {
  const [tasks, setTasks] = useState<Task[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState('')
  const [statusFilter, setStatusFilter] = useState<string>('all')
  const [showModal, setShowModal] = useState(false)
  const [saving, setSaving] = useState(false)

  // New task form
  const [newTitle, setNewTitle] = useState('')
  const [newDesc, setNewDesc] = useState('')
  const [newCategory, setNewCategory] = useState(TASK_CATEGORIES[0])
  const [newPriority, setNewPriority] = useState('medium')
  const [newDueDate, setNewDueDate] = useState('')

  const fetchTasks = useCallback(async () => {
    setLoading(true)
    setError('')
    try {
      const params = statusFilter !== 'all' ? `?status=${statusFilter}` : ''
      const data = await apiFetch<Task[]>(
        `/api/sdk/v1/dsb/assignments/${assignmentId}/tasks${params}`
      )
      setTasks(data)
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : 'Fehler beim Laden der Aufgaben')
    } finally {
      setLoading(false)
    }
  }, [assignmentId, statusFilter])

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

  const handleCreateTask = async (e: React.FormEvent) => {
    e.preventDefault()
    setSaving(true)
    try {
      await apiFetch<Task>(`/api/sdk/v1/dsb/assignments/${assignmentId}/tasks`, {
        method: 'POST',
        body: JSON.stringify({
          title: newTitle,
          description: newDesc,
          category: newCategory,
          priority: newPriority,
          due_date: newDueDate || null,
        }),
      })
      addToast('Aufgabe erstellt')
      setShowModal(false)
      setNewTitle('')
      setNewDesc('')
      setNewCategory(TASK_CATEGORIES[0])
      setNewPriority('medium')
      setNewDueDate('')
      fetchTasks()
    } catch (e: unknown) {
      addToast(e instanceof Error ? e.message : 'Fehler', 'error')
    } finally {
      setSaving(false)
    }
  }

  const handleCompleteTask = async (taskId: string) => {
    try {
      await apiFetch(`/api/sdk/v1/dsb/tasks/${taskId}/complete`, { method: 'POST' })
      addToast('Aufgabe abgeschlossen')
      fetchTasks()
    } catch (e: unknown) {
      addToast(e instanceof Error ? e.message : 'Fehler', 'error')
    }
  }

  const statusFilters = [
    { value: 'all', label: 'Alle' },
    { value: 'open', label: 'Offen' },
    { value: 'in_progress', label: 'In Bearbeitung' },
    { value: 'completed', label: 'Erledigt' },
  ]

  return (
    <div>
      {/* Toolbar */}
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 mb-4">
        <div className="flex flex-wrap gap-1">
          {statusFilters.map((f) => (
            <button
              key={f.value}
              onClick={() => setStatusFilter(f.value)}
              className={`px-3 py-1.5 rounded-lg text-xs font-medium transition-colors ${
                statusFilter === f.value
                  ? 'bg-purple-600 text-white'
                  : 'bg-gray-100 text-gray-600 hover:bg-gray-200'
              }`}
            >
              {f.label}
            </button>
          ))}
        </div>
        <PrimaryButton onClick={() => setShowModal(true)} className="flex items-center gap-1.5">
          <IconPlus />
          Neue Aufgabe
        </PrimaryButton>
      </div>

      {/* Content */}
      {loading ? (
        <div className="space-y-3">
          {Array.from({ length: 4 }).map((_, i) => (
            <Skeleton key={i} className="h-16 rounded-lg" />
          ))}
        </div>
      ) : error ? (
        <ErrorState message={error} onRetry={fetchTasks} />
      ) : tasks.length === 0 ? (
        <EmptyState
          icon={<IconTask className="w-7 h-7" />}
          title="Keine Aufgaben"
          description="Erstellen Sie eine neue Aufgabe um zu beginnen."
        />
      ) : (
        <div className="space-y-2">
          {tasks.map((task) => (
            <div
              key={task.id}
              className="bg-white border border-gray-200 rounded-lg p-4 hover:border-purple-300 transition-colors"
            >
              <div className="flex items-start justify-between gap-3">
                <div className="flex-1 min-w-0">
                  <div className="flex items-center gap-2 flex-wrap">
                    <h4
                      className={`font-medium ${
                        task.status === 'completed' ? 'line-through text-gray-400' : 'text-gray-900'
                      }`}
                    >
                      {task.title}
                    </h4>
                    <Badge
                      label={task.category}
                      className="bg-purple-50 text-purple-600 border-purple-200"
                    />
                    <Badge
                      label={PRIORITY_LABELS[task.priority] || task.priority}
                      className={PRIORITY_COLORS[task.priority] || 'bg-gray-100 text-gray-500'}
                    />
                    <Badge
                      label={TASK_STATUS_LABELS[task.status] || task.status}
                      className={TASK_STATUS_COLORS[task.status] || 'bg-gray-100 text-gray-500'}
                    />
                  </div>
                  {task.description && (
                    <p className="text-sm text-gray-500 mt-1 line-clamp-2">{task.description}</p>
                  )}
                  <div className="flex items-center gap-3 mt-2 text-xs text-gray-400">
                    {task.due_date && (
                      <span className="flex items-center gap-1">
                        <IconCalendar className="w-3 h-3" />
                        Frist: {formatDate(task.due_date)}
                      </span>
                    )}
                    <span>Erstellt: {formatDate(task.created_at)}</span>
                  </div>
                </div>
                {task.status !== 'completed' && task.status !== 'cancelled' && (
                  <button
                    onClick={() => handleCompleteTask(task.id)}
                    title="Aufgabe abschliessen"
                    className="p-2 rounded-lg text-green-600 hover:bg-green-50 transition-colors flex-shrink-0"
                  >
                    <IconCheck className="w-5 h-5" />
                  </button>
                )}
              </div>
            </div>
          ))}
        </div>
      )}

      {/* Create task modal */}
      <Modal open={showModal} onClose={() => setShowModal(false)} title="Neue Aufgabe erstellen">
        <form onSubmit={handleCreateTask} className="space-y-4">
          <div>
            <FormLabel htmlFor="task-title">Titel *</FormLabel>
            <FormInput
              id="task-title"
              value={newTitle}
              onChange={setNewTitle}
              placeholder="Aufgabentitel"
              required
            />
          </div>
          <div>
            <FormLabel htmlFor="task-desc">Beschreibung</FormLabel>
            <FormTextarea
              id="task-desc"
              value={newDesc}
              onChange={setNewDesc}
              placeholder="Beschreibung der Aufgabe..."
            />
          </div>
          <div className="grid grid-cols-2 gap-4">
            <div>
              <FormLabel htmlFor="task-cat">Kategorie</FormLabel>
              <FormSelect
                id="task-cat"
                value={newCategory}
                onChange={setNewCategory}
                options={TASK_CATEGORIES.map((c) => ({ value: c, label: c }))}
              />
            </div>
            <div>
              <FormLabel htmlFor="task-prio">Prioritaet</FormLabel>
              <FormSelect
                id="task-prio"
                value={newPriority}
                onChange={setNewPriority}
                options={[
                  { value: 'urgent', label: 'Dringend' },
                  { value: 'high', label: 'Hoch' },
                  { value: 'medium', label: 'Mittel' },
                  { value: 'low', label: 'Niedrig' },
                ]}
              />
            </div>
          </div>
          <div>
            <FormLabel htmlFor="task-due">Faelligkeitsdatum</FormLabel>
            <FormInput id="task-due" type="date" value={newDueDate} onChange={setNewDueDate} />
          </div>
          <div className="flex justify-end gap-3 pt-2">
            <SecondaryButton onClick={() => setShowModal(false)}>Abbrechen</SecondaryButton>
            <PrimaryButton type="submit" disabled={saving || !newTitle.trim()}>
              {saving ? 'Erstelle...' : 'Aufgabe erstellen'}
            </PrimaryButton>
          </div>
        </form>
      </Modal>
    </div>
  )
}

// =============================================================================
// ZEITERFASSUNG TAB
// =============================================================================

function ZeiterfassungTab({
  assignmentId,
  monthlyBudget,
  addToast,
}: {
  assignmentId: string
  monthlyBudget: number
  addToast: (msg: string, type?: 'success' | 'error') => void
}) {
  const [hours, setHours] = useState<HourEntry[]>([])
  const [summary, setSummary] = useState<HoursSummary | null>(null)
  const [month, setMonth] = useState(currentMonth())
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState('')
  const [showModal, setShowModal] = useState(false)
  const [saving, setSaving] = useState(false)

  // Form
  const [formDate, setFormDate] = useState(new Date().toISOString().slice(0, 10))
  const [formHours, setFormHours] = useState('1')
  const [formCategory, setFormCategory] = useState(HOUR_CATEGORIES[0])
  const [formDesc, setFormDesc] = useState('')
  const [formBillable, setFormBillable] = useState(true)

  const fetchData = useCallback(async () => {
    setLoading(true)
    setError('')
    try {
      const [hoursData, summaryData] = await Promise.all([
        apiFetch<HourEntry[]>(
          `/api/sdk/v1/dsb/assignments/${assignmentId}/hours?month=${month}`
        ),
        apiFetch<HoursSummary>(
          `/api/sdk/v1/dsb/assignments/${assignmentId}/hours/summary?month=${month}`
        ),
      ])
      setHours(hoursData)
      setSummary(summaryData)
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : 'Fehler beim Laden der Zeiterfassung')
    } finally {
      setLoading(false)
    }
  }, [assignmentId, month])

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

  const handleLogHours = async (e: React.FormEvent) => {
    e.preventDefault()
    setSaving(true)
    try {
      await apiFetch(`/api/sdk/v1/dsb/assignments/${assignmentId}/hours`, {
        method: 'POST',
        body: JSON.stringify({
          date: formDate,
          hours: parseFloat(formHours),
          category: formCategory,
          description: formDesc,
          billable: formBillable,
        }),
      })
      addToast('Stunden erfasst')
      setShowModal(false)
      setFormDate(new Date().toISOString().slice(0, 10))
      setFormHours('1')
      setFormCategory(HOUR_CATEGORIES[0])
      setFormDesc('')
      setFormBillable(true)
      fetchData()
    } catch (e: unknown) {
      addToast(e instanceof Error ? e.message : 'Fehler', 'error')
    } finally {
      setSaving(false)
    }
  }

  // Calculate max category hours for bar sizing
  const maxCatHours = summary
    ? Math.max(...Object.values(summary.by_category), 1)
    : 1

  return (
    <div>
      {/* Toolbar */}
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 mb-4">
        <div className="flex items-center gap-2">
          <button
            onClick={() => setMonth(prevMonth(month))}
            className="p-2 rounded-lg hover:bg-gray-100 text-gray-500 transition-colors"
          >
            <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
            </svg>
          </button>
          <span className="text-sm font-medium text-gray-700 min-w-[140px] text-center">
            {monthLabel(month)}
          </span>
          <button
            onClick={() => setMonth(nextMonth(month))}
            className="p-2 rounded-lg hover:bg-gray-100 text-gray-500 transition-colors"
          >
            <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
            </svg>
          </button>
        </div>
        <PrimaryButton onClick={() => setShowModal(true)} className="flex items-center gap-1.5">
          <IconPlus />
          Stunden erfassen
        </PrimaryButton>
      </div>

      {loading ? (
        <div className="space-y-3">
          <Skeleton className="h-24 rounded-lg" />
          <Skeleton className="h-40 rounded-lg" />
        </div>
      ) : error ? (
        <ErrorState message={error} onRetry={fetchData} />
      ) : (
        <div className="space-y-6">
          {/* Summary cards */}
          {summary && (
            <div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
              <div className="bg-purple-50 rounded-xl p-4 border border-purple-200">
                <p className="text-xs text-purple-600 font-medium">Gesamt-Stunden</p>
                <p className="text-2xl font-bold text-purple-900 mt-1">{summary.total_hours}h</p>
                <div className="mt-2">
                  <HoursBar used={summary.total_hours} budget={monthlyBudget} />
                </div>
              </div>
              <div className="bg-green-50 rounded-xl p-4 border border-green-200">
                <p className="text-xs text-green-600 font-medium">Abrechnungsfaehig</p>
                <p className="text-2xl font-bold text-green-900 mt-1">{summary.billable_hours}h</p>
                <p className="text-xs text-green-500 mt-1">
                  {summary.total_hours > 0
                    ? `${Math.round((summary.billable_hours / summary.total_hours) * 100)}% der Gesamtstunden`
                    : 'Keine Stunden erfasst'}
                </p>
              </div>
              <div className="bg-gray-50 rounded-xl p-4 border border-gray-200">
                <p className="text-xs text-gray-500 font-medium">Budget verbleibend</p>
                <p className="text-2xl font-bold text-gray-900 mt-1">
                  {Math.max(monthlyBudget - summary.total_hours, 0)}h
                </p>
                <p className="text-xs text-gray-400 mt-1">
                  von {monthlyBudget}h Monatsbudget
                </p>
              </div>
            </div>
          )}

          {/* Hours by category */}
          {summary && Object.keys(summary.by_category).length > 0 && (
            <div className="bg-white border border-gray-200 rounded-xl p-5">
              <h4 className="text-sm font-semibold text-gray-700 mb-3">
                Stunden nach Kategorie
              </h4>
              <div className="space-y-2.5">
                {Object.entries(summary.by_category)
                  .sort(([, a], [, b]) => b - a)
                  .map(([cat, h]) => (
                    <div key={cat} className="flex items-center gap-3">
                      <span className="text-xs text-gray-500 min-w-[120px] truncate">{cat}</span>
                      <div className="flex-1 h-5 bg-gray-100 rounded-full overflow-hidden">
                        <div
                          className="h-full bg-purple-400 rounded-full transition-all"
                          style={{ width: `${(h / maxCatHours) * 100}%` }}
                        />
                      </div>
                      <span className="text-xs font-medium text-gray-700 min-w-[40px] text-right">
                        {h}h
                      </span>
                    </div>
                  ))}
              </div>
            </div>
          )}

          {/* Hours table */}
          {hours.length === 0 ? (
            <EmptyState
              icon={<IconClock className="w-7 h-7" />}
              title="Keine Stunden erfasst"
              description={`Fuer ${monthLabel(month)} wurden noch keine Stunden erfasst.`}
            />
          ) : (
            <div className="bg-white border border-gray-200 rounded-xl overflow-hidden">
              <div className="overflow-x-auto">
                <table className="w-full text-sm">
                  <thead>
                    <tr className="bg-gray-50 border-b border-gray-200">
                      <th className="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase">
                        Datum
                      </th>
                      <th className="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase">
                        Stunden
                      </th>
                      <th className="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase">
                        Kategorie
                      </th>
                      <th className="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase">
                        Beschreibung
                      </th>
                      <th className="px-4 py-3 text-left text-xs font-semibold text-gray-500 uppercase">
                        Abrechenbar
                      </th>
                    </tr>
                  </thead>
                  <tbody className="divide-y divide-gray-100">
                    {hours.map((entry) => (
                      <tr key={entry.id} className="hover:bg-gray-50 transition-colors">
                        <td className="px-4 py-3 text-gray-700 whitespace-nowrap">
                          {formatDate(entry.date)}
                        </td>
                        <td className="px-4 py-3 font-medium text-gray-900">{entry.hours}h</td>
                        <td className="px-4 py-3">
                          <Badge
                            label={entry.category}
                            className="bg-purple-50 text-purple-600 border-purple-200"
                          />
                        </td>
                        <td className="px-4 py-3 text-gray-600 max-w-xs truncate">
                          {entry.description || '-'}
                        </td>
                        <td className="px-4 py-3">
                          {entry.billable ? (
                            <span className="text-green-600 font-medium">Ja</span>
                          ) : (
                            <span className="text-gray-400">Nein</span>
                          )}
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </div>
          )}
        </div>
      )}

      {/* Log hours modal */}
      <Modal open={showModal} onClose={() => setShowModal(false)} title="Stunden erfassen">
        <form onSubmit={handleLogHours} className="space-y-4">
          <div className="grid grid-cols-2 gap-4">
            <div>
              <FormLabel htmlFor="h-date">Datum *</FormLabel>
              <FormInput id="h-date" type="date" value={formDate} onChange={setFormDate} required />
            </div>
            <div>
              <FormLabel htmlFor="h-hours">Stunden *</FormLabel>
              <FormInput
                id="h-hours"
                type="number"
                value={formHours}
                onChange={setFormHours}
                min={0.25}
                max={24}
                step={0.25}
                required
              />
            </div>
          </div>
          <div>
            <FormLabel htmlFor="h-cat">Kategorie</FormLabel>
            <FormSelect
              id="h-cat"
              value={formCategory}
              onChange={setFormCategory}
              options={HOUR_CATEGORIES.map((c) => ({ value: c, label: c }))}
            />
          </div>
          <div>
            <FormLabel htmlFor="h-desc">Beschreibung</FormLabel>
            <FormTextarea
              id="h-desc"
              value={formDesc}
              onChange={setFormDesc}
              placeholder="Was wurde gemacht..."
            />
          </div>
          <div className="flex items-center gap-2">
            <input
              id="h-billable"
              type="checkbox"
              checked={formBillable}
              onChange={(e) => setFormBillable(e.target.checked)}
              className="rounded border-gray-300 text-purple-600 focus:ring-purple-500"
            />
            <label htmlFor="h-billable" className="text-sm text-gray-700">
              Abrechnungsfaehig
            </label>
          </div>
          <div className="flex justify-end gap-3 pt-2">
            <SecondaryButton onClick={() => setShowModal(false)}>Abbrechen</SecondaryButton>
            <PrimaryButton type="submit" disabled={saving}>
              {saving ? 'Erfasse...' : 'Stunden erfassen'}
            </PrimaryButton>
          </div>
        </form>
      </Modal>
    </div>
  )
}

// =============================================================================
// KOMMUNIKATION TAB
// =============================================================================

function KommunikationTab({
  assignmentId,
  addToast,
}: {
  assignmentId: string
  addToast: (msg: string, type?: 'success' | 'error') => void
}) {
  const [comms, setComms] = useState<Communication[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState('')
  const [showModal, setShowModal] = useState(false)
  const [saving, setSaving] = useState(false)

  // Form
  const [formDirection, setFormDirection] = useState('outbound')
  const [formChannel, setFormChannel] = useState(COMM_CHANNELS[0])
  const [formSubject, setFormSubject] = useState('')
  const [formContent, setFormContent] = useState('')
  const [formParticipants, setFormParticipants] = useState('')

  const fetchComms = useCallback(async () => {
    setLoading(true)
    setError('')
    try {
      const data = await apiFetch<Communication[]>(
        `/api/sdk/v1/dsb/assignments/${assignmentId}/communications`
      )
      setComms(data)
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : 'Fehler beim Laden der Kommunikation')
    } finally {
      setLoading(false)
    }
  }, [assignmentId])

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

  const handleCreate = async (e: React.FormEvent) => {
    e.preventDefault()
    setSaving(true)
    try {
      await apiFetch(`/api/sdk/v1/dsb/assignments/${assignmentId}/communications`, {
        method: 'POST',
        body: JSON.stringify({
          direction: formDirection,
          channel: formChannel,
          subject: formSubject,
          content: formContent,
          participants: formParticipants,
        }),
      })
      addToast('Kommunikation erfasst')
      setShowModal(false)
      setFormDirection('outbound')
      setFormChannel(COMM_CHANNELS[0])
      setFormSubject('')
      setFormContent('')
      setFormParticipants('')
      fetchComms()
    } catch (e: unknown) {
      addToast(e instanceof Error ? e.message : 'Fehler', 'error')
    } finally {
      setSaving(false)
    }
  }

  const channelColors: Record<string, string> = {
    'E-Mail': 'bg-blue-100 text-blue-700 border-blue-200',
    'Telefon': 'bg-green-100 text-green-700 border-green-200',
    'Besprechung': 'bg-purple-100 text-purple-700 border-purple-200',
    'Portal': 'bg-indigo-100 text-indigo-700 border-indigo-200',
    'Brief': 'bg-orange-100 text-orange-700 border-orange-200',
  }

  return (
    <div>
      {/* Toolbar */}
      <div className="flex items-center justify-between mb-4">
        <p className="text-sm text-gray-500">Kommunikations-Protokoll</p>
        <PrimaryButton onClick={() => setShowModal(true)} className="flex items-center gap-1.5">
          <IconPlus />
          Kommunikation erfassen
        </PrimaryButton>
      </div>

      {loading ? (
        <div className="space-y-3">
          {Array.from({ length: 3 }).map((_, i) => (
            <Skeleton key={i} className="h-20 rounded-lg" />
          ))}
        </div>
      ) : error ? (
        <ErrorState message={error} onRetry={fetchComms} />
      ) : comms.length === 0 ? (
        <EmptyState
          icon={<IconMail className="w-7 h-7" />}
          title="Keine Kommunikation"
          description="Erfassen Sie die erste Kommunikation mit dem Mandanten."
        />
      ) : (
        <div className="space-y-3">
          {comms.map((comm) => (
            <div
              key={comm.id}
              className="bg-white border border-gray-200 rounded-xl p-4 hover:border-purple-200 transition-colors"
            >
              <div className="flex items-start gap-3">
                {/* Direction icon */}
                <div
                  className={`w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0 ${
                    comm.direction === 'inbound'
                      ? 'bg-blue-100 text-blue-600'
                      : 'bg-green-100 text-green-600'
                  }`}
                >
                  {comm.direction === 'inbound' ? (
                    <IconInbound className="w-4 h-4" />
                  ) : (
                    <IconOutbound className="w-4 h-4" />
                  )}
                </div>
                <div className="flex-1 min-w-0">
                  <div className="flex items-center gap-2 flex-wrap">
                    <span className="font-medium text-gray-900 text-sm">{comm.subject}</span>
                    <Badge
                      label={comm.channel}
                      className={channelColors[comm.channel] || 'bg-gray-100 text-gray-600 border-gray-200'}
                    />
                    <span className="text-xs text-gray-400">
                      {comm.direction === 'inbound' ? 'Eingehend' : 'Ausgehend'}
                    </span>
                  </div>
                  {comm.content && (
                    <p className="text-sm text-gray-500 mt-1 line-clamp-2">{comm.content}</p>
                  )}
                  <div className="flex items-center gap-3 mt-2 text-xs text-gray-400">
                    <span>{formatDateTime(comm.created_at)}</span>
                    {comm.participants && <span>Teilnehmer: {comm.participants}</span>}
                  </div>
                </div>
              </div>
            </div>
          ))}
        </div>
      )}

      {/* Create communication modal */}
      <Modal
        open={showModal}
        onClose={() => setShowModal(false)}
        title="Kommunikation erfassen"
      >
        <form onSubmit={handleCreate} className="space-y-4">
          <div className="grid grid-cols-2 gap-4">
            <div>
              <FormLabel htmlFor="comm-dir">Richtung</FormLabel>
              <FormSelect
                id="comm-dir"
                value={formDirection}
                onChange={setFormDirection}
                options={[
                  { value: 'outbound', label: 'Ausgehend' },
                  { value: 'inbound', label: 'Eingehend' },
                ]}
              />
            </div>
            <div>
              <FormLabel htmlFor="comm-ch">Kanal</FormLabel>
              <FormSelect
                id="comm-ch"
                value={formChannel}
                onChange={setFormChannel}
                options={COMM_CHANNELS.map((c) => ({ value: c, label: c }))}
              />
            </div>
          </div>
          <div>
            <FormLabel htmlFor="comm-subj">Betreff *</FormLabel>
            <FormInput
              id="comm-subj"
              value={formSubject}
              onChange={setFormSubject}
              placeholder="Betreff der Kommunikation"
              required
            />
          </div>
          <div>
            <FormLabel htmlFor="comm-content">Inhalt</FormLabel>
            <FormTextarea
              id="comm-content"
              value={formContent}
              onChange={setFormContent}
              placeholder="Inhalt / Zusammenfassung..."
              rows={4}
            />
          </div>
          <div>
            <FormLabel htmlFor="comm-parts">Teilnehmer</FormLabel>
            <FormInput
              id="comm-parts"
              value={formParticipants}
              onChange={setFormParticipants}
              placeholder="z.B. Herr Mueller, Frau Schmidt"
            />
          </div>
          <div className="flex justify-end gap-3 pt-2">
            <SecondaryButton onClick={() => setShowModal(false)}>Abbrechen</SecondaryButton>
            <PrimaryButton type="submit" disabled={saving || !formSubject.trim()}>
              {saving ? 'Speichere...' : 'Kommunikation erfassen'}
            </PrimaryButton>
          </div>
        </form>
      </Modal>
    </div>
  )
}

// =============================================================================
// EINSTELLUNGEN TAB
// =============================================================================

function EinstellungenTab({
  assignment,
  onUpdate,
  addToast,
}: {
  assignment: AssignmentOverview
  onUpdate: () => void
  addToast: (msg: string, type?: 'success' | 'error') => void
}) {
  const [status, setStatus] = useState(assignment.status)
  const [budget, setBudget] = useState(String(assignment.monthly_hours_budget))
  const [notes, setNotes] = useState(assignment.notes || '')
  const [contractStart, setContractStart] = useState(assignment.contract_start?.slice(0, 10) || '')
  const [contractEnd, setContractEnd] = useState(assignment.contract_end?.slice(0, 10) || '')
  const [saving, setSaving] = useState(false)

  const handleSave = async () => {
    setSaving(true)
    try {
      await apiFetch(`/api/sdk/v1/dsb/assignments/${assignment.id}`, {
        method: 'PUT',
        body: JSON.stringify({
          status,
          monthly_hours_budget: parseFloat(budget) || 0,
          notes,
          contract_start: contractStart || null,
          contract_end: contractEnd || null,
        }),
      })
      addToast('Einstellungen gespeichert')
      onUpdate()
    } catch (e: unknown) {
      addToast(e instanceof Error ? e.message : 'Fehler beim Speichern', 'error')
    } finally {
      setSaving(false)
    }
  }

  return (
    <div className="max-w-2xl space-y-6">
      {/* Status */}
      <div className="bg-white border border-gray-200 rounded-xl p-5">
        <h4 className="text-sm font-semibold text-gray-700 mb-3">Status</h4>
        <div className="flex gap-2">
          {(['active', 'paused', 'terminated'] as const).map((s) => (
            <button
              key={s}
              onClick={() => setStatus(s)}
              className={`px-4 py-2 rounded-lg text-sm font-medium border transition-colors ${
                status === s
                  ? s === 'active'
                    ? 'bg-green-100 text-green-700 border-green-300'
                    : s === 'paused'
                    ? 'bg-yellow-100 text-yellow-700 border-yellow-300'
                    : 'bg-red-100 text-red-700 border-red-300'
                  : 'bg-white text-gray-500 border-gray-200 hover:bg-gray-50'
              }`}
            >
              {ASSIGNMENT_STATUS_LABELS[s]}
            </button>
          ))}
        </div>
      </div>

      {/* Contract period */}
      <div className="bg-white border border-gray-200 rounded-xl p-5">
        <h4 className="text-sm font-semibold text-gray-700 mb-3">Vertragszeitraum</h4>
        <div className="grid grid-cols-2 gap-4">
          <div>
            <FormLabel htmlFor="s-start">Vertragsbeginn</FormLabel>
            <FormInput
              id="s-start"
              type="date"
              value={contractStart}
              onChange={setContractStart}
            />
          </div>
          <div>
            <FormLabel htmlFor="s-end">Vertragsende</FormLabel>
            <FormInput
              id="s-end"
              type="date"
              value={contractEnd}
              onChange={setContractEnd}
            />
          </div>
        </div>
      </div>

      {/* Budget */}
      <div className="bg-white border border-gray-200 rounded-xl p-5">
        <h4 className="text-sm font-semibold text-gray-700 mb-3">Monatliches Stundenbudget</h4>
        <div className="max-w-xs">
          <FormInput
            type="number"
            value={budget}
            onChange={setBudget}
            min={0}
            max={999}
            step={1}
          />
          <p className="text-xs text-gray-400 mt-1">Stunden pro Monat</p>
        </div>
      </div>

      {/* Notes */}
      <div className="bg-white border border-gray-200 rounded-xl p-5">
        <h4 className="text-sm font-semibold text-gray-700 mb-3">Anmerkungen</h4>
        <FormTextarea
          value={notes}
          onChange={setNotes}
          placeholder="Interne Anmerkungen zum Mandat..."
          rows={4}
        />
      </div>

      {/* Save */}
      <div className="flex justify-end">
        <PrimaryButton onClick={handleSave} disabled={saving}>
          {saving ? 'Speichere...' : 'Einstellungen speichern'}
        </PrimaryButton>
      </div>
    </div>
  )
}

// =============================================================================
// DETAIL VIEW
// =============================================================================

type DetailTab = 'aufgaben' | 'zeit' | 'kommunikation' | 'einstellungen'

function DetailView({
  assignment,
  onBack,
  onUpdate,
  addToast,
}: {
  assignment: AssignmentOverview
  onBack: () => void
  onUpdate: () => void
  addToast: (msg: string, type?: 'success' | 'error') => void
}) {
  const [activeTab, setActiveTab] = useState<DetailTab>('aufgaben')

  const tabs: { id: DetailTab; label: string; icon: React.ReactNode }[] = [
    { id: 'aufgaben', label: 'Aufgaben', icon: <IconTask className="w-4 h-4" /> },
    { id: 'zeit', label: 'Zeiterfassung', icon: <IconClock className="w-4 h-4" /> },
    { id: 'kommunikation', label: 'Kommunikation', icon: <IconMail className="w-4 h-4" /> },
    { id: 'einstellungen', label: 'Einstellungen', icon: <IconSettings className="w-4 h-4" /> },
  ]

  return (
    <div className="space-y-6">
      {/* Back + Header */}
      <div>
        <button
          onClick={onBack}
          className="flex items-center gap-2 text-sm text-purple-600 hover:text-purple-800 font-medium mb-4 transition-colors"
        >
          <IconBack className="w-4 h-4" />
          Zurueck zur Uebersicht
        </button>

        <div className="bg-white border border-gray-200 rounded-xl p-6">
          <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
            <div>
              <div className="flex items-center gap-3">
                <div className="w-10 h-10 rounded-lg bg-purple-100 flex items-center justify-center text-purple-600">
                  <IconShield className="w-5 h-5" />
                </div>
                <div>
                  <h2 className="text-xl font-bold text-gray-900">{assignment.tenant_name}</h2>
                  <p className="text-sm text-gray-400 font-mono">{assignment.tenant_slug}</p>
                </div>
              </div>
            </div>
            <div className="flex items-center gap-2">
              <Badge
                label={ASSIGNMENT_STATUS_LABELS[assignment.status] || assignment.status}
                className={ASSIGNMENT_STATUS_COLORS[assignment.status] || 'bg-gray-100 text-gray-600'}
              />
            </div>
          </div>

          {/* Meta info */}
          <div className="grid grid-cols-2 sm:grid-cols-4 gap-4 mt-5 pt-5 border-t border-gray-100">
            <div>
              <p className="text-xs text-gray-400">Vertragsbeginn</p>
              <p className="text-sm font-medium text-gray-700">{formatDate(assignment.contract_start)}</p>
            </div>
            <div>
              <p className="text-xs text-gray-400">Vertragsende</p>
              <p className="text-sm font-medium text-gray-700">
                {assignment.contract_end ? formatDate(assignment.contract_end) : 'Unbefristet'}
              </p>
            </div>
            <div>
              <p className="text-xs text-gray-400">Compliance-Score</p>
              <div className="mt-1">
                <ComplianceBar score={assignment.compliance_score} />
              </div>
            </div>
            <div>
              <p className="text-xs text-gray-400">Stunden diesen Monat</p>
              <div className="mt-1">
                <HoursBar used={assignment.hours_this_month} budget={assignment.hours_budget} />
              </div>
            </div>
          </div>

          {assignment.notes && (
            <div className="mt-4 pt-4 border-t border-gray-100">
              <p className="text-xs text-gray-400 mb-1">Anmerkungen</p>
              <p className="text-sm text-gray-600">{assignment.notes}</p>
            </div>
          )}
        </div>
      </div>

      {/* Tabs */}
      <div className="border-b border-gray-200">
        <nav className="flex gap-0 -mb-px overflow-x-auto">
          {tabs.map((tab) => (
            <button
              key={tab.id}
              onClick={() => setActiveTab(tab.id)}
              className={`flex items-center gap-2 px-5 py-3 text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${
                activeTab === tab.id
                  ? 'border-purple-600 text-purple-700'
                  : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
              }`}
            >
              {tab.icon}
              {tab.label}
            </button>
          ))}
        </nav>
      </div>

      {/* Tab content */}
      <div>
        {activeTab === 'aufgaben' && (
          <AufgabenTab assignmentId={assignment.id} addToast={addToast} />
        )}
        {activeTab === 'zeit' && (
          <ZeiterfassungTab
            assignmentId={assignment.id}
            monthlyBudget={assignment.monthly_hours_budget}
            addToast={addToast}
          />
        )}
        {activeTab === 'kommunikation' && (
          <KommunikationTab assignmentId={assignment.id} addToast={addToast} />
        )}
        {activeTab === 'einstellungen' && (
          <EinstellungenTab
            assignment={assignment}
            onUpdate={onUpdate}
            addToast={addToast}
          />
        )}
      </div>
    </div>
  )
}

// =============================================================================
// MAIN PAGE
// =============================================================================

export default function DSBPortalPage() {
  const [dashboard, setDashboard] = useState<DSBDashboard | null>(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState('')
  const [selectedAssignment, setSelectedAssignment] = useState<AssignmentOverview | null>(null)
  const { toasts, addToast } = useToast()

  const fetchDashboard = useCallback(async () => {
    setLoading(true)
    setError('')
    try {
      const data = await apiFetch<DSBDashboard>('/api/sdk/v1/dsb/dashboard')
      setDashboard(data)
      // If we had a selected assignment, update it from fresh data
      if (selectedAssignment) {
        const updated = data.assignments.find((a) => a.id === selectedAssignment.id)
        if (updated) setSelectedAssignment(updated)
      }
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : 'Fehler beim Laden des Dashboards')
    } finally {
      setLoading(false)
    }
  }, []) // eslint-disable-line react-hooks/exhaustive-deps

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

  const handleSelectAssignment = (assignment: AssignmentOverview) => {
    setSelectedAssignment(assignment)
  }

  const handleBackToDashboard = () => {
    setSelectedAssignment(null)
    fetchDashboard()
  }

  return (
    <div className="min-h-screen bg-gray-50">
      <ToastContainer toasts={toasts} />

      {/* Global Header */}
      <div className="bg-gradient-to-r from-purple-700 via-violet-600 to-purple-800 text-white">
        <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-4">
              <div className="w-12 h-12 rounded-xl bg-white/20 backdrop-blur-sm flex items-center justify-center">
                <IconShield className="w-7 h-7 text-white" />
              </div>
              <div>
                <h1 className="text-2xl font-bold">DSB-Portal</h1>
                <p className="text-purple-200 text-sm">
                  Datenschutzbeauftragter Mandanten-Verwaltung
                </p>
              </div>
            </div>
            <button
              onClick={fetchDashboard}
              className="p-2 rounded-lg bg-white/10 hover:bg-white/20 transition-colors"
              title="Aktualisieren"
            >
              <IconRefresh className="w-5 h-5" />
            </button>
          </div>
        </div>
      </div>

      {/* Content */}
      <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
        {loading && !dashboard ? (
          <DashboardSkeleton />
        ) : error && !dashboard ? (
          <ErrorState message={error} onRetry={fetchDashboard} />
        ) : selectedAssignment ? (
          <DetailView
            assignment={selectedAssignment}
            onBack={handleBackToDashboard}
            onUpdate={fetchDashboard}
            addToast={addToast}
          />
        ) : dashboard ? (
          <div className="space-y-6">
            {/* Stats Row */}
            <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
              <StatCard
                title="Aktive Mandanten"
                value={dashboard.active_assignments}
                icon={<IconUsers />}
              />
              <StatCard
                title="Stunden diesen Monat"
                value={`${dashboard.total_hours_this_month}h`}
                icon={<IconClock />}
              />
              <StatCard
                title="Offene Aufgaben"
                value={dashboard.open_tasks}
                icon={<IconTask />}
              />
              <StatCard
                title="Dringende Aufgaben"
                value={dashboard.urgent_tasks}
                icon={<IconAlert />}
                accent={dashboard.urgent_tasks > 0}
              />
            </div>

            {/* Mandanten Grid */}
            <div>
              <div className="flex items-center justify-between mb-4">
                <h2 className="text-lg font-semibold text-gray-900">
                  Mandanten ({dashboard.total_assignments})
                </h2>
              </div>

              {dashboard.assignments.length === 0 ? (
                <EmptyState
                  icon={<IconUsers className="w-7 h-7" />}
                  title="Keine Mandanten"
                  description="Es sind noch keine Mandanten-Zuweisungen vorhanden."
                />
              ) : (
                <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6">
                  {dashboard.assignments.map((a) => (
                    <MandantCard
                      key={a.id}
                      assignment={a}
                      onClick={() => handleSelectAssignment(a)}
                    />
                  ))}
                </div>
              )}
            </div>
          </div>
        ) : null}
      </div>

      {/* Inline animation styles */}
      <style jsx global>{`
        @keyframes slideIn {
          from {
            opacity: 0;
            transform: translateX(100px);
          }
          to {
            opacity: 1;
            transform: translateX(0);
          }
        }
        .animate-slide-in {
          animation: slideIn 0.3s ease-out;
        }
        .line-clamp-2 {
          display: -webkit-box;
          -webkit-line-clamp: 2;
          -webkit-box-orient: vertical;
          overflow: hidden;
        }
      `}</style>
    </div>
  )
}
