import { useState, useCallback } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import {
  Box,
  Typography,
  Chip,
  Button,
  Accordion,
  AccordionSummary,
  AccordionDetails,
  List,
  ListItem,
  ListItemText,
  ListItemIcon,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  Checkbox,
  Skeleton,
  Alert,
  Paper,
  Stack,
  Tooltip,
  CircularProgress,
  useTheme,
  useMediaQuery,
} from '@mui/material';
import {
  ExpandMore as ExpandMoreIcon,
  CheckCircle as CheckIcon,
  Cancel as CancelIcon,
  HelpOutline as UnknownIcon,
  Star as StarIcon,
  LocationOn as LocationIcon,
  AccessTime as TimeIcon,
  Group as GroupIcon,
  ArrowBack as BackIcon,
  Edit as EditIcon,
  Info as InfoIcon,
  HowToReg as AttendanceIcon,
} from '@mui/icons-material';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import DashboardLayout from '../components/dashboard/DashboardLayout';
import { usePermissionContext } from '../contexts/PermissionContext';
import { trainingApi } from '../services/training';
import type { TeilnahmeStatus, UebungTyp, Teilnahme } from '../types/training.types';

// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------

const TYP_CHIP_COLOR: Record<
  UebungTyp,
  'primary' | 'secondary' | 'warning' | 'default' | 'error' | 'info' | 'success'
> = {
  'Übungsabend':      'primary',
  'Lehrgang':         'secondary',
  'Sonderdienst':     'warning',
  'Versammlung':      'default',
  'Gemeinschaftsübung': 'info',
  'Sonstiges':        'default',
};

const WEEKDAY = ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'];
const MONTH   = ['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'];

function formatDateFull(iso: string): string {
  const d = new Date(iso);
  return `${WEEKDAY[d.getDay()]}, ${d.getDate()}. ${MONTH[d.getMonth()]} ${d.getFullYear()}`;
}

function formatTime(iso: string): string {
  const d = new Date(iso);
  return `${String(d.getHours()).padStart(2,'0')}:${String(d.getMinutes()).padStart(2,'0')} Uhr`;
}

// ---------------------------------------------------------------------------
// RSVP Status icon
// ---------------------------------------------------------------------------

function StatusIcon({ status }: { status: TeilnahmeStatus | undefined }) {
  if (!status || status === 'unbekannt') return <UnknownIcon sx={{ color: 'text.disabled' }} />;
  if (status === 'zugesagt')  return <CheckIcon sx={{ color: 'success.main' }} />;
  if (status === 'erschienen') return <CheckIcon sx={{ color: 'success.dark' }} />;
  if (status === 'entschuldigt') return <CancelIcon sx={{ color: 'warning.main' }} />;
  return <CancelIcon sx={{ color: 'error.main' }} />;
}

const STATUS_LABEL: Record<TeilnahmeStatus, string> = {
  zugesagt:    'Zugesagt',
  abgesagt:    'Abgesagt',
  erschienen:  'Erschienen',
  entschuldigt:'Entschuldigt',
  unbekannt:   'Ausstehend',
};

// ---------------------------------------------------------------------------
// Mark Attendance Modal
// ---------------------------------------------------------------------------

interface MarkAttendanceDialogProps {
  open: boolean;
  onClose: () => void;
  uebungId: string;
  teilnahmen: Teilnahme[];
}

