import React, { useEffect, useMemo, useState } from 'react';
import axios from 'axios';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import IconButton from '@mui/material/IconButton';
import Tooltip from '@mui/material/Tooltip';
import Chip from '@mui/material/Chip';
import EventIcon from '@mui/icons-material/Event';
import SwapHorizIcon from '@mui/icons-material/SwapHoriz';
import PersonSearchIcon from '@mui/icons-material/PersonSearch';
import SchoolIcon from '@mui/icons-material/School';
import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
import { t } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import WidgetWrapper from './WidgetWrapper';
import { useFeatureFlag } from '../../hooks/useFeatureFlag';
import { styleForSessionStatus } from '../../utils/classSlice';
import { MyAssignment, ShiftInfo } from '../../types/swapReplacement';
import type { ClassSession } from '../../types/class';

interface MyShiftsWidgetProps {
  assignments: MyAssignment[];
  loading: boolean;
  onRefresh: () => void;
  refreshing?: boolean;
  onRequestSwap: (assignment: MyAssignment) => void;
  onRequestReplacement: (assignment: MyAssignment) => void;
  month: string;
  onMonthChange: (month: string) => void;
}

function getStatusColor(status: string | null): 'default' | 'warning' | 'info' | 'success' | 'error' {
  switch (status) {
    case 'swap_requested': return 'info';
    case 'swap_accepted': return 'success';
    case 'seeking_replacement': return 'warning';
    case 'replaced': return 'success';
    default: return 'default';
  }
}

function getStatusLabel(status: string | null, i18n: any): string {
  switch (status) {
    case 'swap_requested': return i18n._(t`Tausch angefragt`);
    case 'swap_accepted': return i18n._(t`Getauscht`);
    case 'seeking_replacement': return i18n._(t`Vertretung gesucht`);
    case 'replaced': return i18n._(t`Vertreten`);
    default: return '';
  }
}

function formatShiftTime(shift: ShiftInfo): string {
  const start = shift.zs_start_time?.substring(0, 5) || '';
  const end = shift.zs_end_time?.substring(0, 5) || '';
  return `${start} - ${end}`;
}

function formatDate(dateStr: string): string {
  const date = new Date(dateStr + 'T00:00:00');
  const day = date.getDate().toString().padStart(2, '0');
  const month = (date.getMonth() + 1).toString().padStart(2, '0');
  const weekdays = ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'];
  return `${weekdays[date.getDay()]}, ${day}.${month}`;
}

function getMonthLabel(month: string): string {
  const [year, m] = month.split('-');
  const months = ['Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'];
  return `${months[parseInt(m, 10) - 1]} ${year}`;
}

const statusDotColor: Record<string, string> = {
  swap_requested: 'info.main',
  swap_accepted: 'success.main',
  seeking_replacement: 'warning.main',
  replaced: 'success.main',
};

