import { useCallback, useEffect, useMemo, useState } from "react";
import { useNavigate } from "@tanstack/react-router";
import {
  AlertTriangle,
  Bell,
  CheckCircle2,
  CircleDot,
  FileStack,
  HelpCircle,
  MessageSquareReply,
  Upload,
} from "lucide-react";
import type { AuthPlatform } from "@/lib/auth";
import { getSession } from "@/lib/auth";
import {
  fetchNotifications,
  markAllNotificationsRead,
  markNotificationRead,
  notificationNavigation,
  notificationRelativeTime,
  type AppNotification,
} from "@/lib/notifications-api";
import { Button } from "@/components/ui/button";
import { EmptyState, PageHeader, SectionCard } from "@/components/ledger/Primitives";
import { cn } from "@/lib/utils";

function iconFor(type: string) {
  switch (type) {
    case "DOCUMENT_UPLOADED":
      return { Icon: Upload, className: "bg-muted text-muted-foreground" };
    case "DOCUMENT_NEEDS_REVIEW":
    case "AI_ADVICE_REQUIRES_APPROVAL":
      return { Icon: AlertTriangle, className: "bg-attention-soft text-attention" };
    case "ACCOUNTANT_QUESTION":
      return { Icon: HelpCircle, className: "bg-attention-soft text-attention" };
    case "QUESTION_ANSWERED":
      return { Icon: MessageSquareReply, className: "bg-primary-soft text-primary" };
    case "INVOICE_APPROVED":
    case "DOCUMENT_READY":
    case "SNLSTART_SYNC_SUCCESS":
      return { Icon: CheckCircle2, className: "bg-success-soft text-success" };
    case "INVOICE_REJECTED":
    case "SNLSTART_SYNC_FAILED":
      return { Icon: AlertTriangle, className: "bg-destructive-soft text-destructive" };
    case "CLIENT_REMINDER":
      return { Icon: CircleDot, className: "bg-brand-soft text-brand" };
    default:
      return { Icon: FileStack, className: "bg-muted text-muted-foreground" };
  }
}

function startOfToday(): number {
  const d = new Date();
  d.setHours(0, 0, 0, 0);
  return d.getTime();
}

export function NotificationsPage({ platform }: { platform: AuthPlatform }) {
  const navigate = useNavigate();
  const session = getSession(platform);
  const [items, setItems] = useState<AppNotification[]>([]);
  const [filter, setFilter] = useState<"all" | "unread">("all");
  const [loading, setLoading] = useState(true);

  const refresh = useCallback(async () => {
    if (!session?.email) return;
    setLoading(true);
    try {
      const data = await fetchNotifications(platform, session.email, {
        clientId: session.clientId,
        unreadOnly: filter === "unread",
        limit: 100,
      });
      setItems(data.items);
    } catch {
      setItems([]);
    } finally {
      setLoading(false);
    }
  }, [platform, session?.email, session?.clientId, filter]);

  useEffect(() => {
    void refresh();
  }, [refresh]);

  const groups = useMemo(() => {
    const today: AppNotification[] = [];
    const earlier: AppNotification[] = [];
    const cutoff = startOfToday();
    for (const n of items) {
      const t = Date.parse(n.created_at);
      if (!Number.isNaN(t) && t >= cutoff) today.push(n);
      else earlier.push(n);
    }
    return { today, earlier };
  }, [items]);

  const onOpen = async (n: AppNotification) => {
    if (!session?.email) return;
    if (!n.is_read) {
      try {
        await markNotificationRead(platform, session.email, n.id, session.clientId);
      } catch {
        // continue
      }
    }
    const nav = notificationNavigation(platform, n);
    void navigate({ to: nav.to as never, params: nav.params as never });
  };

  const onMarkAll = async () => {
    if (!session?.email) return;
    await markAllNotificationsRead(platform, session.email, session.clientId);
    await refresh();
  };

  return (
    <div className="space-y-6">
      <PageHeader
        eyebrow={platform === "firm" ? "Firm" : "Client"}
        title="Notifications"
        subtitle="Actions and updates that need your awareness."
        actions={
          <Button variant="outline" size="sm" onClick={() => void onMarkAll()}>
            Mark all as read
          </Button>
        }
      />

      <div className="flex gap-1.5">
        {(["all", "unread"] as const).map((key) => (
          <button
            key={key}
            type="button"
            onClick={() => setFilter(key)}
            className={cn(
              "rounded-full px-3 py-1.5 text-[12px] font-medium transition-colors",
              filter === key
                ? "bg-primary text-primary-foreground"
                : "bg-muted text-muted-foreground hover:text-foreground",
            )}
          >
            {key === "all" ? "All" : "Unread"}
          </button>
        ))}
      </div>

      {loading ? (
        <SectionCard>
          <p className="px-5 py-10 text-center text-[13.5px] text-muted-foreground">Loading…</p>
        </SectionCard>
      ) : items.length === 0 ? (
        <SectionCard>
          <EmptyState
            icon={Bell}
            title={filter === "unread" ? "No unread notifications" : "No notifications yet"}
            description="When something needs your attention, it will show up here."
          />
        </SectionCard>
      ) : (
        <div className="space-y-4">
          {groups.today.length > 0 ? (
            <SectionCard title="Today">
              <NotificationList items={groups.today} onOpen={onOpen} />
            </SectionCard>
          ) : null}
          {groups.earlier.length > 0 ? (
            <SectionCard title="Earlier">
              <NotificationList items={groups.earlier} onOpen={onOpen} />
            </SectionCard>
          ) : null}
        </div>
      )}
    </div>
  );
}

function NotificationList({
  items,
  onOpen,
}: {
  items: AppNotification[];
  onOpen: (n: AppNotification) => void;
}) {
  return (
    <ul className="divide-y divide-border">
      {items.map((n) => {
        const { Icon, className } = iconFor(n.type);
        return (
          <li key={n.id}>
            <button
              type="button"
              onClick={() => onOpen(n)}
              className={cn(
                "flex w-full items-start gap-3 px-5 py-3.5 text-left transition-colors hover:bg-brand-soft/40",
                !n.is_read && "bg-brand-soft/20",
              )}
            >
              <span
                className={cn(
                  "mt-0.5 flex size-9 shrink-0 items-center justify-center rounded-full",
                  className,
                )}
              >
                <Icon size={16} aria-hidden="true" />
              </span>
              <div className="min-w-0 flex-1">
                <div className="flex flex-wrap items-center gap-2">
                  <p className={cn("text-[14px] text-foreground", !n.is_read ? "font-semibold" : "font-medium")}>
                    {n.title}
                  </p>
                  {n.priority === "high" ? (
                    <span className="rounded-full bg-attention-soft px-2 py-0.5 text-[10px] font-semibold text-attention">
                      Important
                    </span>
                  ) : null}
                  {!n.is_read ? (
                    <span className="size-1.5 rounded-full bg-brand" aria-label="Unread" />
                  ) : null}
                </div>
                <p className="mt-0.5 text-[13px] leading-5 text-muted-foreground">{n.message}</p>
                <p className="mt-1 text-[12px] text-muted-foreground">
                  {notificationRelativeTime(n.created_at)}
                </p>
              </div>
            </button>
          </li>
        );
      })}
    </ul>
  );
}
