import { createFileRoute } from "@tanstack/react-router";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useServerFn } from "@tanstack/react-start";
import { useEffect, useState } from "react";
import { toast } from "sonner";
import { Loader2, CheckCheck, Inbox } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Switch } from "@/components/ui/switch";
import { Label } from "@/components/ui/label";
import {
  getNotificationPrefs,
  listNotifications,
  markAllNotificationsRead,
  markNotificationRead,
  updateNotificationPrefs,
  type NotificationPrefs,
} from "@/lib/notifications.functions";

export default function NotificationsPage() {
  const qc = useQueryClient();
  const fetchList = useServerFn(listNotifications);
  const fetchPrefs = useServerFn(getNotificationPrefs);
  const doMark = useServerFn(markNotificationRead);
  const doMarkAll = useServerFn(markAllNotificationsRead);
  const doSetPrefs = useServerFn(updateNotificationPrefs);

  const list = useQuery({
    queryKey: ["notifications"],
    queryFn: () => fetchList({ data: undefined as never }),
  });
  const prefs = useQuery({
    queryKey: ["notification-prefs"],
    queryFn: () => fetchPrefs({ data: undefined as never }),
  });

  const [draft, setDraft] = useState<NotificationPrefs | null>(null);
  useEffect(() => {
    if (prefs.data && !draft) setDraft(prefs.data);
  }, [prefs.data, draft]);

  const savePrefs = useMutation({
    mutationFn: (v: NotificationPrefs) => doSetPrefs({ data: v }),
    onSuccess: () => {
      toast.success("Preferences saved");
      qc.invalidateQueries({ queryKey: ["notification-prefs"] });
    },
    onError: (e: Error) => toast.error(e.message),
  });

  async function markAll() {
    await doMarkAll({ data: undefined as never }).catch(() => {});
    qc.invalidateQueries({ queryKey: ["notifications"] });
  }
  async function mark(id: string) {
    await doMark({ data: { id } }).catch(() => {});
    qc.invalidateQueries({ queryKey: ["notifications"] });
  }

  return (
    <div className="mx-auto max-w-3xl space-y-6 px-6 py-8">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold tracking-tight">Notifications</h1>
          <p className="mt-1 text-sm text-muted-foreground">Recent updates and system events.</p>
        </div>
        <Button variant="outline" size="sm" onClick={markAll}>
          <CheckCheck className="mr-2 h-4 w-4" /> Mark all read
        </Button>
      </div>

      <section className="rounded-xl border bg-card">
        {list.isLoading && (
          <div className="flex justify-center p-8">
            <Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
          </div>
        )}
        {list.data?.length === 0 && (
          <div className="flex flex-col items-center gap-2 p-12 text-center text-sm text-muted-foreground">
            <Inbox className="h-6 w-6" />
            You're all caught up.
          </div>
        )}
        <ul className="divide-y">
          {list.data?.map((n) => (
            <li key={n.id} className={`flex gap-3 p-4 ${!n.read_at ? "bg-primary/5" : ""}`}>
              <div className="mt-1 h-2 w-2 shrink-0 rounded-full bg-primary/70" />
              <div className="min-w-0 flex-1">
                <div className="font-medium">{n.title}</div>
                {n.body && <div className="mt-0.5 text-sm text-muted-foreground">{n.body}</div>}
                <div className="mt-1 text-xs text-muted-foreground">{new Date(n.created_at).toLocaleString()}</div>
              </div>
              {!n.read_at && (
                <Button size="sm" variant="ghost" onClick={() => mark(n.id)}>
                  Mark read
                </Button>
              )}
            </li>
          ))}
        </ul>
      </section>

      <section className="space-y-4 rounded-xl border bg-card p-6">
        <div>
          <h2 className="text-sm font-semibold">Preferences</h2>
          <p className="mt-1 text-xs text-muted-foreground">Choose how you'd like to be notified.</p>
        </div>
        {draft && (
          <div className="space-y-3">
            <PrefRow
              label="In-app notifications"
              description="Show a badge on the bell and inline notifications."
              value={draft.in_app}
              onChange={(v) => setDraft({ ...draft, in_app: v })}
            />
            <PrefRow
              label="Email"
              description="Send important events to your email address."
              value={draft.email}
              onChange={(v) => setDraft({ ...draft, email: v })}
            />
            <PrefRow
              label="Push"
              description="Browser push notifications (coming soon)."
              value={draft.push}
              onChange={(v) => setDraft({ ...draft, push: v })}
            />
            <div className="flex justify-end">
              <Button onClick={() => savePrefs.mutate(draft)} disabled={savePrefs.isPending}>
                {savePrefs.isPending && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
                Save preferences
              </Button>
            </div>
          </div>
        )}
      </section>
    </div>
  );
}

function PrefRow({
  label,
  description,
  value,
  onChange,
}: {
  label: string;
  description: string;
  value: boolean;
  onChange: (v: boolean) => void;
}) {
  return (
    <div className="flex items-start justify-between gap-4">
      <div>
        <Label className="text-sm">{label}</Label>
        <p className="mt-0.5 text-xs text-muted-foreground">{description}</p>
      </div>
      <Switch checked={value} onCheckedChange={onChange} />
    </div>
  );
}