function MarkAttendanceDialog({
  open, onClose, uebungId, teilnahmen,
}: MarkAttendanceDialogProps) {
  const queryClient = useQueryClient();
  const [selected, setSelected] = useState<Set<string>>(
    // Pre-select anyone already marked zugesagt
    new Set(teilnahmen.filter((t) => t.status === 'zugesagt' || t.status === 'erschienen').map((t) => t.user_id))
  );

  const mutation = useMutation({
    mutationFn: () => trainingApi.markAttendance(uebungId, Array.from(selected)),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['training', 'event', uebungId] });
      onClose();
    },
  });

  const toggle = (userId: string) => {
    setSelected((prev) => {
      const next = new Set(prev);
      if (next.has(userId)) next.delete(userId);
      else next.add(userId);
      return next;
    });
  };

  return (
    <Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth>
      <DialogTitle sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
        <AttendanceIcon color="primary" />
        Anwesenheit erfassen
      </DialogTitle>
      <DialogContent dividers sx={{ p: 0 }}>
        <List dense>
          {teilnahmen.map((t) => (
            <ListItem
              key={t.user_id}
              onClick={() => toggle(t.user_id)}
              sx={{ cursor: 'pointer', '&:hover': { bgcolor: 'action.hover' } }}
            >
              <ListItemIcon sx={{ minWidth: 36 }}>
                <Checkbox
                  checked={selected.has(t.user_id)}
                  size="small"
                  tabIndex={-1}
                  disableRipple
                />
              </ListItemIcon>
              <ListItemText
                primary={t.user_name ?? t.user_email ?? t.user_id}
                secondary={STATUS_LABEL[t.status]}
              />
            </ListItem>
          ))}
        </List>
      </DialogContent>
      <DialogActions sx={{ px: 2, pb: 2 }}>
        <Typography variant="caption" color="text.secondary" sx={{ flexGrow: 1 }}>
          {selected.size} von {teilnahmen.length} ausgewählt
        </Typography>
        <Button onClick={onClose} disabled={mutation.isPending}>Abbrechen</Button>
        <Button
          variant="contained"
          onClick={() => mutation.mutate()}
          disabled={mutation.isPending}
          startIcon={mutation.isPending ? <CircularProgress size={16} /> : <CheckIcon />}
        >
          Speichern
        </Button>
      </DialogActions>
    </Dialog>
  );
}

// ---------------------------------------------------------------------------
// Attendee Accordion
// ---------------------------------------------------------------------------

function AttendeeAccordion({
  teilnahmen,
  counts,
  canSeeList,
}: {
  teilnahmen?: Teilnahme[];
  counts: {
    anzahl_zugesagt: number;
    anzahl_abgesagt: number;
    anzahl_unbekannt: number;
    anzahl_entschuldigt: number;
    anzahl_erschienen: number;
    gesamt_eingeladen: number;
  };
  canSeeList: boolean;
}) {

  return (
    <Accordion disableGutters elevation={0} sx={{ border: '1px solid', borderColor: 'divider', borderRadius: 1 }}>
      <AccordionSummary expandIcon={<ExpandMoreIcon />}>
        <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap' }}>
          <GroupIcon fontSize="small" color="action" />
          <Typography variant="subtitle2">Rückmeldungen</Typography>
          <Chip label={`${counts.anzahl_zugesagt} zugesagt`} size="small" color="success" variant="outlined" sx={{ fontSize: '0.65rem', height: 18 }} />
          <Chip label={`${counts.anzahl_abgesagt} abgesagt`} size="small" color="error" variant="outlined" sx={{ fontSize: '0.65rem', height: 18 }} />
          <Chip label={`${counts.anzahl_unbekannt} ausstehend`} size="small" color="default" variant="outlined" sx={{ fontSize: '0.65rem', height: 18 }} />
          {counts.anzahl_erschienen > 0 && (
            <Chip label={`${counts.anzahl_erschienen} erschienen`} size="small" color="primary" variant="outlined" sx={{ fontSize: '0.65rem', height: 18 }} />
          )}
        </Box>
      </AccordionSummary>

      <AccordionDetails sx={{ pt: 0 }}>
        {!canSeeList && (
          <Alert severity="info" icon={<InfoIcon fontSize="small" />} sx={{ mb: 1 }}>
            Nur Gruppenführer und Kommandanten sehen die individuelle Rückmeldungsliste.
          </Alert>
        )}

        {canSeeList && teilnahmen && (
          <List dense disablePadding>
            {teilnahmen.map((t) => (
              <ListItem key={t.user_id} disablePadding sx={{ py: 0.25 }}>
                <ListItemIcon sx={{ minWidth: 32 }}>
                  <StatusIcon status={t.status} />
                </ListItemIcon>
                <ListItemText
                  primary={t.user_name ?? t.user_email ?? t.user_id}
                  secondary={
                    <Box component="span" sx={{ display: 'flex', gap: 1, alignItems: 'center' }}>
                      <span>{STATUS_LABEL[t.status]}</span>
                      {t.bemerkung && (
                        <Typography component="span" variant="caption" color="text.disabled">
                          — {t.bemerkung}
                        </Typography>
                      )}
                    </Box>
                  }
                  primaryTypographyProps={{ variant: 'body2' }}
                />
              </ListItem>
            ))}
          </List>
        )}

        {canSeeList && !teilnahmen && (
          <Typography variant="body2" color="text.secondary">
            Keine Teilnehmer gefunden.
          </Typography>
        )}
      </AccordionDetails>
    </Accordion>
  );
}

// ---------------------------------------------------------------------------
// Main Page
// ---------------------------------------------------------------------------

