import { useEffect, useState } from "react";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "~/components/ui/card";
import { Switch } from "~/components/ui/switch";
import { Button } from "~/components/ui/button";
import { Badge } from "~/components/ui/badge";
import { Separator } from "~/components/ui/separator";
import {
  Bell,
  Smartphone,
  Trash2,
  Send,
  AlertTriangle,
  Loader,
  Save,
} from "lucide-react";
import InstallApp, { isInstalled } from "./install-app";
import {
  isNotificationEnabled,
  registerNotification,
  STORAGE_KEY,
  unregisterNotification,
} from "~/lib/notification";
import {
  testNotification,
  unsubscribe,
  updateSubscription,
  useNotifications,
  type Event,
} from "~/lib/api";
import { toast } from "sonner";

const EVENTS = [
  {
    id: "SYSTEM",
    label: "Système",
    description:
      "Soyez informé des mises à jour et des nouveautés de Khollisé.",
  },
  {
    id: "COLLE_ADDED",
    label: "Colle ajoutée",
    description:
      "Recevez une notification lorsqu'une nouvelle colle est ajoutée par votre CDT.",
  },
  {
    id: "COLLE_REMOVED",
    label: "Colle supprimée",
    description: "Recevez une notification lorsqu'une colle est supprimée.",
  },
  {
    id: "COLLE_UPDATED",
    label: "Colle modifiée",
    description:
      "Soyez averti lorsqu'un colleur modifie le contenu d'une colle.",
  },

  {
    id: "GRADE_ADDED",
    label: "Note ajoutée",
    description: "Recevez une notification lorsqu'une colle est notée.",
  },
  {
    id: "GRADE_UPDATED",
    label: "Note modifiée",
    description: "Soyez averti lorsqu'une note est modifiée.",
  },

  {
    id: "ROOM_UPDATED",
    label: "Salle modifiée",
    description: "Soyez averti lorsqu'une colle change de salle.",
  },
];