const MyShiftsWidget: React.FC<MyShiftsWidgetProps> = ({
  assignments,
  loading,
  onRefresh,
  refreshing = false,
  onRequestSwap,
  onRequestReplacement,
  month,
  onMonthChange,
}) => {
  const { i18n } = useLingui();
  const classesFlag = useFeatureFlag('classes_v1');
  const classesV1Enabled: boolean = classesFlag.enabled;

  const bersAndRange = useMemo((): { bers: number[]; from: string; to: string } => {
    const bers: Set<number> = new Set<number>();
    let minDate: string = '';
    let maxDate: string = '';
    for (const a of assignments) {
      const ber: number | undefined = a.shift?.department?.ber_id;
      if (typeof ber === 'number') bers.add(ber);
      const d: string | undefined = a.shift?.zs_date;
      if (d) {
        if (!minDate || d < minDate) minDate = d;
        if (!maxDate || d > maxDate) maxDate = d;
      }
    }
    return { bers: Array.from(bers), from: minDate, to: maxDate };
  }, [assignments]);

  const [classSessionsByShiftId, setClassSessionsByShiftId] = useState<Map<number, ClassSession[]>>(
    () => new Map<number, ClassSession[]>()
  );

  useEffect(() => {
    if (!classesV1Enabled) {
      setClassSessionsByShiftId(new Map<number, ClassSession[]>());
      return;
    }
    const { bers, from, to } = bersAndRange;
    if (bers.length === 0 || from === '' || to === '') {
      setClassSessionsByShiftId(new Map<number, ClassSession[]>());
      return;
    }
    let cancelled: boolean = false;
    const load = async (): Promise<void> => {
      const map: Map<number, ClassSession[]> = new Map<number, ClassSession[]>();
      await Promise.all(
        bers.map(async (berId: number) => {
          try {
            const response = await axios.get('/zeiterfassung/class-sessions', {
              params: { ber_id: berId, from, to },
            });
            const list: ClassSession[] = Array.isArray(response.data)
              ? (response.data as ClassSession[])
              : [];
            for (const cs of list) {
              if (cs.zcs_shift_id === null || cs.zcs_shift_id === undefined) continue;
              const arr: ClassSession[] = map.get(cs.zcs_shift_id) ?? [];
              arr.push(cs);
              map.set(cs.zcs_shift_id, arr);
            }
          } catch {
            // best-effort; widget is read-only overlay
          }
        })
      );
      if (!cancelled) {
        setClassSessionsByShiftId(map);
      }
    };
    load();
    return () => {
      cancelled = true;
    };
  }, [classesV1Enabled, bersAndRange]);

  const sortedAssignments = useMemo(() => {
    return [...assignments].sort((a, b) => {
      const dateA = a.shift?.zs_date || '';
      const dateB = b.shift?.zs_date || '';
      if (dateA !== dateB) return dateA.localeCompare(dateB);
      const timeA = a.shift?.zs_start_time || '';
      const timeB = b.shift?.zs_start_time || '';
      return timeA.localeCompare(timeB);
    });
  }, [assignments]);

  const handlePrevMonth = () => {
    const [year, m] = month.split('-').map(Number);
    const date = new Date(year, m - 2, 1);
    onMonthChange(`${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`);
  };

  const handleNextMonth = () => {
    const [year, m] = month.split('-').map(Number);
    const date = new Date(year, m, 1);
    onMonthChange(`${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`);
  };

  const monthNav = (
    <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
      <IconButton size="small" onClick={handlePrevMonth} sx={{ color: 'text.secondary' }}>
        <ChevronLeftIcon fontSize="small" />
      </IconButton>
      <Typography
        variant="caption"
        fontWeight={600}
        sx={{ minWidth: 72, textAlign: 'center', letterSpacing: 0.3, color: 'text.primary' }}
      >
        {getMonthLabel(month)}
      </Typography>
      <IconButton size="small" onClick={handleNextMonth} sx={{ color: 'text.secondary' }}>
        <ChevronRightIcon fontSize="small" />
      </IconButton>
    </Box>
  );

  return (
    <WidgetWrapper
      title={i18n._(t`Meine Schichten`)}
      icon={<EventIcon />}
      headerActions={monthNav}
      loading={loading}
      onRefresh={onRefresh}
      refreshing={refreshing}
      badge={assignments.length}
      badgeColor="primary"
      empty={assignments.length === 0}
      emptyMessage={i18n._(t`Keine Schichten in diesem Monat`)}
      emptyIcon={<EventIcon sx={{ fontSize: 40 }} />}
    >
      <Box sx={{ overflow: 'auto' }}>
        {sortedAssignments.map((assignment, index) => {
          const shift = assignment.shift;
          if (!shift) return null;

          const isPast = new Date(shift.zs_date) < new Date(new Date().toISOString().split('T')[0]);
          const hasStatus = !!assignment.zsa_replacement_status;
          const canAct = assignment.can_request_swap && !isPast;
          const isLast = index === sortedAssignments.length - 1;
          const relatedClasses: ClassSession[] =
            classesV1Enabled ? classSessionsByShiftId.get(shift.zs_id) ?? [] : [];

          return (
            <Box
              key={assignment.zsa_id}
              sx={{
                opacity: isPast ? 0.45 : 1,
                ...(!isLast && {
                  borderBottom: '1px solid',
                  borderColor: 'divider',
                }),
              }}
            >
            <Box
              sx={{
                display: 'flex',
                alignItems: 'center',
                px: 2,
                py: 1.5,
                transition: 'background-color 0.15s ease',
                '&:hover': {
                  bgcolor: isPast ? 'transparent' : 'action.hover',
                },
              }}
            >
              <Box
                sx={{
                  width: 3,
                  alignSelf: 'stretch',
                  borderRadius: 1.5,
                  bgcolor: shift.template?.zst_color || 'primary.main',
                  flexShrink: 0,
                  mr: 1.5,
                }}
              />

              <Box sx={{ flex: 1, minWidth: 0 }}>
                <Box sx={{ display: 'flex', alignItems: 'baseline', gap: 1 }}>
                  <Typography
                    variant="body2"
                    fontWeight={600}
                    sx={{ color: 'text.primary', lineHeight: 1.4 }}
                  >
                    {formatDate(shift.zs_date)}
                  </Typography>
                  <Typography
                    variant="body2"
                    sx={{ color: 'text.secondary', fontSize: '0.8125rem', lineHeight: 1.4 }}
                  >
                    {formatShiftTime(shift)}
                  </Typography>
                </Box>

                <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75, mt: 0.25 }}>
                  <Typography
                    variant="caption"
                    sx={{ color: 'text.secondary', fontSize: '0.7rem', lineHeight: 1.3 }}
                  >
                    {shift.display_name}
                  </Typography>
                  {shift.department && (
                    <>
                      <Box
                        component="span"
                        sx={{
                          width: 3,
                          height: 3,
                          borderRadius: '50%',
                          bgcolor: 'text.disabled',
                          flexShrink: 0,
                        }}
                      />
                      <Typography
                        variant="caption"
                        sx={{ color: 'text.disabled', fontSize: '0.7rem', lineHeight: 1.3 }}
                      >
                        {shift.department.ber_name}
                      </Typography>
                    </>
                  )}
                  {hasStatus && (
                    <Box
                      sx={{
                        display: 'inline-flex',
                        alignItems: 'center',
                        gap: 0.5,
                        ml: 0.25,
                        px: 0.75,
                        py: 0.125,
                        borderRadius: 1,
                        bgcolor: `${statusDotColor[assignment.zsa_replacement_status || ''] ? assignment.zsa_replacement_status === 'seeking_replacement' ? 'warning' : assignment.zsa_replacement_status === 'swap_requested' ? 'info' : 'success' : 'grey'}.50`,
                      }}
                    >
                      <Box
                        sx={{
                          width: 5,
                          height: 5,
                          borderRadius: '50%',
                          bgcolor: statusDotColor[assignment.zsa_replacement_status || ''] || 'text.disabled',
                          flexShrink: 0,
                        }}
                      />
                      <Typography
                        variant="caption"
                        sx={{
                          fontSize: '0.625rem',
                          fontWeight: 500,
                          lineHeight: 1,
                          color: statusDotColor[assignment.zsa_replacement_status || ''] || 'text.secondary',
                        }}
                      >
                        {getStatusLabel(assignment.zsa_replacement_status, i18n)}
                      </Typography>
                    </Box>
                  )}
                </Box>
              </Box>

              {canAct && !hasStatus && (
                <Box sx={{ display: 'flex', gap: 0.75, ml: 1, flexShrink: 0 }}>
                  <Tooltip title={i18n._(t`Schicht tauschen`)}>
                    <IconButton
                      size="small"
                      onClick={() => onRequestSwap(assignment)}
                      sx={{
                        width: 28,
                        height: 28,
                        bgcolor: 'primary.main',
                        color: '#fff',
                        '&:hover': { bgcolor: 'primary.dark' },
                      }}
                    >
                      <SwapHorizIcon sx={{ fontSize: 16 }} />
                    </IconButton>
                  </Tooltip>
                  <Tooltip title={i18n._(t`Vertretung suchen`)}>
                    <IconButton
                      size="small"
                      onClick={() => onRequestReplacement(assignment)}
                      sx={{
                        width: 28,
                        height: 28,
                        bgcolor: 'warning.main',
                        color: '#fff',
                        '&:hover': { bgcolor: 'warning.dark' },
                      }}
                    >
                      <PersonSearchIcon sx={{ fontSize: 16 }} />
                    </IconButton>
                  </Tooltip>
                </Box>
              )}
            </Box>
            {classesV1Enabled && relatedClasses.length > 0 && (
              <Box sx={{ px: 2, pb: 1, pl: 5, display: 'flex', flexDirection: 'column', gap: 0.5 }}>
                {relatedClasses.map((cs: ClassSession) => {
                  const style = styleForSessionStatus(cs.zcs_status);
                  const beckenName: string = cs.becken?.zb_name ?? '';
                  const templateName: string = cs.template?.zct_name ?? `#${cs.zcs_class_template_id}`;
                  return (
                    <Box
                      key={cs.zcs_id}
                      sx={{
                        display: 'flex',
                        alignItems: 'center',
                        gap: 0.75,
                        fontSize: '0.7rem',
                        color: 'text.secondary',
                      }}
                    >
                      <SchoolIcon sx={{ fontSize: 12 }} />
                      {beckenName && (
                        <Typography variant="caption" sx={{ fontWeight: 600, fontSize: '0.7rem' }}>
                          {beckenName}
                        </Typography>
                      )}
                      <Typography variant="caption" sx={{ fontSize: '0.7rem' }} noWrap>
                        {templateName}
                      </Typography>
                      <Chip
                        size="small"
                        label={style.label}
                        sx={{
                          height: 16,
                          fontSize: '0.6rem',
                          backgroundColor: style.bg,
                          color: style.textColor,
                          border: style.border,
                          '& .MuiChip-label': { px: 0.75 },
                        }}
                      />
                    </Box>
                  );
                })}
              </Box>
            )}
            </Box>
          );
        })}
      </Box>
    </WidgetWrapper>
  );
};

export default React.memo(MyShiftsWidget);