export default function UebungDetail() {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const { hasPermission } = usePermissionContext();
  const queryClient = useQueryClient();
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down('sm'));

  const canWrite = hasPermission('kalender:create');
  const canSeeAttendees = hasPermission('kalender:create');

  const [markAttendanceOpen, setMarkAttendanceOpen] = useState(false);
  const [rsvpLoading, setRsvpLoading] = useState<'zugesagt' | 'abgesagt' | null>(null);

  const { data: event, isLoading, isError } = useQuery({
    queryKey: ['training', 'event', id],
    queryFn: () => trainingApi.getById(id!),
    enabled: Boolean(id),
  });

  const rsvpMutation = useMutation({
    mutationFn: (status: 'zugesagt' | 'abgesagt') =>
      trainingApi.updateRsvp(id!, status),
    onSuccess: (_data, _status) => {
      queryClient.invalidateQueries({ queryKey: ['training', 'event', id] });
      queryClient.invalidateQueries({ queryKey: ['training', 'upcoming'] });
      setRsvpLoading(null);
    },
    onError: () => setRsvpLoading(null),
  });

  const handleRsvp = useCallback((status: 'zugesagt' | 'abgesagt') => {
    setRsvpLoading(status);
    rsvpMutation.mutate(status);
  }, [rsvpMutation]);

  // -------------------------------------------------------------------------
  // Loading / error states
  // -------------------------------------------------------------------------

  if (isLoading) {
    return (
      <DashboardLayout>
        <Box sx={{ maxWidth: 720, mx: 'auto' }}>
          <Skeleton variant="text" width={200} height={32} sx={{ mb: 1 }} />
          <Skeleton variant="rectangular" height={160} sx={{ borderRadius: 2, mb: 2 }} />
          <Skeleton variant="rectangular" height={120} sx={{ borderRadius: 2, mb: 2 }} />
          <Skeleton variant="rectangular" height={200} sx={{ borderRadius: 2 }} />
        </Box>
      </DashboardLayout>
    );
  }

  if (isError || !event) {
    return (
      <DashboardLayout>
        <Alert severity="error" sx={{ maxWidth: 720, mx: 'auto' }}>
          Veranstaltung konnte nicht geladen werden.
        </Alert>
      </DashboardLayout>
    );
  }

  const isPast = new Date(event.datum_von) < new Date();
  // const isAlreadyRsvp = event.eigener_status === 'zugesagt' || event.eigener_status === 'abgesagt';

  return (
    <DashboardLayout>
      <Box sx={{ maxWidth: 720, mx: 'auto' }}>
        {/* Back button */}
        <Button
          startIcon={<BackIcon />}
          onClick={() => navigate(-1)}
          sx={{ mb: 2, textTransform: 'none' }}
          size="small"
        >
          Zurück zum Kalender
        </Button>

        {/* Cancelled banner */}
        {event.abgesagt && (
          <Alert severity="error" sx={{ mb: 2 }}>
            <strong>Abgesagt:</strong> {event.absage_grund ?? 'Kein Grund angegeben.'}
          </Alert>
        )}

        {/* Header card */}
        <Paper elevation={1} sx={{ p: { xs: 2, sm: 3 }, mb: 2, borderRadius: 2 }}>
          <Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 1, mb: 1, flexWrap: 'wrap' }}>
            <Chip
              label={event.typ}
              color={TYP_CHIP_COLOR[event.typ]}
              size="small"
            />
            {event.pflichtveranstaltung && (
              <Chip
                icon={<StarIcon sx={{ fontSize: 14 }} />}
                label="Pflichtveranstaltung"
                size="small"
                color="warning"
                variant="outlined"
              />
            )}
            {canWrite && (
              <Tooltip title="Bearbeiten">
                <Button
                  size="small"
                  startIcon={<EditIcon fontSize="small" />}
                  sx={{ ml: 'auto', textTransform: 'none' }}
                  onClick={() => navigate(`/training/${id}/bearbeiten`)}
                >
                  {!isMobile && 'Bearbeiten'}
                </Button>
              </Tooltip>
            )}
          </Box>

          <Typography
            variant="h5"
            sx={{
              fontWeight: 700,
              textDecoration: event.abgesagt ? 'line-through' : 'none',
              mb: 1.5,
            }}
          >
            {event.titel}
          </Typography>

          {/* Meta info */}
          <Stack spacing={0.75}>
            <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
              <TimeIcon fontSize="small" color="action" />
              <Typography variant="body2">
                {formatDateFull(event.datum_von)},{' '}
                {formatTime(event.datum_von)} – {formatTime(event.datum_bis)}
              </Typography>
            </Box>
            {event.ort && (
              <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
                <LocationIcon fontSize="small" color="action" />
                <Typography variant="body2">{event.ort}</Typography>
              </Box>
            )}
            {event.treffpunkt && event.treffpunkt !== event.ort && (
              <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
                <LocationIcon fontSize="small" color="action" sx={{ opacity: 0.5 }} />
                <Typography variant="body2" color="text.secondary">
                  Treffpunkt: {event.treffpunkt}
                </Typography>
              </Box>
            )}
            {event.angelegt_von_name && (
              <Typography variant="caption" color="text.disabled">
                Erstellt von {event.angelegt_von_name}
              </Typography>
            )}
          </Stack>
        </Paper>

        {/* Description */}
        {event.beschreibung && (
          <Paper elevation={1} sx={{ p: { xs: 2, sm: 3 }, mb: 2, borderRadius: 2 }}>
            <Typography variant="subtitle2" gutterBottom>Beschreibung</Typography>
            <Typography variant="body2" sx={{ whiteSpace: 'pre-wrap' }}>
              {event.beschreibung}
            </Typography>
          </Paper>
        )}

        {/* RSVP section */}
        {!event.abgesagt && !isPast && (
          <Paper elevation={1} sx={{ p: { xs: 2, sm: 3 }, mb: 2, borderRadius: 2 }}>
            <Typography variant="subtitle2" gutterBottom>
              Meine Rückmeldung
            </Typography>

            {event.eigener_status && event.eigener_status !== 'unbekannt' && (
              <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 1.5 }}>
                <StatusIcon status={event.eigener_status} />
                <Typography variant="body2">
                  Aktuelle Rückmeldung: <strong>{STATUS_LABEL[event.eigener_status]}</strong>
                </Typography>
              </Box>
            )}

            <Stack
              direction={isMobile ? 'column' : 'row'}
              spacing={1.5}
            >
              <Button
                variant={event.eigener_status === 'zugesagt' ? 'contained' : 'outlined'}
                color="success"
                size="large"
                startIcon={
                  rsvpLoading === 'zugesagt'
                    ? <CircularProgress size={18} color="inherit" />
                    : <CheckIcon />
                }
                onClick={() => handleRsvp('zugesagt')}
                disabled={rsvpMutation.isPending}
                fullWidth={isMobile}
                sx={{
                  minHeight: 56, // Large tap target per mobile requirement
                  fontWeight: 600,
                  fontSize: '1rem',
                }}
              >
                Zusagen
              </Button>

              <Button
                variant={event.eigener_status === 'abgesagt' ? 'contained' : 'outlined'}
                color="error"
                size="large"
                startIcon={
                  rsvpLoading === 'abgesagt'
                    ? <CircularProgress size={18} color="inherit" />
                    : <CancelIcon />
                }
                onClick={() => handleRsvp('abgesagt')}
                disabled={rsvpMutation.isPending}
                fullWidth={isMobile}
                sx={{
                  minHeight: 56, // Large tap target per mobile requirement
                  fontWeight: 600,
                  fontSize: '1rem',
                }}
              >
                Absagen
              </Button>
            </Stack>
          </Paper>
        )}

        {/* Attendee summary + list */}
        <Paper elevation={1} sx={{ p: { xs: 2, sm: 3 }, mb: 2, borderRadius: 2 }}>
          <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 1.5 }}>
            <Typography variant="subtitle2">Teilnehmer</Typography>
            {canWrite && !event.abgesagt && (
              <Button
                size="small"
                variant="outlined"
                startIcon={<AttendanceIcon fontSize="small" />}
                onClick={() => setMarkAttendanceOpen(true)}
                sx={{ textTransform: 'none' }}
              >
                Anwesenheit erfassen
              </Button>
            )}
          </Box>

          <AttendeeAccordion
            teilnahmen={event.teilnahmen}
            counts={event}
            canSeeList={canSeeAttendees}
          />
        </Paper>
      </Box>

      {/* Mark Attendance Dialog */}
      {event.teilnahmen && (
        <MarkAttendanceDialog
          open={markAttendanceOpen}
          onClose={() => setMarkAttendanceOpen(false)}
          uebungId={id!}
          teilnahmen={event.teilnahmen}
        />
      )}
    </DashboardLayout>
  );
}
