import { useState, useEffect } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { ScrollArea } from '@/components/ui/scroll-area';
import { apiRequest } from '@/lib/queryClient';
import { useToast } from '@/hooks/use-toast';
import {
  Bell,
  BellRing,
  Clock,
  Check,
  AlertCircle,
  Package,
  MapPin,
  Pill,
  User,
  X,
  Settings,
  Eye,
  EyeOff
} from 'lucide-react';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from '@/components/ui/dialog';

interface Notification {
  id: string;
  type: 'order_update' | 'medicine_reminder' | 'appointment' | 'promotion' | 'system' | 'emergency';
  title: string;
  message: string;
  isRead: boolean;
  createdAt: string;
  priority: 'low' | 'medium' | 'high' | 'urgent';
  actionUrl?: string;
  metadata?: {
    orderId?: string;
    medicineId?: string;
    appointmentId?: string;
  };
}

interface NotificationSettings {
  orderUpdates: boolean;
  medicineReminders: boolean;
  promotions: boolean;
  systemAlerts: boolean;
  emergencyAlerts: boolean;
  pushNotifications: boolean;
  emailNotifications: boolean;
  smsNotifications: boolean;
}

interface ClientNotificationsProps {
  userId: string;
}

export function ClientNotifications({ userId }: ClientNotificationsProps) {
  const [showAll, setShowAll] = useState(false);
  const [showSettings, setShowSettings] = useState(false);
  const { toast } = useToast();
  const queryClient = useQueryClient();

  // Fetch notifications
  const { data: notifications = [], isLoading } = useQuery<Notification[]>({
    queryKey: ['/api/notifications', userId],
    initialData: [
      {
        id: '1',
        type: 'order_update',
        title: 'Commande livrée',
        message: 'Votre commande #12345 de Paracétamol a été livrée avec succès.',
        isRead: false,
        createdAt: new Date(Date.now() - 2 * 60 * 1000).toISOString(), // 2 minutes ago
        priority: 'medium',
        metadata: { orderId: '12345' }
      },
      {
        id: '2',
        type: 'medicine_reminder',
        title: 'Rappel médicament',
        message: 'Il est temps de prendre votre Lisinopril (10mg).',
        isRead: false,
        createdAt: new Date(Date.now() - 30 * 60 * 1000).toISOString(), // 30 minutes ago
        priority: 'high',
        metadata: { medicineId: 'med_123' }
      },
      {
        id: '3',
        type: 'promotion',
        title: 'Offre spéciale',
        message: 'Profitez de -20% sur tous les médicaments de première nécessité.',
        isRead: true,
        createdAt: new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString(), // 2 hours ago
        priority: 'low'
      },
      {
        id: '4',
        type: 'system',
        title: 'Maintenance programmée',
        message: 'Le système sera indisponible le 15 décembre de 2h à 4h du matin.',
        isRead: true,
        createdAt: new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(), // 1 day ago
        priority: 'medium'
      },
      {
        id: '5',
        type: 'appointment',
        title: 'Rendez-vous confirmé',
        message: 'Votre consultation télémédecine est confirmée pour demain 14h.',
        isRead: false,
        createdAt: new Date(Date.now() - 4 * 60 * 60 * 1000).toISOString(), // 4 hours ago
        priority: 'high',
        metadata: { appointmentId: 'apt_789' }
      }
    ],
    refetchInterval: 30000 // Refetch every 30 seconds for real-time updates
  });

  // Fetch notification settings
  const { data: settings } = useQuery<NotificationSettings>({
    queryKey: ['/api/notification-settings', userId],
    initialData: {
      orderUpdates: true,
      medicineReminders: true,
      promotions: false,
      systemAlerts: true,
      emergencyAlerts: true,
      pushNotifications: true,
      emailNotifications: true,
      smsNotifications: false
    }
  });

  // Mark notification as read
  const markAsReadMutation = useMutation({
    mutationFn: async (notificationId: string) => {
      return await apiRequest(`/api/notifications/${notificationId}/read`, {
        method: 'PUT'
      });
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['/api/notifications', userId] });
    }
  });

  // Mark all notifications as read
  const markAllAsReadMutation = useMutation({
    mutationFn: async () => {
      return await apiRequest('/api/notifications/mark-all-read', {
        method: 'PUT',
        body: JSON.stringify({ userId })
      });
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['/api/notifications', userId] });
      toast({
        title: "Notifications marquées comme lues",
        description: "Toutes vos notifications ont été marquées comme lues.",
      });
    }
  });

  // Update notification settings
  const updateSettingsMutation = useMutation({
    mutationFn: async (newSettings: Partial<NotificationSettings>) => {
      return await apiRequest('/api/notification-settings', {
        method: 'PUT',
        body: JSON.stringify({ userId, ...newSettings })
      });
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['/api/notification-settings', userId] });
      toast({
        title: "Préférences mises à jour",
        description: "Vos préférences de notification ont été sauvegardées.",
      });
    }
  });

  const unreadCount = notifications.filter(n => !n.isRead).length;
  const displayNotifications = showAll ? notifications : notifications.slice(0, 5);

  const getNotificationIcon = (type: string) => {
    const icons = {
      order_update: Package,
      medicine_reminder: Pill,
      appointment: User,
      promotion: BellRing,
      system: Settings,
      emergency: AlertCircle
    };
    const IconComponent = icons[type as keyof typeof icons] || Bell;
    return <IconComponent className="h-4 w-4" />;
  };

  const getPriorityBadge = (priority: string) => {
    const variants = {
      low: 'bg-gray-100 text-gray-800',
      medium: 'bg-blue-100 text-blue-800',
      high: 'bg-orange-100 text-orange-800',
      urgent: 'bg-red-100 text-red-800'
    };
    
    return (
      <Badge className={variants[priority as keyof typeof variants] || 'bg-gray-100 text-gray-800'}>
        {priority}
      </Badge>
    );
  };

  const formatTimestamp = (timestamp: string) => {
    const date = new Date(timestamp);
    const now = new Date();
    const diffInMinutes = Math.floor((now.getTime() - date.getTime()) / (1000 * 60));
    
    if (diffInMinutes < 1) return 'À l\'instant';
    if (diffInMinutes < 60) return `${diffInMinutes}min`;
    if (diffInMinutes < 24 * 60) return `${Math.floor(diffInMinutes / 60)}h`;
    return `${Math.floor(diffInMinutes / (24 * 60))}j`;
  };

  // Real-time notification updates via WebSocket (simplified)
  useEffect(() => {
    // In a real app, you'd connect to a WebSocket here
    // const ws = new WebSocket(`wss://localhost:5000/notifications/${userId}`);
    // ws.onmessage = (event) => {
    //   const newNotification = JSON.parse(event.data);
    //   queryClient.setQueryData(['/api/notifications', userId], (old: Notification[]) => 
    //     [newNotification, ...old]
    //   );
    //   // Show toast for new notification
    //   toast({
    //     title: newNotification.title,
    //     description: newNotification.message,
    //   });
    // };
    // return () => ws.close();
  }, [userId, queryClient, toast]);

  if (isLoading) {
    return (
      <Card>
        <CardContent className="p-6">
          <div className="animate-pulse space-y-4">
            <div className="h-4 bg-gray-200 rounded w-1/3"></div>
            <div className="h-4 bg-gray-200 rounded w-1/2"></div>
            <div className="h-4 bg-gray-200 rounded w-2/3"></div>
          </div>
        </CardContent>
      </Card>
    );
  }

  return (
    <Card>
      <CardHeader>
        <div className="flex items-center justify-between">
          <CardTitle className="flex items-center gap-2">
            <Bell className="h-5 w-5" />
            Notifications
            {unreadCount > 0 && (
              <Badge variant="destructive" className="ml-2">
                {unreadCount}
              </Badge>
            )}
          </CardTitle>
          <div className="flex items-center gap-2">
            {unreadCount > 0 && (
              <Button
                variant="outline"
                size="sm"
                onClick={() => markAllAsReadMutation.mutate()}
                disabled={markAllAsReadMutation.isPending}
                data-testid="button-mark-all-read"
              >
                <Check className="h-4 w-4 mr-1" />
                Tout marquer lu
              </Button>
            )}
            <Dialog open={showSettings} onOpenChange={setShowSettings}>
              <DialogTrigger asChild>
                <Button variant="outline" size="sm" data-testid="button-notification-settings">
                  <Settings className="h-4 w-4" />
                </Button>
              </DialogTrigger>
              <DialogContent>
                <DialogHeader>
                  <DialogTitle>Préférences de notification</DialogTitle>
                  <DialogDescription>
                    Configurez vos préférences de notification.
                  </DialogDescription>
                </DialogHeader>
                <div className="space-y-4">
                  {settings && Object.entries(settings).map(([key, value]) => (
                    <div key={key} className="flex items-center justify-between">
                      <span className="text-sm">
                        {key === 'orderUpdates' && 'Mises à jour des commandes'}
                        {key === 'medicineReminders' && 'Rappels de médicaments'}
                        {key === 'promotions' && 'Promotions'}
                        {key === 'systemAlerts' && 'Alertes système'}
                        {key === 'emergencyAlerts' && 'Alertes d\'urgence'}
                        {key === 'pushNotifications' && 'Notifications push'}
                        {key === 'emailNotifications' && 'Notifications email'}
                        {key === 'smsNotifications' && 'Notifications SMS'}
                      </span>
                      <Button
                        variant={value ? "default" : "outline"}
                        size="sm"
                        onClick={() => updateSettingsMutation.mutate({ [key]: !value })}
                      >
                        {value ? <Eye className="h-4 w-4" /> : <EyeOff className="h-4 w-4" />}
                      </Button>
                    </div>
                  ))}
                </div>
              </DialogContent>
            </Dialog>
          </div>
        </div>
      </CardHeader>
      <CardContent>
        <ScrollArea className="h-96">
          <div className="space-y-3">
            {displayNotifications.map((notification) => (
              <div
                key={notification.id}
                className={`p-3 border rounded-lg transition-colors hover:bg-gray-50 ${
                  !notification.isRead ? 'bg-blue-50 border-blue-200' : ''
                }`}
                data-testid={`notification-${notification.id}`}
              >
                <div className="flex items-start justify-between">
                  <div className="flex items-start gap-3 flex-1">
                    <div className={`p-1.5 rounded-full ${
                      !notification.isRead ? 'bg-blue-100 text-blue-600' : 'bg-gray-100 text-gray-600'
                    }`}>
                      {getNotificationIcon(notification.type)}
                    </div>
                    <div className="flex-1">
                      <div className="flex items-center gap-2 mb-1">
                        <h4 className={`font-medium ${!notification.isRead ? 'text-blue-900' : ''}`}>
                          {notification.title}
                        </h4>
                        {getPriorityBadge(notification.priority)}
                      </div>
                      <p className="text-sm text-muted-foreground mb-2">
                        {notification.message}
                      </p>
                      <div className="flex items-center gap-2 text-xs text-muted-foreground">
                        <Clock className="h-3 w-3" />
                        {formatTimestamp(notification.createdAt)}
                      </div>
                    </div>
                  </div>
                  <div className="flex items-center gap-1">
                    {!notification.isRead && (
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => markAsReadMutation.mutate(notification.id)}
                        disabled={markAsReadMutation.isPending}
                        data-testid={`button-mark-read-${notification.id}`}
                      >
                        <Check className="h-4 w-4" />
                      </Button>
                    )}
                    {notification.actionUrl && (
                      <Button variant="ghost" size="sm">
                        <Eye className="h-4 w-4" />
                      </Button>
                    )}
                  </div>
                </div>
              </div>
            ))}
          </div>
        </ScrollArea>

        {notifications.length > 5 && (
          <div className="mt-4 text-center">
            <Button
              variant="outline"
              onClick={() => setShowAll(!showAll)}
              data-testid="button-toggle-show-all"
            >
              {showAll ? 'Voir moins' : `Voir toutes (${notifications.length})`}
            </Button>
          </div>
        )}

        {notifications.length === 0 && (
          <div className="text-center py-8">
            <Bell className="h-12 w-12 text-muted-foreground mx-auto mb-4" />
            <h3 className="font-medium text-muted-foreground mb-2">
              Aucune notification
            </h3>
            <p className="text-sm text-muted-foreground">
              Vous n'avez aucune notification pour le moment.
            </p>
          </div>
        )}
      </CardContent>
    </Card>
  );
}