/**
 * Property On — Register «Aufgaben» des Personalblatts (§8).
 *
 * Die Liste zeigt jede Aufgabe des gewählten Mitarbeiters einzeln schaltbar.
 * Geändert wird zuerst nur ein lokaler Entwurf: Zuschalten und Pausieren
 * verändert, was ein digitaler Mitarbeiter im Alltag der Bewirtschaftung tut —
 * das darf nicht beiläufig im Hintergrund passieren, sondern erst mit einer
 * bewussten Freigabe über «Änderungen speichern» (§8.2).
 */

import { memo, useCallback, useMemo, useState } from 'react'
import { Box, Button, Switch, Typography } from '@mui/material'
import { Clock, Plug, RotateCcw, Save, ShieldCheck } from 'lucide-react'
import type { AgentTask, TeamAgent } from '../../domain/teamAgent'
import { AGENT_CHANNEL_LABELS, AGENT_SYSTEM_LABELS } from '../../lib/constants'
import { DS_BG, DS_BORDER, DS_SHADOW, DS_SURFACE, DS_TEXT } from '../../lib/ds'
import { GenericBadge } from '../shared/GenericBadge'
import { useSaveAgentTasks } from '../../hooks/useTeamAgents'

// ── Eine Aufgabenzeile ────────────────────────────────────────────────────────

interface TaskRowProps {
  task: AgentTask
  busy: boolean
  onToggle: (id: string, enabled: boolean) => void
}

/**
 * `React.memo` ist Pflicht: ein Mitarbeiter führt bis zu zwölf Aufgaben, und
 * jeder Schalterklick verändert den Entwurf der ganzen Liste (CLAUDE.md §10.2).
 */
const TaskRow = memo(function TaskRow({ task, busy, onToggle }: TaskRowProps) {
  const dependencies = useMemo(() => {
    const out: string[] = []
    if (task.dependsOnChannel) {
      out.push(`Kanal: ${AGENT_CHANNEL_LABELS[task.dependsOnChannel] ?? task.dependsOnChannel}`)
    }
    if (task.dependsOnSystem) {
      out.push(`Systemzugang: ${AGENT_SYSTEM_LABELS[task.dependsOnSystem] ?? task.dependsOnSystem}`)
    }
    return out
  }, [task.dependsOnChannel, task.dependsOnSystem])

  const handleChange = useCallback(
    (_event: unknown, checked: boolean) => onToggle(task.id, checked),
    [onToggle, task.id],
  )

  return (
    <Box
      component="li"
      sx={{
        display: 'flex',
        gap: 1.5,
        alignItems: 'flex-start',
        p: 1.75,
        border: `1px solid ${DS_BORDER.default}`,
        borderRadius: 2,
        bgcolor: task.enabled ? DS_BG.surface : DS_BG.subtle,
        boxShadow: task.enabled ? DS_SHADOW.card : 'none',
      }}
    >
      {/* Schalter mit Zustand als Text — Farbe allein trägt keinen Status (§18) */}
      <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', flexShrink: 0, width: 76 }}>
        <Switch
          checked={task.enabled}
          disabled={busy}
          onChange={handleChange}
          slotProps={{ input: { 'aria-label': `Aufgabe «${task.title}» aktivieren` } }}
          sx={{
            '& .MuiSwitch-switchBase.Mui-focusVisible + .MuiSwitch-track': {
              outline: `2px solid ${DS_TEXT.brand}`,
              outlineOffset: 2,
            },
          }}
        />
        <Typography
          variant="caption"
          sx={{ fontWeight: 600, color: task.enabled ? DS_TEXT.success : DS_TEXT.muted }}
        >
          {task.enabled ? 'Aktiv' : 'Pausiert'}
        </Typography>
      </Box>

      <Box sx={{ minWidth: 0, flex: 1 }}>
        <Typography sx={{ fontWeight: 700, fontSize: '0.9375rem', color: DS_TEXT.primary }}>
          {task.title}
        </Typography>

        <Typography variant="body2" sx={{ color: DS_TEXT.secondary, mt: 0.25 }}>
          {task.description}
        </Typography>

        <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5, mt: 1 }}>
          <Clock size={13} color={DS_TEXT.muted} aria-hidden style={{ flexShrink: 0 }} />
          <Typography variant="caption" sx={{ color: DS_TEXT.secondary }}>
            Zeitplan: {task.schedule}
          </Typography>
        </Box>

        {dependencies.map((dependency) => (
          <Box key={dependency} sx={{ display: 'flex', alignItems: 'center', gap: 0.5, mt: 0.375 }}>
            <Plug size={13} color={DS_TEXT.muted} aria-hidden style={{ flexShrink: 0 }} />
            <Typography variant="caption" sx={{ color: DS_TEXT.secondary }}>
              Setzt voraus — {dependency}
            </Typography>
          </Box>
        ))}

        {task.requiresApproval && (
          <Box sx={{ mt: 1 }}>
            <GenericBadge
              label="Freigabe erforderlich"
              semanticVariant="confidenceMedium"
              bold
              icon={<ShieldCheck size={13} aria-hidden />}
              tooltip="Das Ergebnis dieser Aufgabe wird erst nach Ihrer Freigabe wirksam."
            />
          </Box>
        )}
      </Box>
    </Box>
  )
})

