import React, { useEffect, useState, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import {
  ActionIcon,
  Badge,
  Box,
  Button,
  Card,
  Divider,
  Group,
  Indicator,
  Popover,
  PopoverDropdown,
  PopoverTarget,
  ScrollAreaAutosize,
  Stack,
  Text,
  ThemeIcon,
  Tooltip,
  useMantineTheme,
} from '@mantine/core';
import {
  Bell,
  Check,
  CheckCheck,
  Download,
  ExternalLink,
  Info,
  Settings,
  AlertTriangle,
  Megaphone,
  X,
  Eye,
  EyeOff,
  ArrowRight,
} from 'lucide-react';
import useNotificationsStore from '../store/notifications';
import {
  dismissAllNotifications,
  dismissNotification,
  getNotifications,
} from '../utils/components/NotificationCenterUtils.js';

// Get icon for notification type
const getNotificationIcon = (type) => {
  switch (type) {
    case 'version_update':
      return <Download size={16} />;
    case 'setting_recommendation':
      return <Settings size={16} />;
    case 'announcement':
      return <Megaphone size={16} />;
    case 'warning':
      return <AlertTriangle size={16} />;
    case 'info':
    default:
      return <Info size={16} />;
  }
};

// Get color for notification priority
const getPriorityColor = (priority) => {
  switch (priority) {
    case 'critical':
      return 'red';
    case 'high':
      return 'orange';
    case 'normal':
      return 'blue';
    case 'low':
    default:
      return 'gray';
  }
};

// Get color for notification type
const getTypeColor = (type) => {
  switch (type) {
    case 'version_update':
      return 'green';
    case 'setting_recommendation':
      return 'blue';
    case 'announcement':
      return 'violet';
    case 'warning':
      return 'orange';
    case 'info':
    default:
      return 'gray';
  }
};

// Individual notification item component
const NotificationItem = ({ notification, onDismiss, onAction, onClose }) => {
  const theme = useMantineTheme();
  const navigate = useNavigate();
  const typeColor = getTypeColor(notification.notification_type);
  const priorityColor = getPriorityColor(notification.priority);
  const isDismissed = notification.is_dismissed;

  const handleDismiss = (e) => {
    e.stopPropagation();
    onDismiss(notification.id, 'dismissed');
  };

  const handleAction = () => {
    // Handle action_url from action_data
    const actionUrl = notification.action_data?.action_url;
    const releaseUrl = notification.action_data?.release_url;

    if (actionUrl) {
      // Internal navigation
      onClose(); // Close the popover
      navigate(actionUrl);
    } else if (releaseUrl) {
      // External link
      window.open(releaseUrl, '_blank');
    }

    if (onAction) {
      onAction(notification);
    }
  };

  return (
    <Card
      padding="sm"
      radius="md"
      withBorder
      style={{
        borderLeft: `3px solid ${theme.colors[priorityColor][5]}`,
        backgroundColor:
          notification.priority === 'critical'
            ? theme.colors.red[9] + '10'
            : undefined,
        opacity: isDismissed ? 0.6 : 1,
        position: 'relative',
      }}
    >
      {/* Dismiss button for non-setting notifications (only if not already dismissed) */}
      {notification.notification_type !== 'setting_recommendation' &&
        !isDismissed && (
          <ActionIcon
            variant="subtle"
            color="gray"
            size="sm"
            onClick={handleDismiss}
            style={{ position: 'absolute', top: 8, right: 8 }}
          >
            <X size={14} />
          </ActionIcon>
        )}

      <Group wrap="nowrap" align="flex-start" gap="sm">
        <ThemeIcon color={typeColor} variant="light" size="md" radius="xl">
          {getNotificationIcon(notification.notification_type)}
        </ThemeIcon>
        <Box style={{ flex: 1 }}>
          <Group gap="xs" mb={4}>
            <Text size="sm" fw={600} lineClamp={1}>
              {notification.title}
            </Text>
            {isDismissed && (
              <Badge size="xs" color="gray" variant="light">
                Dismissed
              </Badge>
            )}
            {notification.priority === 'high' ||
            notification.priority === 'critical' ? (
              <Badge size="xs" color={priorityColor} variant="filled">
                {notification.priority}
              </Badge>
            ) : null}
          </Group>
          <Text size="xs" c="dimmed" lineClamp={5}>
            {notification.message}
          </Text>

          {/* Action buttons for specific notification types */}
          {notification.notification_type === 'version_update' &&
            notification.action_data?.release_url && (
              <Button
                size="xs"
                variant="light"
                color="green"
                mt="xs"
                leftSection={<ExternalLink size={12} />}
                onClick={handleAction}
              >
                View Release
              </Button>
            )}

          {/* Generic action button for notifications with action_url/action_text */}
          {notification.action_data?.action_url &&
            notification.action_data?.action_text && (
              <Button
                size="xs"
                variant="light"
                color={typeColor}
                mt="xs"
                rightSection={<ArrowRight size={12} />}
                onClick={handleAction}
              >
                {notification.action_data.action_text}
              </Button>
            )}

          {notification.notification_type === 'setting_recommendation' &&
            !notification.action_data?.action_url && (
              <Group gap="xs" mt="xs">
                <Button
                  size="xs"
                  variant="light"
                  color="blue"
                  onClick={() => {
                    onDismiss(notification.id, 'applied');
                    // Navigate to settings or apply the setting
                    if (onAction) onAction(notification);
                  }}
                >
                  Apply
                </Button>
                <Button
                  size="xs"
                  variant="subtle"
                  color="gray"
                  onClick={handleDismiss}
                >
                  Ignore
                </Button>
              </Group>
            )}
        </Box>
      </Group>

      <Text size="xs" c="dimmed" mt="xs" ta="right">
        {new Date(notification.created_at).toLocaleDateString()}
      </Text>
    </Card>
  );
};

// Main notification center component with bell icon and popover
const NotificationCenter = ({ onSettingAction }) => {
  const [opened, setOpened] = useState(false);
  const [showDismissed, setShowDismissed] = useState(false);

  const notifications = useNotificationsStore((s) => s.notifications);
  const unreadCount = useNotificationsStore((s) => s.unreadCount);
  const getUnreadNotifications = useNotificationsStore(
    (s) => s.getUnreadNotifications
  );

  // Fetch notifications on mount and periodically
  const fetchNotifications = useCallback(async () => {
    try {
      await getNotifications(showDismissed);
    } catch (error) {
      console.error('Failed to fetch notifications:', error);
    }
  }, [showDismissed]);

  useEffect(() => {
    fetchNotifications();

    // Refresh notifications every 5 minutes
    const interval = setInterval(fetchNotifications, 5 * 60 * 1000);
    return () => clearInterval(interval);
  }, [fetchNotifications]);

  const handleDismiss = async (notificationId, actionTaken = null) => {
    try {
      await dismissNotification(notificationId, actionTaken);
    } catch (error) {
      console.error('Failed to dismiss notification:', error);
    }
  };

  const handleDismissAll = async () => {
    try {
      await dismissAllNotifications();
    } catch (error) {
      console.error('Failed to dismiss all notifications:', error);
    }
  };

  const handleAction = (notification) => {
    if (
      notification.notification_type === 'setting_recommendation' &&
      onSettingAction
    ) {
      onSettingAction(notification);
    }
  };

  const unreadNotifications = getUnreadNotifications();
  const displayedNotifications = showDismissed
    ? notifications
    : unreadNotifications;

  return (
    <Popover
      opened={opened}
      onChange={setOpened}
      width={380}
      position="bottom-end"
      shadow="lg"
      withArrow
    >
      <PopoverTarget>
        <Indicator
          color="red"
          size={16}
          label={unreadCount > 9 ? '9+' : unreadCount}
          disabled={unreadCount === 0}
          offset={4}
          processing={unreadCount > 0}
        >
          <ActionIcon
            variant="subtle"
            color="gray"
            size="lg"
            onClick={() => setOpened((o) => !o)}
            aria-label="Notifications"
          >
            <Bell size={20} />
          </ActionIcon>
        </Indicator>
      </PopoverTarget>

      <PopoverDropdown p={0}>
        {/* Header */}
        <Group justify="space-between" p="sm" pb="xs">
          <Group gap="xs">
            <Text fw={600} size="sm">
              Notifications
            </Text>
            {unreadCount > 0 && (
              <Badge size="sm" color="blue" variant="light">
                {unreadCount} new
              </Badge>
            )}
          </Group>
          <Group gap="xs">
            <Tooltip
              label={showDismissed ? 'Hide dismissed' : 'Show dismissed'}
            >
              <ActionIcon
                variant="subtle"
                color="gray"
                size="sm"
                onClick={() => setShowDismissed((prev) => !prev)}
              >
                {showDismissed ? <EyeOff size={16} /> : <Eye size={16} />}
              </ActionIcon>
            </Tooltip>
            {unreadCount > 0 && (
              <Tooltip label="Mark all as read">
                <ActionIcon
                  variant="subtle"
                  color="gray"
                  size="sm"
                  onClick={handleDismissAll}
                >
                  <CheckCheck size={16} />
                </ActionIcon>
              </Tooltip>
            )}
          </Group>
        </Group>

        <Divider />

        {/* Notification list */}
        <ScrollAreaAutosize mah={400} type="auto" offsetScrollbars>
          {displayedNotifications.length === 0 ? (
            <Box p="lg" ta="center">
              <ThemeIcon
                color="gray"
                variant="light"
                size="xl"
                radius="xl"
                mb="sm"
              >
                <Check size={20} />
              </ThemeIcon>
              <Text size="sm" c="dimmed">
                {showDismissed
                  ? 'No dismissed notifications'
                  : 'All caught up!'}
              </Text>
              <Text size="xs" c="dimmed">
                {showDismissed
                  ? 'Dismissed notifications appear here'
                  : 'No new notifications'}
              </Text>
            </Box>
          ) : (
            <Stack gap="xs" p="xs">
              {displayedNotifications.map((notification) => (
                <NotificationItem
                  key={notification.id}
                  notification={notification}
                  onDismiss={handleDismiss}
                  onAction={handleAction}
                  onClose={() => setOpened(false)}
                />
              ))}
            </Stack>
          )}
        </ScrollAreaAutosize>

        {/* Footer with info text */}
        {!showDismissed &&
          notifications.length > unreadNotifications.length && (
            <>
              <Divider />
              <Box p="xs" ta="center">
                <Text size="xs" c="dimmed">
                  {notifications.length - unreadNotifications.length} dismissed
                  notification
                  {notifications.length - unreadNotifications.length !== 1
                    ? 's'
                    : ''}
                </Text>
              </Box>
            </>
          )}
      </PopoverDropdown>
    </Popover>
  );
};

export default NotificationCenter;
