import { useMemo } from 'react';
import {
  Box,
  List,
  ListItem,
  ListItemText,
  Chip,
  Typography,
  Button,
  Skeleton,
  Tooltip,
} from '@mui/material';
import {
  CheckCircle as CheckIcon,
  Cancel as CancelIcon,
  HelpOutline as UnknownIcon,
  Star as StarIcon,
  CalendarMonth as CalendarIcon,
  ArrowForward as ArrowIcon,
} from '@mui/icons-material';
import { useNavigate } from 'react-router-dom';
import { useQuery } from '@tanstack/react-query';
import { trainingApi } from '../../services/training';
import type { UebungListItem, TeilnahmeStatus, UebungTyp } from '../../types/training.types';

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

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

const WEEKDAY_SHORT = ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'];
const MONTH_SHORT   = ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'];

function formatEventDate(isoString: string): string {
  const d = new Date(isoString);
  return `${WEEKDAY_SHORT[d.getDay()]}, ${String(d.getDate()).padStart(2, '0')}. ${MONTH_SHORT[d.getMonth()]}`;
}

function formatEventTime(vonIso: string, bisIso: string): string {
  const von = new Date(vonIso);
  const bis = new Date(bisIso);
  const pad = (n: number) => String(n).padStart(2, '0');
  return `${pad(von.getHours())}:${pad(von.getMinutes())} – ${pad(bis.getHours())}:${pad(bis.getMinutes())} Uhr`;
}

// ---------------------------------------------------------------------------
// RSVP Status badge
// ---------------------------------------------------------------------------

function RsvpBadge({ status }: { status: TeilnahmeStatus | undefined }) {
  if (!status || status === 'unbekannt') {
    return (
      <Tooltip title="Noch keine Rückmeldung">
        <UnknownIcon sx={{ color: 'text.disabled', fontSize: 20 }} />
      </Tooltip>
    );
  }
  if (status === 'zugesagt') {
    return (
      <Tooltip title="Zugesagt">
        <CheckIcon sx={{ color: 'success.main', fontSize: 20 }} />
      </Tooltip>
    );
  }
  if (status === 'erschienen') {
    return (
      <Tooltip title="Erschienen">
        <CheckIcon sx={{ color: 'success.dark', fontSize: 20 }} />
      </Tooltip>
    );
  }
  if (status === 'abgesagt' || status === 'entschuldigt') {
    return (
      <Tooltip title={status === 'entschuldigt' ? 'Entschuldigt' : 'Abgesagt'}>
        <CancelIcon sx={{ color: 'error.main', fontSize: 20 }} />
      </Tooltip>
    );
  }
  return null;
}

// ---------------------------------------------------------------------------
// Single event row
// ---------------------------------------------------------------------------

function EventRow({ event }: { event: UebungListItem }) {
  const navigate = useNavigate();

  return (
    <ListItem
      disablePadding
      onClick={() => navigate(`/training/${event.id}`)}
      sx={{
        cursor: 'pointer',
        borderRadius: 1,
        mb: 0.5,
        px: 1,
        py: 0.75,
        transition: 'background 0.15s',
        '&:hover': { backgroundColor: 'action.hover' },
        opacity: event.abgesagt ? 0.55 : 1,
      }}
    >
      {/* Date column */}
      <Box
        sx={{
          minWidth: 72,
          mr: 1.5,
          textAlign: 'center',
          flexShrink: 0,
        }}
      >
        <Typography
          variant="caption"
          sx={{
            display: 'block',
            color: 'text.secondary',
            lineHeight: 1.2,
            fontSize: '0.7rem',
          }}
        >
          {formatEventDate(event.datum_von)}
        </Typography>
        <Typography
          variant="caption"
          sx={{
            display: 'block',
            color: 'text.disabled',
            fontSize: '0.65rem',
          }}
        >
          {formatEventTime(event.datum_von, event.datum_bis)}
        </Typography>
      </Box>

      {/* Title + chip */}
      <ListItemText
        primary={
          <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5, flexWrap: 'wrap' }}>
            {event.pflichtveranstaltung && (
              <StarIcon sx={{ fontSize: 14, color: 'warning.main', flexShrink: 0 }} />
            )}
            <Typography
              variant="body2"
              sx={{
                fontWeight: event.pflichtveranstaltung ? 700 : 400,
                textDecoration: event.abgesagt ? 'line-through' : 'none',
                lineHeight: 1.3,
              }}
            >
              {event.titel}
            </Typography>
          </Box>
        }
        secondary={
          <Chip
            label={event.typ}
            size="small"
            color={TYP_COLORS[event.typ]}
            variant="outlined"
            sx={{ fontSize: '0.65rem', height: 18, mt: 0.25 }}
          />
        }
        sx={{ my: 0 }}
      />

      {/* RSVP status */}
      <Box sx={{ ml: 1, flexShrink: 0 }}>
        <RsvpBadge status={event.eigener_status} />
      </Box>
    </ListItem>
  );
}

// ---------------------------------------------------------------------------
// Main widget component
// ---------------------------------------------------------------------------

export default function UpcomingEvents() {
  const navigate = useNavigate();

  const { data, isLoading, isError } = useQuery({
    queryKey: ['training', 'upcoming', 3],
    queryFn: () => trainingApi.getUpcoming(3),
    staleTime: 5 * 60 * 1000, // 5 min
  });

  const events = useMemo(() => data ?? [], [data]);

  return (
    <Box>
      <Box sx={{ display: 'flex', alignItems: 'center', mb: 1, gap: 1 }}>
        <CalendarIcon color="primary" fontSize="small" />
        <Typography variant="h6" sx={{ flexGrow: 1 }}>
          Nächste Dienste
        </Typography>
      </Box>

      {isLoading && (
        <Box>
          {[1, 2, 3].map((n) => (
            <Skeleton key={n} variant="rectangular" height={56} sx={{ borderRadius: 1, mb: 0.5 }} />
          ))}
        </Box>
      )}

      {isError && (
        <Typography variant="body2" color="text.secondary" sx={{ py: 2, textAlign: 'center' }}>
          Dienste konnten nicht geladen werden.
        </Typography>
      )}

      {!isLoading && !isError && events.length === 0 && (
        <Typography variant="body2" color="text.secondary" sx={{ py: 2, textAlign: 'center' }}>
          Keine bevorstehenden Veranstaltungen.
        </Typography>
      )}

      {!isLoading && !isError && events.length > 0 && (
        <List dense disablePadding>
          {events.map((event) => (
            <EventRow key={event.id} event={event} />
          ))}
        </List>
      )}

      <Box sx={{ mt: 1.5, display: 'flex', justifyContent: 'flex-end' }}>
        <Button
          size="small"
          endIcon={<ArrowIcon />}
          onClick={() => navigate('/kalender')}
          sx={{ textTransform: 'none' }}
        >
          Zum Kalender
        </Button>
      </Box>
    </Box>
  );
}