// ── Register «Aufgaben» ───────────────────────────────────────────────────────

export function AgentTasksTab({ agent }: { agent: TeamAgent }) {
  const [draft, setDraft] = useState<AgentTask[]>(agent.tasks)
  const saveTasks = useSaveAgentTasks()

  /**
   * Beim Wechsel des Mitarbeiters wird der Entwurf neu aufgesetzt — sonst stünde
   * der Entwurf des zuvor gewählten Mitarbeiters in einem fremden Personalblatt.
   * Bewusst nur an `agent.id` gebunden: liefe der Effekt auch bei jeder neuen
   * Referenz von `agent.tasks`, würde ein Hintergrundabgleich unbestätigte
   * Änderungen still verwerfen.
   */
  // Kein Effekt nötig: `Personalverwaltung` gibt diesem Reiter die Mitarbeiter-ID
  // als `key` mit, er wird beim Wechsel des Dossiers ohnehin neu aufgebaut.

  /** Ein Durchlauf für beide Ableitungen — Anzahl aktiver Aufgaben und Abweichung (§10.4). */
  const { activeCount, dirty } = useMemo(() => {
    const saved = new Map(agent.tasks.map((task) => [task.id, task.enabled]))
    let active = 0
    let changed = draft.length !== agent.tasks.length
    for (const task of draft) {
      if (task.enabled) active += 1
      if (saved.get(task.id) !== task.enabled) changed = true
    }
    return { activeCount: active, dirty: changed }
  }, [draft, agent.tasks])

  const handleToggle = useCallback((id: string, enabled: boolean) => {
    setDraft((prev) => prev.map((task) => (task.id === id ? { ...task, enabled } : task)))
  }, [])

  const handleReset = useCallback(() => setDraft(agent.tasks), [agent.tasks])

  const handleSave = useCallback(() => {
    saveTasks.mutate({ id: agent.id, tasks: draft })
  }, [saveTasks, agent.id, draft])

  const busy = saveTasks.isPending
  const focusRing = { '&:focus-visible': { outline: `2px solid ${DS_TEXT.brand}`, outlineOffset: 2 } }

  return (
    <Box>
      <Typography component="h2" sx={{ fontWeight: 700, fontSize: '0.9375rem', color: DS_TEXT.primary }}>
        {activeCount} von {draft.length} Aufgaben aktiv
      </Typography>
      <Typography variant="body2" sx={{ color: DS_TEXT.secondary, mt: 0.25 }}>
        Jede Aufgabe lässt sich einzeln zuschalten oder pausieren. Änderungen werden erst mit dem
        Speichern für {agent.name} wirksam.
      </Typography>

      {dirty && (
        <Box
          role="status"
          aria-live="polite"
          sx={{
            position: 'sticky',
            top: 0,
            zIndex: 1,
            display: 'flex',
            alignItems: 'center',
            gap: 1.5,
            flexWrap: 'wrap',
            mt: 1.75,
            p: 1.5,
            borderRadius: 2,
            bgcolor: DS_SURFACE.warning.bg,
            border: `1px solid ${DS_SURFACE.warning.border}`,
          }}
        >
          <Typography variant="body2" sx={{ fontWeight: 700, color: DS_TEXT.warningDark }}>
            Nicht gespeicherte Änderungen
          </Typography>
          <Button
            variant="contained"
            size="small"
            disabled={busy}
            startIcon={<Save size={15} />}
            onClick={handleSave}
            sx={{ textTransform: 'none', fontWeight: 600, ml: 'auto', ...focusRing }}
          >
            Änderungen speichern
          </Button>
          <Button
            variant="outlined"
            size="small"
            disabled={busy}
            startIcon={<RotateCcw size={15} />}
            onClick={handleReset}
            sx={{ textTransform: 'none', fontWeight: 600, ...focusRing }}
          >
            Zurücksetzen
          </Button>
        </Box>
      )}

      {draft.length === 0 ? (
        <Typography variant="body2" sx={{ color: DS_TEXT.muted, mt: 2 }}>
          Für {agent.name} sind noch keine Aufgaben hinterlegt.
        </Typography>
      ) : (
        <Box component="ul" sx={{ listStyle: 'none', m: 0, mt: 1.75, p: 0, display: 'grid', gap: 1.25 }}>
          {draft.map((task) => (
            <TaskRow key={task.id} task={task} busy={busy} onToggle={handleToggle} />
          ))}
        </Box>
      )}
    </Box>
  )
}
