"use client";

import { useCallback, useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import {
  Clock3,
  CheckCircle2,
  PackageCheck,
  XCircle,
  Megaphone,
  BellRing,
  CheckCheck,
  LucideIcon,
} from "lucide-react";
import { TopBar } from "@/components/ui/TopBar";
import { EmptyState } from "@/components/ui/EmptyState";
import { Skeleton } from "@/components/ui/Skeleton";
import {
  fetchNotifications,
  markNotificationRead,
  markAllNotificationsRead,
  NOTIFICATION_POLL_MS,
} from "@/lib/data/notifications";
import { useAuth } from "@/lib/auth/auth-provider";
import { Notification, NotificationType } from "@/lib/types";
import { cn } from "@/lib/cn";
import { useTranslation } from "@/lib/i18n/LanguageProvider";
import { formatDate } from "@/lib/i18n/format-date";
import { Language } from "@/lib/i18n/translations";
import { translateNotification } from "@/lib/i18n/notification-templates";

// Icons/colors mirror StatusPill's existing pending/approved/completed/
// rejected mapping exactly, so a notification and its order's status pill
// always look like the same event, not two different visual languages.
const ICON_BY_TITLE: Record<string, { icon: LucideIcon; className: string }> = {
  "Order Submitted": { icon: Clock3, className: "bg-gold/15 text-gold-dim dark:text-gold-bright" },
  "Payment Approved": { icon: CheckCircle2, className: "bg-teal/15 text-teal-dim dark:text-teal" },
  "Order Completed": { icon: PackageCheck, className: "bg-teal/20 text-teal-dim dark:text-teal" },
  "Payment Rejected": { icon: XCircle, className: "bg-danger/15 text-danger" },
};

const ICON_BY_TYPE: Record<NotificationType, { icon: LucideIcon; className: string }> = {
  order: { icon: Clock3, className: "bg-gold/15 text-gold-dim dark:text-gold-bright" },
  payment: { icon: CheckCircle2, className: "bg-teal/15 text-teal-dim dark:text-teal" },
  user: { icon: BellRing, className: "bg-muted/15 text-muted" },
  system: { icon: BellRing, className: "bg-muted/15 text-muted" },
  broadcast: { icon: Megaphone, className: "bg-gold/15 text-gold-dim dark:text-gold-bright" },
};

function iconFor(n: Notification) {
  return ICON_BY_TITLE[n.title] ?? ICON_BY_TYPE[n.type];
}

function timeAgo(
  iso: string,
  t: (path: string, vars?: Record<string, string | number>) => string,
  language: Language
) {
  const diffMs = Date.now() - new Date(iso).getTime();
  const mins = Math.floor(diffMs / 60000);
  if (mins < 1) return t("notifications.justNow");
  if (mins < 60) return t("notifications.minsAgo", { n: mins });
  const hrs = Math.floor(mins / 60);
  if (hrs < 24) return t("notifications.hoursAgo", { n: hrs });
  const days = Math.floor(hrs / 24);
  if (days < 7) return t("notifications.daysAgo", { n: days });
  return formatDate(iso, language);
}

export default function NotificationsPage() {
  const router = useRouter();
  const { user } = useAuth();
  const { t, language } = useTranslation();
  const [items, setItems] = useState<Notification[]>([]);
  const [loading, setLoading] = useState(true);
  const [markingAll, setMarkingAll] = useState(false);

  const load = useCallback(() => {
    if (!user) return;
    fetchNotifications()
      .then(setItems)
      .finally(() => setLoading(false));
  }, [user]);

  useEffect(() => {
    load();
  }, [load]);

  useEffect(() => {
    if (!user) return;
    // Polling, not a WebSocket/Realtime subscription — see
    // NOTIFICATION_POLL_MS's own comment in lib/data/notifications.ts.
    const interval = setInterval(load, NOTIFICATION_POLL_MS);
    window.addEventListener("focus", load);
    return () => {
      clearInterval(interval);
      window.removeEventListener("focus", load);
    };
  }, [user, load]);

  async function handleTap(n: Notification) {
    if (!n.isRead) {
      setItems((prev) => prev.map((item) => (item.id === n.id ? { ...item, isRead: true } : item)));
      markNotificationRead(n.id).catch(() => load());
    }
    if (n.relatedOrderNumber) {
      router.push(`/orders/${n.relatedOrderNumber}`);
    }
  }

  async function handleMarkAll() {
    if (!user) return;
    setMarkingAll(true);
    setItems((prev) => prev.map((item) => ({ ...item, isRead: true })));
    try {
      await markAllNotificationsRead();
    } finally {
      setMarkingAll(false);
    }
  }

  const unreadCount = items.filter((n) => !n.isRead).length;

  return (
    <div className="flex flex-1 flex-col">
      <TopBar
        title={t("notifications.title")}
        right={
          unreadCount > 0 ? (
            <button
              type="button"
              aria-label={t("notifications.markAllRead")}
              onClick={handleMarkAll}
              disabled={markingAll}
              className="flex h-10 w-10 items-center justify-center rounded-full glass disabled:opacity-50"
            >
              <CheckCheck size={17} strokeWidth={2} />
            </button>
          ) : null
        }
      />

      <div className="flex flex-col gap-3 px-4 pb-8 pt-2">
        {loading ? (
          <>
            <Skeleton className="h-20 w-full !rounded-4xl" />
            <Skeleton className="h-20 w-full !rounded-4xl" />
            <Skeleton className="h-20 w-full !rounded-4xl" />
          </>
        ) : items.length === 0 ? (
          <EmptyState
            icon={BellRing}
            title={t("notifications.empty")}
            description={t("notifications.emptyDesc")}
          />
        ) : (
          items.map((n) => {
            const { icon: Icon, className } = iconFor(n);
            const display = translateNotification(n.title, n.message, language, t);
            return (
              <button
                key={n.id}
                onClick={() => handleTap(n)}
                className={cn(
                  "flex items-start gap-3 rounded-4xl px-4 py-4 text-left active:scale-[0.985] transition-transform",
                  n.isRead ? "glass" : "glass-strong ring-1 ring-gold/30"
                )}
              >
                <span className={cn("flex h-10 w-10 shrink-0 items-center justify-center rounded-2xl", className)}>
                  <Icon size={17} strokeWidth={2} />
                </span>
                <div className="min-w-0 flex-1">
                  <div className="flex items-center gap-2">
                    <h3 className="truncate text-[14px] font-semibold">{display.title}</h3>
                    {!n.isRead && <span className="h-1.5 w-1.5 shrink-0 rounded-full bg-gold-bright" />}
                  </div>
                  <p className="mt-0.5 text-[13px] text-muted">{display.message}</p>
                  <p className="mt-1.5 text-[11px] text-muted/70" suppressHydrationWarning>
                    {timeAgo(n.createdAt, t, language)}
                  </p>
                </div>
              </button>
            );
          })
        )}
      </div>
    </div>
  );
}
