import React, { useState, useEffect, useCallback, useRef } from 'react';
import {
  Badge,
  Box,
  Button,
  CircularProgress,
  Divider,
  IconButton,
  List,
  ListItem,
  ListItemButton,
  ListItemText,
  Popover,
  Tooltip,
  Typography,
} from '@mui/material';
import {
  Notifications as BellIcon,
  NotificationsNone as BellEmptyIcon,
  Circle as CircleIcon,
} from '@mui/icons-material';
import { useNavigate } from 'react-router-dom';
import { notificationsApi } from '../../services/notifications';
import type { Notification, NotificationSchwere } from '../../types/notification.types';

const POLL_INTERVAL_MS = 60_000; // 60 seconds

function schwerebColor(schwere: NotificationSchwere): 'error' | 'warning' | 'info' {
  if (schwere === 'fehler') return 'error';
  if (schwere === 'warnung') return 'warning';
  return 'info';
}

function formatRelative(iso: string): string {
  const diff = Date.now() - new Date(iso).getTime();
  const minutes = Math.floor(diff / 60_000);
  if (minutes < 2) return 'Gerade eben';
  if (minutes < 60) return `vor ${minutes} Min.`;
  const hours = Math.floor(minutes / 60);
  if (hours < 24) return `vor ${hours} Std.`;
  const days = Math.floor(hours / 24);
  return `vor ${days} Tag${days !== 1 ? 'en' : ''}`;
}

const NotificationBell: React.FC = () => {
  const navigate = useNavigate();
  const [unreadCount, setUnreadCount] = useState(0);
  const [notifications, setNotifications] = useState<Notification[]>([]);
  const [loadingList, setLoadingList] = useState(false);
  const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
  const pollTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);

  const fetchUnreadCount = useCallback(async () => {
    try {
      const count = await notificationsApi.getUnreadCount();
      setUnreadCount(count);
    } catch {
      // non-critical
    }
  }, []);

  // Poll unread count every 60 seconds
  useEffect(() => {
    fetchUnreadCount();
    pollTimerRef.current = setInterval(fetchUnreadCount, POLL_INTERVAL_MS);
    return () => {
      if (pollTimerRef.current) clearInterval(pollTimerRef.current);
    };
  }, [fetchUnreadCount]);

  const handleOpen = async (event: React.MouseEvent<HTMLElement>) => {
    setAnchorEl(event.currentTarget);
    setLoadingList(true);
    try {
      const data = await notificationsApi.getNotifications();
      setNotifications(data);
      // Refresh count after loading full list
      const count = await notificationsApi.getUnreadCount();
      setUnreadCount(count);
    } catch {
      // non-critical
    } finally {
      setLoadingList(false);
    }
  };

  const handleClose = () => {
    setAnchorEl(null);
  };

  const handleClickNotification = async (n: Notification) => {
    if (!n.gelesen) {
      try {
        await notificationsApi.markRead(n.id);
        setNotifications((prev) =>
          prev.map((item) => item.id === n.id ? { ...item, gelesen: true } : item)
        );
        setUnreadCount((c) => Math.max(0, c - 1));
      } catch {
        // non-critical
      }
    }
    handleClose();
    if (n.link) {
      if (n.link.startsWith('http://') || n.link.startsWith('https://')) {
        window.open(n.link, '_blank');
      } else {
        navigate(n.link);
      }
    }
  };

  const handleMarkAllRead = async () => {
    try {
      await notificationsApi.markAllRead();
      setNotifications((prev) => prev.map((n) => ({ ...n, gelesen: true })));
      setUnreadCount(0);
    } catch {
      // non-critical
    }
  };

  const open = Boolean(anchorEl);
  const hasUnread = unreadCount > 0;

  return (
    <>
      <Tooltip title="Benachrichtigungen">
        <IconButton
          color="inherit"
          onClick={handleOpen}
          aria-label="Benachrichtigungen öffnen"
          size="small"
        >
          <Badge badgeContent={unreadCount} color="error" invisible={!hasUnread}>
            {hasUnread ? <BellIcon /> : <BellEmptyIcon />}
          </Badge>
        </IconButton>
      </Tooltip>

      <Popover
        open={open}
        anchorEl={anchorEl}
        onClose={handleClose}
        anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
        transformOrigin={{ vertical: 'top', horizontal: 'right' }}
        PaperProps={{ sx: { width: 360, maxHeight: 500, display: 'flex', flexDirection: 'column' } }}
      >
        {/* Header */}
        <Box sx={{ px: 2, py: 1.5, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <Typography variant="subtitle1" fontWeight={600}>
            Benachrichtigungen
          </Typography>
          {unreadCount > 0 && (
            <Button size="small" onClick={handleMarkAllRead} sx={{ fontSize: '0.75rem' }}>
              Alle als gelesen markieren
            </Button>
          )}
        </Box>
        <Divider />

        {/* Body */}
        <Box sx={{ overflowY: 'auto', flexGrow: 1 }}>
          {loadingList ? (
            <Box sx={{ display: 'flex', justifyContent: 'center', py: 4 }}>
              <CircularProgress size={28} />
            </Box>
          ) : notifications.length === 0 ? (
            <Box sx={{ textAlign: 'center', py: 4 }}>
              <BellEmptyIcon sx={{ fontSize: 40, color: 'text.disabled', mb: 1 }} />
              <Typography variant="body2" color="text.secondary">
                Keine Benachrichtigungen
              </Typography>
            </Box>
          ) : (
            <List disablePadding>
              {notifications.map((n, idx) => (
                <React.Fragment key={n.id}>
                  {idx > 0 && <Divider component="li" />}
                  <ListItem disablePadding>
                    <ListItemButton
                      onClick={() => handleClickNotification(n)}
                      sx={{
                        py: 1.5,
                        px: 2,
                        bgcolor: n.gelesen ? 'transparent' : 'action.hover',
                        alignItems: 'flex-start',
                        gap: 1,
                      }}
                    >
                      <CircleIcon
                        sx={{
                          fontSize: 8,
                          mt: 0.75,
                          flexShrink: 0,
                          color: n.gelesen ? 'transparent' : `${schwerebColor(n.schwere)}.main`,
                        }}
                      />
                      <ListItemText
                        primary={
                          <Typography variant="body2" fontWeight={n.gelesen ? 400 : 600}>
                            {n.titel}
                          </Typography>
                        }
                        secondary={
                          <Box>
                            <Typography variant="caption" color="text.secondary" display="block">
                              {n.nachricht}
                            </Typography>
                            <Typography variant="caption" color="text.disabled">
                              {formatRelative(n.erstellt_am)}
                            </Typography>
                          </Box>
                        }
                        disableTypography
                      />
                    </ListItemButton>
                  </ListItem>
                </React.Fragment>
              ))}
            </List>
          )}
        </Box>
      </Popover>
    </>
  );
};

export default NotificationBell;
