import { useTranslation } from "react-i18next";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { Bell, Check, CheckCheck, Trash2, X } from "lucide-react";
import { api, type AppNotification } from "../lib/api";
import { useLiveQuery } from "../lib/useLiveQuery";

// The durable, server-backed notification center (inbox phase 1). It COEXISTS with the
// client-side transient bell in the nav rail: the bell is a quick peek at recent toasts kept
// in localStorage, this is the full, filterable, clearable history synced from the server.
const POLL_MS = 8000;

function relativeTime(iso: string | null, t: (k: string, o?: any) => string): string {
  if (!iso) return "";
  const then = new Date(iso).getTime();
  const secs = Math.max(0, Math.round((Date.now() - then) / 1000));
  // Reuse the bell's relative-time strings (notifications.time.*) — same format, no dupes.
  if (secs < 60) return t("notifications.time.justNow");
  const mins = Math.round(secs / 60);
  if (mins < 60) return t("notifications.time.minutes", { count: mins });
  const hours = Math.round(mins / 60);
  if (hours < 24) return t("notifications.time.hours", { count: hours });
  const days = Math.round(hours / 24);
  return t("notifications.time.days", { count: days });
}

export default function NotificationsPanel() {
  const { t } = useTranslation();
  const qc = useQueryClient();
  const q = useLiveQuery<{ items: AppNotification[]; total: number }>(
    ["notifications"],
    () => api.notifications(),
    { intervalMs: POLL_MS }
  );
  const items = q.data?.items ?? [];

  // Any mutation refreshes both the list and the nav badge's unread count.
  const refresh = () => {
    qc.invalidateQueries({ queryKey: ["notifications"] });
    qc.invalidateQueries({ queryKey: ["notif-unread"] });
  };
  const readMut = useMutation({ mutationFn: api.markNotificationRead, onSuccess: refresh });
  const readAllMut = useMutation({ mutationFn: api.markAllNotificationsRead, onSuccess: refresh });
  const dismissMut = useMutation({ mutationFn: api.dismissNotification, onSuccess: refresh });
  const clearMut = useMutation({ mutationFn: api.clearNotifications, onSuccess: refresh });

  const hasUnread = items.some((n) => !n.read);

  return (
    <div className="p-4 max-w-3xl w-full mx-auto space-y-4">
      <div className="glass rounded-2xl p-4 flex items-center gap-3">
        <Bell className="w-5 h-5 text-accent shrink-0" />
        <div className="flex-1 min-w-0">
          <div className="font-semibold">{t("inbox.title")}</div>
          <div className="text-xs text-muted">{t("inbox.subtitle")}</div>
        </div>
        {items.length > 0 && (
          <div className="flex items-center gap-2">
            <button
              onClick={() => readAllMut.mutate()}
              disabled={!hasUnread || readAllMut.isPending}
              className="inline-flex items-center gap-1.5 text-xs px-2.5 py-1.5 rounded-lg text-muted hover:text-fg hover:bg-card transition disabled:opacity-40"
            >
              <CheckCheck className="w-4 h-4" />
              {t("inbox.markAllRead")}
            </button>
            <button
              onClick={() => clearMut.mutate()}
              disabled={clearMut.isPending}
              className="inline-flex items-center gap-1.5 text-xs px-2.5 py-1.5 rounded-lg text-muted hover:text-fg hover:bg-card transition disabled:opacity-40"
            >
              <Trash2 className="w-4 h-4" />
              {t("inbox.clearAll")}
            </button>
          </div>
        )}
      </div>

      {q.isLoading && !q.data ? (
        <div className="p-8 text-muted text-center">{t("common.loading")}</div>
      ) : items.length === 0 ? (
        <div className="glass rounded-2xl p-10 text-center text-muted">
          <Bell className="w-8 h-8 mx-auto mb-3 opacity-40" />
          {t("inbox.empty")}
        </div>
      ) : (
        <div className="flex flex-col gap-2">
          {items.map((n) => (
            <NotificationRow
              key={n.id}
              n={n}
              t={t}
              onRead={() => readMut.mutate(n.id)}
              onDismiss={() => dismissMut.mutate(n.id)}
            />
          ))}
        </div>
      )}
    </div>
  );
}

function NotificationRow({
  n,
  t,
  onRead,
  onDismiss,
}: {
  n: AppNotification;
  t: (k: string, o?: any) => string;
  onRead: () => void;
  onDismiss: () => void;
}) {
  // The maintenance producer ships the affected videos in `data.videos`; list a few titles.
  const videos: { id: string; title: string | null }[] = Array.isArray(n.data?.videos)
    ? n.data!.videos
    : [];
  // Known notification types are rendered from i18n (so they're trilingual) using the typed
  // payload; the server-stored title/body are an English fallback for any unknown type.
  const isMaintenance = n.type === "maintenance" && typeof n.data?.count === "number";
  const title = isMaintenance ? t("inbox.maintenance.title") : n.title;
  const body = isMaintenance
    ? t("inbox.maintenance.body", { count: n.data!.count })
    : n.body;
  return (
    <div
      className={`glass rounded-xl p-3.5 flex items-start gap-3 transition ${
        n.read ? "opacity-70" : ""
      }`}
    >
      {!n.read && <span className="mt-1.5 w-2 h-2 rounded-full bg-accent shrink-0" aria-hidden />}
      <div className="flex-1 min-w-0">
        <div className="flex items-baseline gap-2">
          <span className="font-medium text-sm">{title}</span>
          <span className="text-[11px] text-muted shrink-0">
            {relativeTime(n.created_at, t)}
          </span>
        </div>
        {body && <div className="text-sm text-muted mt-0.5">{body}</div>}
        {videos.length > 0 && (
          <ul className="mt-2 text-xs text-muted list-disc pl-4 space-y-0.5">
            {videos.slice(0, 8).map((v) => (
              <li key={v.id} className="truncate">
                {v.title || v.id}
              </li>
            ))}
            {videos.length > 8 && (
              <li className="list-none text-muted/70">
                {t("inbox.andMore", { count: videos.length - 8 })}
              </li>
            )}
          </ul>
        )}
      </div>
      <div className="flex items-center gap-1 shrink-0">
        {!n.read && (
          <button
            onClick={onRead}
            title={t("inbox.markRead")}
            aria-label={t("inbox.markRead")}
            className="p-1.5 rounded-lg text-muted hover:text-fg hover:bg-card transition"
          >
            <Check className="w-4 h-4" />
          </button>
        )}
        <button
          onClick={onDismiss}
          title={t("inbox.dismiss")}
          aria-label={t("inbox.dismiss")}
          className="p-1.5 rounded-lg text-muted hover:text-fg hover:bg-card transition"
        >
          <X className="w-4 h-4" />
        </button>
      </div>
    </div>
  );
}