export default function NotificationSettings() {
  const [pushEnabled, setPushEnabled] = useState(isNotificationEnabled());
  const [isRegistering, setIsRegistering] = useState(false);

  async function togglePushEnabled() {
    setIsRegistering(true);
    if (pushEnabled) {
      // Unregister notifications
      try {
        await unregisterNotification();
        setPushEnabled(false);
      } catch (error) {
        console.error("Failed to unregister notifications:", error);
      } finally {
        setIsRegistering(false);
      }
    } else {
      // Register notifications
      try {
        const result = await registerNotification();
        if ("error" in result && result.error) {
          console.error(
            "Failed to unregister previous notifications:",
            result.error
          );
        } else {
          setPushEnabled(true);
        }
      } catch (error) {
        console.error("Failed to unregister previous notifications:", error);
      } finally {
        setIsRegistering(false);
      }
    }

    await refetch();
  }

  const [events, setEvents] = useState<Event[]>([]);
  // TODO: Loader and error handling
  const { notifications, isError, isLoading, refetch } = useNotifications();

  const toggleEvent = (eventId: string) => {
    setEvents(
      events.map((event) =>
        event.id === eventId ? { ...event, enabled: !event.enabled } : event
      )
    );
  };
  const hasEvent = (eventId: string) => {
    return events.some((event) => event.id === eventId && event.enabled);
  };

  const currentSubscriptionId = localStorage.getItem(STORAGE_KEY);
  const currentSubscription = notifications.find(
    (sub) => sub.id.toString() === currentSubscriptionId
  );
  useEffect(() => {
    setEvents(currentSubscription?.events || []);
    // Remove pushEnabled if no current subscription (i.e., user unsubscribed)
    if (!isLoading && !isError && pushEnabled && !currentSubscription) {
      setPushEnabled(false);
      localStorage.removeItem(STORAGE_KEY);
    }
  }, [currentSubscription]);

  async function handleDelete(subscriptionId: string) {
    try {
      await unsubscribe(subscriptionId);
      if (subscriptionId === currentSubscriptionId) {
        localStorage.removeItem(STORAGE_KEY);
      }
      await refetch();
      toast.success("L'appareil a été désabonné des notifications.");
    } catch (error) {
      console.error("Failed to unsubscribe:", error);
      toast.error("Échec de la désinscription de l'appareil.");
    }
  }

  return (
    <div className="max-w-4xl mx-auto space-y-6 sm:space-y-8">
      <div className="space-y-2">
        <h1 className="text-2xl sm:text-3xl font-bold tracking-tight">
          Paramètres de notifications
        </h1>
        <p className="text-sm sm:text-base text-muted-foreground">
          Gérez vos préférences de notification et vos appareils abonnés.
        </p>
      </div>

      {/* Enable Push Notifications Section */}
      <Card>
        <CardHeader>
          <div className="flex items-center gap-2">
            <Bell className="h-5 w-5" />
            <CardTitle>Activer les notifications</CardTitle>
          </div>
          <CardDescription>
            Autorisez cette application à vous envoyer des notifications push.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          {isInstalled() ? (
            pushEnabled ? (
              <div className="flex items-start sm:items-center justify-between gap-4">
                <div className="space-y-1 flex-1">
                  <p className="font-medium text-sm sm:text-base">
                    Notifications
                  </p>
                  <p className="text-xs sm:text-sm text-muted-foreground">
                    Recevez des notifications même lorsque l’application est
                    fermée.
                  </p>
                </div>
                <Switch
                  checked={pushEnabled}
                  onCheckedChange={togglePushEnabled}
                  disabled={isRegistering}
                  className="flex-shrink-0"
                />
              </div>
            ) : (
              <Button
                variant="outline"
                className="w-full"
                onClick={togglePushEnabled}
                disabled={isRegistering}
              >
                {isRegistering ? (
                  <span className="flex items-center gap-2">
                    <Loader className="animate-spin h-4 w-4" />
                    Activation...
                  </span>
                ) : (
                  <span className="flex items-center gap-2">
                    <Bell className="h-4 w-4" />
                    Activer les notifications
                  </span>
                )}
              </Button>
            )
          ) : (
            <InstallApp />
          )}
        </CardContent>
      </Card>

      {/* Select Notification Events Section */}
      {currentSubscription && (
        <Card>
          <CardHeader>
            <CardTitle>Configurer vos notifications</CardTitle>
            <CardDescription>
              Choisissez les événements qui déclencheront une notification.
            </CardDescription>
          </CardHeader>
          <CardContent>
            <div className="space-y-3 sm:space-y-4">
              {EVENTS.map((event, index) => (
                <div key={event.id}>
                  <div className="flex items-start sm:items-center justify-between py-2 gap-4">
                    <div className="space-y-1 flex-1 min-w-0">
                      <p className="font-medium text-sm sm:text-base">
                        {event.label}
                      </p>
                      <p className="text-xs sm:text-sm text-muted-foreground leading-relaxed">
                        {event.description}
                      </p>
                    </div>
                    <Switch
                      checked={hasEvent(event.id)}
                      onCheckedChange={() => toggleEvent(event.id)}
                      aria-label={`Toggle ${event.label} notifications`}
                      className="flex-shrink-0"
                    />
                  </div>
                  {index < events.length - 1 && (
                    <Separator className="mt-3 sm:mt-4" />
                  )}
                </div>
              ))}
              <Button
                variant="outline"
                className="w-full mt-4"
                onClick={() =>
                  updateSubscription(
                    currentSubscription.id,
                    events.filter((e) => e.enabled).map((e) => e.id)
                  )
                    .then(() => {
                      toast.success(
                        "Vos préférences de notification ont été mises à jour."
                      );
                    })
                    .catch((error) => {
                      console.error("Failed to update subscription:", error);
                      toast.error(
                        "Échec de la mise à jour des préférences de notification."
                      );
                    })
                }
              >
                <Save className="h-4 w-4 mr-2" />
                Enregistrer
              </Button>
            </div>
          </CardContent>
        </Card>
      )}

      {/* Manage Subscriptions Section */}
      <Card>
        <CardHeader>
          <CardTitle>Manage Subscriptions</CardTitle>
          <CardDescription>
            View and manage devices that can receive notifications
          </CardDescription>
        </CardHeader>
        <CardContent>
          <div className="space-y-3 sm:space-y-4">
            {notifications.map((subscription, index) => (
              <div key={subscription.id}>
                <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-3 sm:gap-4">
                  <div className="flex items-center gap-3 flex-1 min-w-0">
                    <div className="flex-shrink-0">
                      <Smartphone className="h-4 w-4 sm:h-5 sm:w-5 text-muted-foreground" />
                    </div>
                    <div className="space-y-1 flex-1 min-w-0">
                      <div className="flex items-center gap-2 flex-wrap">
                        <p className="font-medium text-sm sm:text-base truncate">
                          {subscription.device}
                        </p>
                        {subscription.enabled ? (
                          <Badge variant="secondary" className="text-xs">
                            Active
                          </Badge>
                        ) : (
                          <Badge
                            variant="destructive"
                            className="flex items-center gap-1 text-xs"
                          >
                            <AlertTriangle className="h-3 w-3" />
                            Revoked
                          </Badge>
                        )}
                      </div>
                    </div>
                  </div>
                  <div className="flex items-center gap-2 sm:gap-2 self-start sm:self-center">
                    <Button
                      variant="outline"
                      size="sm"
                      disabled={!subscription.enabled}
                      onClick={() => {
                        testNotification(subscription.id)
                          .then(() => {
                            toast.success(
                              "Vous allez recevoir une notification de test sur votre appareil..."
                            );
                          })
                          .catch((error) => {
                            console.error(
                              "Failed to send test notification:",
                              error
                            );
                            toast.error(
                              "Échec de l'envoi de la notification de test."
                            );
                          });
                      }}
                      className="flex items-center gap-1 bg-transparent text-xs sm:text-sm px-2 sm:px-3"
                    >
                      <Send className="h-3 w-3 sm:h-4 sm:w-4" />
                      <span className="hidden xs:inline">Test</span>
                    </Button>
                    <Button
                      variant="outline"
                      size="sm"
                      className="flex items-center gap-1 text-destructive hover:text-destructive bg-transparent text-xs sm:text-sm px-2 sm:px-3"
                      onClick={() => handleDelete(subscription.id)}
                    >
                      <Trash2 className="h-3 w-3 sm:h-4 sm:w-4" />
                      <span className="hidden xs:inline">Delete</span>
                    </Button>
                  </div>
                </div>
                {index < notifications.length - 1 && (
                  <Separator className="mt-3 sm:mt-4" />
                )}
              </div>
            ))}

            {notifications.length === 0 && (
              <div className="text-center py-6 sm:py-8 text-muted-foreground">
                <Bell className="h-10 w-10 sm:h-12 sm:w-12 mx-auto mb-3 sm:mb-4 opacity-50" />
                <p className="text-sm sm:text-base">
                  Aucun appareil n'est actuellement abonné aux notifications.
                </p>
                <p className="text-xs sm:text-sm">
                  Vous pouvez activer les notifications pour recevoir des
                  alertes sur vos appareils.
                </p>
              </div>
            )}
          </div>
        </CardContent>
      </Card>
    </div>
  );
}
