"use client";

import { useEffect, useState } from "react";
import Image from "next/image";
import Link from "next/link";
import { m } from "framer-motion";
import Select from "react-select";
import {
  ArrowDownLeft,
  ArrowUpRight,
  BarChart3,
  CheckCircle2,
  Clock,
  Eye,
  EyeOff,
  FileText,
  Pin,
  Receipt,
  Send,
  ShieldAlert,
  TrendingUp,
  UserCheck,
  Users,
  Wallet,
  XCircle,
  Building2,
  ChevronLeft,
  ChevronRight,
  ShieldCheck,
  Bell,
  LineChart as LucideLineChart,
  PieChart as LucidePieChart,
} from "lucide-react";
import {
  LineChart, Line, BarChart, Bar, PieChart, Pie, Cell,
  XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer,
} from "recharts";
import { Container } from "@/components/common/Container";
import { Card, CardContent } from "@/components/common/Card";
import { StatCard } from "@/components/app/StatCard";
import { DashboardStatCarousel } from "@/components/app/DashboardStatCarousel";
import { ButtonLink } from "@/components/common/Button";
import { WarningToast } from "@/components/common/WarningToast";
import { AgentVerifyBanner } from "@/components/agent/AgentVerifyBanner";
import { cn } from "@/lib/utils";
import { useAgentAuth } from "@/hooks/useAgentAuth";
import { useAgentDashboard, type DashboardTransaction } from "@/hooks/queries/useAgentDashboard";
import { useAgentNotifications } from "@/hooks/queries/useAgentNotifications";
import { useAgentNotificationState, notifKey } from "@/hooks/useAgentNotificationState";
import { useTranslation } from "@/hooks/useTranslation";
import type { KycStatus } from "@/types";

const AGENT_TWO_FA_DISMISS_KEY = "xremit_agent_2fa_nudge_dismissed";

// --- Helpers ------------------------------------------------------------------

function fmt(amount: number, currency = "USD") {
  return new Intl.NumberFormat("en-US", {
    style: "currency",
    currency,
    maximumFractionDigits: 2,
  }).format(amount);
}

function relativeTime(date: Date): string {
  const diff = Date.now() - date.getTime();
  const mins = Math.floor(diff / 60000);
  if (mins < 1) return "Just now";
  if (mins < 60) return `${mins}m ago`;
  const hrs = Math.floor(mins / 60);
  if (hrs < 24) return `${hrs}h ago`;
  return `${Math.floor(hrs / 24)}d ago`;
}

// --- Animations ---------------------------------------------------------------

const containerVariants = {
  hidden: { opacity: 0 },
  visible: {
    opacity: 1,
    transition: {
      staggerChildren: 0.08,
      delayChildren: 0.05,
    },
  },
};

const itemVariants = {
  hidden: { opacity: 0, y: 15 },
  visible: { opacity: 1, y: 0, transition: { type: "spring", stiffness: 300, damping: 24 } },
};

// --- Status styles ------------------------------------------------------------

const STATUS_STYLES: Record<string, string> = {
  "confirm payment":
    "bg-emerald-50 text-emerald-700 ring-1 ring-emerald-600/20 dark:bg-emerald-500/10 dark:text-emerald-400 dark:ring-emerald-400/20",
  confirmed:
    "bg-emerald-50 text-emerald-700 ring-1 ring-emerald-600/20 dark:bg-emerald-500/10 dark:text-emerald-400 dark:ring-emerald-400/20",
  pending:
    "bg-amber-50 text-amber-700 ring-1 ring-amber-600/20 dark:bg-amber-500/10 dark:text-amber-400 dark:ring-amber-400/20",
  processing:
    "bg-brand-50 text-brand-700 ring-1 ring-brand-600/20 dark:bg-brand-500/10 dark:text-brand-400 dark:ring-brand-400/20",
  cancelled:
    "bg-slate-100 text-slate-600 ring-1 ring-slate-500/20 dark:bg-slate-800 dark:text-slate-400 dark:ring-slate-400/20",
  failed:
    "bg-rose-50 text-rose-700 ring-1 ring-rose-600/20 dark:bg-rose-500/10 dark:text-rose-400 dark:ring-rose-400/20",
};

function statusStyle(status: string) {
  return STATUS_STYLES[status.toLowerCase()] ?? STATUS_STYLES.pending;
}

// --- KYC badge ------------------------------------------------------------------

const KYC_BADGE: Record<KycStatus, { icon: typeof ShieldCheck; labelKey: string; on: boolean }> = {
  verified: { icon: ShieldCheck, labelKey: "app.profile.kycVerified", on: true },
  pending: { icon: ShieldAlert, labelKey: "app.profile.kycPending", on: false },
  rejected: { icon: ShieldAlert, labelKey: "app.profile.kycRejected", on: false },
  unverified: { icon: ShieldAlert, labelKey: "app.profile.kycUnverified", on: false },
};

// --- Activity Chart (Recharts) ------------------------------------------------

interface ChartSeries {
  key: string;
  label: string;
  color: string;
  values: number[];
}

type ChartType = "line" | "bar" | "pie";

const CHART_TYPES = [
  { type: "line" as ChartType, icon: LucideLineChart, key: "chartLine" },
  { type: "bar"  as ChartType, icon: BarChart3,       key: "chartBar"  },
  { type: "pie"  as ChartType, icon: LucidePieChart,  key: "chartPie"  },
] as const;

interface TooltipPayload {
  color: string;
  name: string;
  value: number;
  dataKey: string;
}

function ChartTooltip({ active, payload, label }: {
  active?: boolean;
  payload?: TooltipPayload[];
  label?: string;
}) {
  if (!active || !payload?.length) return null;
  return (
    <div className="rounded-xl border border-slate-200 bg-white p-3 shadow-lg dark:border-slate-800 dark:bg-slate-950">
      <p className="mb-1.5 text-xs font-semibold text-slate-400">{label}</p>
      {payload.map((p) => (
        <div key={p.dataKey} className="flex items-center gap-2 text-xs">
          <span className="inline-block h-2 w-2 rounded-full" style={{ background: p.color }} />
          <span className="text-slate-500 dark:text-slate-400">{p.name}:</span>
          <span className="font-bold text-slate-900 dark:text-white">{p.value.toLocaleString()}</span>
        </div>
      ))}
    </div>
  );
}

function ActivityChart({
  categories,
  series,
}: {
  categories: string[];
  series: ChartSeries[];
}) {
  const { t, dir } = useTranslation();
  const [chartType, setChartType] = useState<ChartType>("pie");

  const data = categories.map((cat, i) => ({
    name: cat.slice(0, 3),
    ...Object.fromEntries(series.map((s) => [s.key, s.values[i] ?? 0])),
  }));

  const pieData = series.map((s) => ({
    name: s.label,
    value: s.values.reduce((a, b) => a + b, 0),
    color: s.color,
  }));

  const hasData = pieData.some((d) => d.value > 0);

  const axisTick = { fill: "#94a3b8", fontSize: 11 };
  const gridProps = { stroke: "rgba(148,163,184,0.12)", strokeDasharray: "3 3" as const };
  const margin = { top: 5, right: 10, left: -20, bottom: 0 };

  return (
    <div className="flex h-full flex-col">
      <div className="mb-5 flex shrink-0 gap-1 rounded-xl bg-slate-100 p-1 dark:bg-slate-800/60">
        {CHART_TYPES.map(({ type, icon: Icon, key }) => (
          <button
            key={type}
            type="button"
            onClick={() => setChartType(type)}
            className={cn(
              "flex flex-1 items-center justify-center gap-1.5 rounded-lg py-1.5 text-xs font-semibold transition-all",
              chartType === type
                ? "bg-white text-slate-900 shadow-sm dark:bg-slate-700 dark:text-white"
                : "text-slate-500 hover:text-slate-700 dark:text-slate-400 dark:hover:text-slate-200",
            )}
          >
            <Icon className={cn("icon-sm", type === "line" && dir === "rtl" && "[transform:scaleX(-1)]")} />
            <span className="hidden sm:inline">{t(`agent.dashboard.${key}`)}</span>
          </button>
        ))}
      </div>

      {!hasData ? (
        <div className="flex flex-1 flex-col items-center justify-center gap-3 px-6 text-center">
          <div>
            <p className="text-sm font-semibold text-slate-700 dark:text-slate-200">
              {t("agent.dashboard.noActivityData")}
            </p>
            <p className="mt-1 text-xs text-slate-500 dark:text-slate-400">
              {t("agent.dashboard.noActivityDataDesc")}
            </p>
          </div>
          <ButtonLink href="/agent/send-remittance" size="sm" className="mt-1">
            <Send className={cn("icon-sm", dir === "rtl" && "[transform:scaleX(-1)]")} />
            {t("agent.dashboard.sendRemittance")}
          </ButtonLink>
        </div>
      ) : (
      <>
      <div className="min-h-[200px] flex-1">
      <ResponsiveContainer width="100%" height="100%">
        {chartType === "line" ? (
          <LineChart data={data} margin={margin}>
            <CartesianGrid {...gridProps} />
            <XAxis dataKey="name" tick={axisTick} axisLine={false} tickLine={false} />
            <YAxis tick={axisTick} axisLine={false} tickLine={false} />
            <Tooltip content={<ChartTooltip />} />
            {series.map((s) => (
              <Line key={s.key} type="monotone" dataKey={s.key} name={s.label} stroke={s.color} strokeWidth={2} dot={{ r: 3, fill: s.color, strokeWidth: 0 }} activeDot={{ r: 5, strokeWidth: 0 }} />
            ))}
          </LineChart>
        ) : chartType === "bar" ? (
          <BarChart data={data} margin={margin}>
            <CartesianGrid {...gridProps} />
            <XAxis dataKey="name" tick={axisTick} axisLine={false} tickLine={false} />
            <YAxis tick={axisTick} axisLine={false} tickLine={false} />
            <Tooltip content={<ChartTooltip />} />
            {series.map((s) => (
              <Bar key={s.key} dataKey={s.key} name={s.label} fill={s.color} radius={[4, 4, 0, 0]} fillOpacity={0.85} />
            ))}
          </BarChart>
        ) : (
          <PieChart>
            <Pie data={pieData} cx="50%" cy="50%" innerRadius={50} outerRadius={80} dataKey="value" paddingAngle={3}>
              {pieData.map((entry) => (
                <Cell key={entry.name} fill={entry.color} fillOpacity={0.9} stroke="none" />
              ))}
            </Pie>
            <Tooltip content={<ChartTooltip />} />
          </PieChart>
        )}
      </ResponsiveContainer>
      </div>

      <div className="mt-3 flex shrink-0 flex-wrap items-center justify-center gap-x-5 gap-y-1.5">
        {series.map((s) => (
          <div key={s.key} className="flex items-center gap-1.5">
            <span className="inline-block h-2.5 w-2.5 rounded-full" style={{ background: s.color }} />
            <span className="text-xs font-medium text-slate-500 dark:text-slate-400">{s.label}</span>
          </div>
        ))}
      </div>
      </>
      )}
    </div>
  );
}

// --- Skeleton -----------------------------------------------------------------

function Skeleton({ className = "" }: { className?: string }) {
  return (
    <div className={cn("animate-pulse rounded-xl bg-slate-200 dark:bg-slate-800", className)} />
  );
}

// --- Quick actions ------------------------------------------------------------

const QUICK_NAV_LINKS = [
  { href: "/agent/send-remittance", icon: Send,          key: "quickSendRemittance", accent: "violet"  },
  { href: "/agent/money-in",        icon: ArrowDownLeft, key: "quickMoneyIn",        accent: "cyan"    },
  { href: "/agent/money-out",       icon: ArrowUpRight,  key: "quickMoneyOut",       accent: "rose"    },
  { href: "/agent/statements",      icon: FileText,      key: "quickStatements",     accent: "indigo"  },
  { href: "/agent/my-recipients",   icon: UserCheck,     key: "myRecipients",        accent: "emerald" },
  { href: "/agent/my-senders",      icon: Users,         key: "mySenders",           accent: "amber"   },
  { href: "/agent/kyc",             icon: CheckCircle2,  key: "kycStatus",           accent: "brand"   },
  { href: "/agent/security",        icon: ShieldCheck,   key: "twoFaSecurity",       accent: "slate"   },
] as const;

const ACCENT_STYLES = {
  brand:   "from-brand-50 to-brand-100 text-brand-600 dark:from-brand-500/15 dark:to-brand-500/5 dark:text-brand-300",
  emerald: "from-emerald-50 to-emerald-100 text-emerald-600 dark:from-emerald-500/15 dark:to-emerald-500/5 dark:text-emerald-300",
  amber:   "from-amber-50 to-amber-100 text-amber-600 dark:from-amber-500/15 dark:to-amber-500/5 dark:text-amber-300",
  slate:   "from-slate-100 to-slate-200 text-slate-600 dark:from-slate-800/60 dark:to-slate-800/30 dark:text-slate-300",
  violet:  "from-violet-50 to-violet-100 text-violet-600 dark:from-violet-500/15 dark:to-violet-500/5 dark:text-violet-300",
  cyan:    "from-cyan-50 to-cyan-100 text-cyan-600 dark:from-cyan-500/15 dark:to-cyan-500/5 dark:text-cyan-300",
  rose:    "from-rose-50 to-rose-100 text-rose-600 dark:from-rose-500/15 dark:to-rose-500/5 dark:text-rose-300",
  indigo:  "from-indigo-50 to-indigo-100 text-indigo-600 dark:from-indigo-500/15 dark:to-indigo-500/5 dark:text-indigo-300",
} as const;

const ACCENT_ON_HOVER = {
  brand:   "group-hover:text-brand-600 dark:group-hover:text-brand-400",
  emerald: "group-hover:text-emerald-600 dark:group-hover:text-emerald-400",
  amber:   "group-hover:text-amber-600 dark:group-hover:text-amber-400",
  slate:   "group-hover:text-slate-700 dark:group-hover:text-slate-300",
  violet:  "group-hover:text-violet-600 dark:group-hover:text-violet-400",
  cyan:    "group-hover:text-cyan-600 dark:group-hover:text-cyan-400",
  rose:    "group-hover:text-rose-600 dark:group-hover:text-rose-400",
  indigo:  "group-hover:text-indigo-600 dark:group-hover:text-indigo-400",
} as const;

// --- Transaction row ----------------------------------------------------------

function TxRow({ tx, index }: { tx: DashboardTransaction; index: number }) {
  const displayName =
    tx.sender_name || tx.recipient_name || tx.account_name || "—";
  const isMoneyIn = tx.type?.toLowerCase() === "money in";

  return (
    <m.tr
      initial={{ opacity: 0, x: -10 }}
      animate={{ opacity: 1, x: 0 }}
      transition={{ delay: index * 0.05 }}
      className="group transition-colors hover:bg-slate-50/70 dark:hover:bg-slate-900/40"
    >
      <td className="px-6 py-4 sm:px-7">
        <p className="text-sm font-semibold text-brand-600 transition-colors group-hover:text-brand-700 dark:text-brand-400 dark:group-hover:text-brand-300">
          {tx.transaction_id}
        </p>
        <p className="mt-0.5 text-xs text-slate-400 dark:text-slate-500">{tx.created_at}</p>
      </td>
      <td className="px-6 py-4 sm:px-7 text-sm text-slate-600 whitespace-nowrap dark:text-slate-300">
        {displayName}
      </td>
      <td className="px-6 py-4 sm:px-7">
        <span
          className={`badge gap-1 text-[length:var(--text-sm-fixed)] font-medium ${
            isMoneyIn
              ? "bg-emerald-50 text-emerald-700 ring-1 ring-emerald-600/20 dark:bg-emerald-500/10 dark:text-emerald-400 dark:ring-emerald-400/20"
              : "bg-brand-50 text-brand-700 ring-1 ring-brand-600/20 dark:bg-brand-500/10 dark:text-brand-400 dark:ring-brand-400/20"
          }`}
        >
          {tx.type || tx.transactin_type}
        </span>
      </td>
      <td className="px-6 py-4 sm:px-7 text-start text-sm font-semibold tabular-nums text-slate-900 dark:text-white">
        {fmt(tx.request_amount, tx.sender_currency)}
      </td>
      <td className="px-6 py-4 sm:px-7 text-start text-sm font-semibold tabular-nums text-rose-500 dark:text-rose-400">
        {fmt(tx.total_charge, tx.sender_currency)}
      </td>
      <td className="px-6 py-4 sm:px-7 text-start">
        <span
          className={`badge capitalize text-[length:var(--text-sm-fixed)] font-medium ${statusStyle(tx.status)}`}
        >
          {tx.status}
        </span>
      </td>
    </m.tr>
  );
}

// Notification filter — by transaction category (also drives the row icon) or by read state.
type NotifCat = "in" | "tx" | "out";
type NotifFilter = NotifCat | "read" | "unread";
type NotifOption = { value: NotifFilter | "all"; label: string };


// react-select classNames — mirrors the shared filter-select styling, sized compact for the card header.
const NOTIF_SELECT_CLS = {
  control: () =>
    "h-9 w-full cursor-pointer rounded-full border border-slate-200/80 bg-white ps-3.5 pe-1 text-xs font-semibold text-slate-700 outline-none transition-colors hover:border-slate-300 dark:border-slate-700/60 dark:bg-slate-900/60 dark:text-slate-200 !min-h-9",
  menu: () =>
    "mt-2 overflow-hidden rounded-xl border border-slate-200 bg-white shadow-2xl dark:border-slate-700 dark:bg-slate-900 z-50",
  menuList: () => "max-h-60 overflow-y-auto p-1",
  option: ({ isFocused, isSelected }: { isFocused: boolean; isSelected: boolean }) =>
    cn(
      "cursor-pointer rounded-lg px-3 py-2 text-xs transition-colors",
      isSelected
        ? "bg-brand-500 font-semibold text-white"
        : isFocused
        ? "bg-brand-50 font-semibold text-brand-700 dark:bg-brand-500/15 dark:text-brand-300"
        : "font-medium text-slate-700 dark:text-slate-300",
    ),
  singleValue: () => "text-xs font-semibold text-slate-700 dark:text-slate-200",
  valueContainer: () => "px-0",
  dropdownIndicator: () =>
    "px-1 text-slate-400 transition-colors hover:text-slate-600 dark:text-slate-500 dark:hover:text-slate-300",
  indicatorSeparator: () => "hidden",
};

// Boxed-cell borders for the notifications grid — top/bottom on every cell,
// right only between columns within the same row (never after the last
// column, computed per nth-child since `divide-x` can't tell "last in row"
// from "last overall" and silently drops the divider after a short trailing
// row, e.g. a single leftover item in a 3-col grid).
const NOTIF_CELL_BORDER = cn(
  "border-t border-b border-slate-100 dark:border-slate-800/60",
  "sm:[&:nth-child(2n+1)]:border-e sm:[&:nth-child(2n)]:border-e-0",
  "lg:[&:nth-child(3n+1)]:border-e lg:[&:nth-child(3n+2)]:border-e lg:[&:nth-child(3n)]:border-e-0",
);

function notifCategory(message: string): NotifCat | "other" {
  const m = message.toLowerCase();
  if (m.includes("money out")) return "out";
  if (m.includes("money in")) return "in";
  if (m.includes("remittance") || m.includes("send")) return "tx";
  return "other";
}

// --- Page ---------------------------------------------------------------------

export default function AgentDashboardPage() {
  const { user } = useAgentAuth();
  const { t, dir } = useTranslation();
  const { data, isLoading, isError, dataUpdatedAt } = useAgentDashboard();
  const { data: notifData, isLoading: notifLoading } = useAgentNotifications();
  const { markRead, isRead } = useAgentNotificationState();
  const [balanceHidden, setBalanceHidden] = useState(false);
  // Defaults to dismissed so a stale nudge never flashes before sessionStorage is read.
  const [twoFaDismissed, setTwoFaDismissed] = useState(true);
  // "Last updated" ticks every 30s so it stays accurate without a manual refresh.
  const [now, setNow] = useState<number | null>(null);

  useEffect(() => {
    try {
      setTwoFaDismissed(sessionStorage.getItem(AGENT_TWO_FA_DISMISS_KEY) === "1");
    } catch {
      setTwoFaDismissed(false);
    }
  }, []);

  useEffect(() => {
    setNow(Date.now());
    const id = setInterval(() => setNow(Date.now()), 30_000);
    return () => clearInterval(id);
  }, []);

  function dismissTwoFaNudge() {
    try {
      sessionStorage.setItem(AGENT_TWO_FA_DISMISS_KEY, "1");
    } catch {
      /* ignore */
    }
    setTwoFaDismissed(true);
  }

  const notifFilterOptions: NotifOption[] = [
    { value: "all",    label: t("agent.notifications.tabAll") },
    { value: "unread", label: t("agent.notifications.tabUnread") },
    { value: "read",   label: t("agent.notifications.tabRead") },
    { value: "in",     label: t("agent.sidebar.moneyIn") },
    { value: "tx",     label: t("agent.sidebar.sendRemittance") },
    { value: "out",    label: t("agent.sidebar.moneyOut") },
  ];

  const [txPage, setTxPage] = useState(1);
  const [notifPage, setNotifPage] = useState(1);
  const [notifFilter, setNotifFilter] = useState<NotifFilter | null>(null);

  const storeName = user?.storeName || "My Store";
  const firstName = user?.firstName || "Agent";
  const currency  = data?.base_currency ?? "USD";

  const kyc = KYC_BADGE[user?.kycStatus ?? "unverified"];
  const KycIcon = kyc.icon;
  const showVerifyBanner = Boolean(user) && user?.kycStatus === "unverified";
  const showTwoFaNudge = Boolean(user) && !user?.twoFactorEnabled && !twoFaDismissed;

  const lastUpdatedText = !dataUpdatedAt || now === null ? null : (() => {
    const mins = Math.floor((now - dataUpdatedAt) / 60_000);
    if (mins < 1) return t("app.dashboard.justNow");
    if (mins < 60) return t("app.dashboard.minutesAgo").replace("{n}", String(mins));
    const hours = Math.floor(mins / 60);
    if (hours < 24) return t("app.dashboard.hoursAgo").replace("{n}", String(hours));
    return t("app.dashboard.daysAgo").replace("{n}", String(Math.floor(hours / 24)));
  })();

  const TX_PAGE_SIZE = 10;
  const allTx = data?.transactions ?? [];
  const txTotalPages = Math.max(1, Math.ceil(allTx.length / TX_PAGE_SIZE));
  const txSafePage   = Math.min(txPage, txTotalPages);
  const pageTx       = allTx.slice((txSafePage - 1) * TX_PAGE_SIZE, txSafePage * TX_PAGE_SIZE);

  const NOTIF_PAGE_SIZE = 12;
  const allNotifs = notifData?.notifications ?? [];
  const filteredNotifs  = !notifFilter
    ? allNotifs
    : notifFilter === "read"
    ? allNotifs.filter((n) => isRead(notifKey(n.message)))
    : notifFilter === "unread"
    ? allNotifs.filter((n) => !isRead(notifKey(n.message)))
    : allNotifs.filter((n) => notifCategory(n.message) === notifFilter);
  const notifTotalPages = Math.max(1, Math.ceil(filteredNotifs.length / NOTIF_PAGE_SIZE));
  const notifSafePage   = Math.min(notifPage, notifTotalPages);
  const pageNotifs      = filteredNotifs.slice((notifSafePage - 1) * NOTIF_PAGE_SIZE, notifSafePage * NOTIF_PAGE_SIZE);
  const notifUnread     = allNotifs.reduce((n, x) => (isRead(notifKey(x.message)) ? n : n + 1), 0);

  const stats = [
    {
      icon: Wallet,
      label: t("agent.dashboard.walletBalance"),
      value: isLoading ? null : fmt(data?.agent_wallet_balance ?? 0, currency),
      accent: "brand" as const,
    },
    {
      icon: TrendingUp,
      label: t("agent.dashboard.profitBalance"),
      value: isLoading ? null : fmt(data?.profit_balance ?? 0, currency),
      accent: "emerald" as const,
    },
    {
      icon: Send,
      label: t("agent.dashboard.sendRemittances"),
      value: isLoading ? null : String(data?.total_send_remittance ?? 0),
      accent: "amber" as const,
    },
    {
      icon: XCircle,
      label: t("agent.dashboard.cancelledTxns"),
      value: isLoading ? null : String(data?.total_canceled_transactions ?? 0),
      accent: "slate" as const,
    },
  ];

  // Single O(n) pass over this-page transactions to count in-flight ones.
  const pendingCount = allTx.reduce((n, tx) => {
    const s = tx.status.toLowerCase();
    return s === "pending" || s === "processing" ? n + 1 : n;
  }, 0);

  const chartSeries = data?.dashboard_content
    ? [
        {
          key: "money_in",
          label: t("agent.sidebar.moneyIn"),
          color: "#10b981",
          values: data.dashboard_content.money_in,
        },
        {
          key: "money_out",
          label: t("agent.sidebar.moneyOut"),
          color: "#f59e0b",
          values: data.dashboard_content.money_out,
        },
        {
          key: "send_remittance",
          label: t("agent.sidebar.sendRemittance"),
          color: "#4f46e5",
          values: data.dashboard_content.send_remittance,
        },
      ]
    : [];

  return (
    <Container className="max-w-full space-y-6 lg:space-y-8">
      <m.div
        variants={containerVariants}
        initial="hidden"
        animate="visible"
        className="flex flex-col gap-6 lg:gap-8"
      >
        {showVerifyBanner && (
          <m.div variants={itemVariants}>
            <AgentVerifyBanner />
          </m.div>
        )}

        {showTwoFaNudge && (
          <m.div variants={itemVariants}>
            <WarningToast
              title={t("agent.dashboard.twoFaNudgeTitle")}
              message={t("agent.dashboard.twoFaNudgeMessage")}
              ctaLabel={t("agent.dashboard.twoFaNudgeCta")}
              ctaHref="/agent/security"
              dismissLabel={t("agent.dashboard.twoFaNudgeDismiss")}
              onClose={dismissTwoFaNudge}
            />
          </m.div>
        )}

        {/* Balance + activity overview — both cards are direct grid siblings so they
            stretch to match each other's height natively, instead of the chart
            trailing off with dead space below its (shorter) content. */}
        <m.div variants={itemVariants}>
          <div className="grid items-stretch gap-6 min-[1441px]:grid-cols-3">
            <Card className="overflow-hidden border border-slate-200/80 dark:border-slate-700/50">
                <div aria-hidden className="absolute inset-0 -z-10">
                  <Image
                    src="/dashboard-topo-bg.webp"
                    alt=""
                    fill
                    priority
                    sizes="100vw"
                    className="object-cover object-center opacity-20 invert dark:opacity-40 dark:invert-0"
                  />
                  <div className="absolute inset-0 bg-gradient-to-br from-white via-slate-50 to-slate-100/80 dark:from-slate-800/95 dark:via-slate-800/85 dark:to-slate-900/90" />
                </div>

                <CardContent className="relative z-10 flex h-full flex-col">
                  <div className="flex items-start justify-between gap-3">
                    <div>
                      <h1 className="text-xl font-bold tracking-tight text-slate-900 dark:text-white sm:text-2xl">
                        {t("agent.dashboard.welcomeBack")}, {firstName}
                      </h1>
                      <p className="mt-1 flex items-center gap-1.5 text-sm text-slate-500 dark:text-slate-400">
                        <Building2 className="icon-sm shrink-0" aria-hidden />
                        <span className="font-medium">{storeName}</span>
                      </p>
                    </div>
                    <div className="flex shrink-0 items-center gap-2">
                      {user?.avatar ? (
                        <Image
                          src={user.avatar}
                          alt=""
                          width={44}
                          height={44}
                          unoptimized
                          className="h-11 w-11 shrink-0 rounded-full object-cover ring-2 ring-slate-200 dark:ring-white/10"
                        />
                      ) : (
                        <span className="grid h-11 w-11 shrink-0 place-items-center rounded-full bg-gradient-to-br from-brand-500 to-accent-500 text-sm font-bold text-white ring-2 ring-slate-200 dark:ring-white/10">
                          {firstName.charAt(0).toUpperCase()}
                        </span>
                      )}
                    </div>
                  </div>

                  <div className="mt-6 rounded-2xl border border-slate-200 bg-slate-50 p-5 dark:border-white/10 dark:bg-white/[0.03]">
                    <div className="flex items-start justify-between gap-3">
                      <div>
                        <p className="text-sm font-medium capitalize tracking-wider text-slate-500 dark:text-slate-400">
                          {t("agent.dashboard.walletBalance")}
                        </p>
                        {isLoading ? (
                          <Skeleton className="mt-2 h-9 w-32" />
                        ) : (
                          <div className="mt-1 flex items-center gap-2">
                            <p className="text-4xl font-extrabold tabular-nums tracking-tight text-slate-900 dark:text-white">
                              {balanceHidden ? "••••••" : fmt(data?.agent_wallet_balance ?? 0, currency)}
                            </p>
                            <button
                              type="button"
                              onClick={() => setBalanceHidden((v) => !v)}
                              aria-label={t(balanceHidden ? "app.dashboard.showBalance" : "app.dashboard.hideBalance")}
                              className="grid h-9 w-9 shrink-0 place-items-center rounded-full border border-slate-200 bg-slate-100 text-slate-500 transition-colors hover:bg-slate-200 hover:text-slate-900 dark:border-white/10 dark:bg-white/5 dark:text-slate-300 dark:hover:bg-white/10 dark:hover:text-white"
                            >
                              {balanceHidden ? <EyeOff className="icon-sm" /> : <Eye className="icon-sm" />}
                            </button>
                          </div>
                        )}
                      </div>
                      <span className="grid h-12 w-12 shrink-0 place-items-center rounded-full bg-brand-500/10 text-brand-600 dark:text-brand-400">
                        <Wallet className="icon-md" />
                      </span>
                    </div>

                    <div className="my-4 border-t border-dashed border-slate-200 dark:border-white/10" />

                    <div className="flex flex-wrap items-center gap-3">
                      <span className="inline-flex shrink-0 items-center gap-2 text-[11px] font-semibold leading-none">
                        <span
                          className={cn(
                            "grid h-6 w-6 shrink-0 place-items-center rounded-full",
                            kyc.on
                              ? "bg-accent-500/10 text-accent-600 dark:bg-accent-500/15 dark:text-accent-300"
                              : "bg-amber-500/10 text-amber-600 dark:bg-amber-500/15 dark:text-amber-300",
                          )}
                        >
                          <KycIcon className="h-3.5 w-3.5" />
                        </span>
                        <span className={cn("leading-none", kyc.on ? "text-accent-600 dark:text-accent-300" : "text-amber-600 dark:text-amber-300")}>
                          {t(kyc.labelKey)}
                        </span>
                      </span>

                      <span aria-hidden className="h-4 w-px shrink-0 bg-slate-200 dark:bg-white/10" />
                      <span className="inline-flex shrink-0 items-center gap-2 text-[11px] font-semibold leading-none">
                        <span
                          className={cn(
                            "grid h-6 w-6 shrink-0 place-items-center rounded-full",
                            user?.twoFactorEnabled
                              ? "bg-accent-500/10 text-accent-600 dark:bg-accent-500/15 dark:text-accent-300"
                              : "bg-amber-500/10 text-amber-600 dark:bg-amber-500/15 dark:text-amber-300",
                          )}
                        >
                          {user?.twoFactorEnabled ? <ShieldCheck className="h-3.5 w-3.5" /> : <ShieldAlert className="h-3.5 w-3.5" />}
                        </span>
                        <span className={cn("leading-none", user?.twoFactorEnabled ? "text-accent-600 dark:text-accent-300" : "text-amber-600 dark:text-amber-300")}>
                          {t(user?.twoFactorEnabled ? "app.dashboard.twoFa.badgeOn" : "app.dashboard.twoFa.badgeOff")}
                        </span>
                      </span>

                      {lastUpdatedText && (
                        <>
                          <span aria-hidden className="h-4 w-px shrink-0 bg-slate-200 dark:bg-white/10" />
                          <span className="inline-flex shrink-0 items-center gap-2 text-[11px] font-medium leading-none text-slate-600 dark:text-slate-300">
                            <span className="grid h-6 w-6 shrink-0 place-items-center rounded-full bg-brand-500/10 text-brand-600 dark:bg-brand-500/15 dark:text-brand-300">
                              <Clock className="h-3.5 w-3.5" />
                            </span>
                            <span className="leading-none">
                              {t("app.dashboard.lastUpdated").replace("{time}", lastUpdatedText)}
                            </span>
                            <span aria-hidden className="h-1.5 w-1.5 rounded-full bg-accent-400" />
                          </span>
                        </>
                      )}
                    </div>
                  </div>

                  <div className="mt-auto pt-6">
                    <ButtonLink href="/agent/send-remittance" size="md" className="w-full">
                      <Send className={cn("icon-md", dir === "rtl" && "[transform:scaleX(-1)]")} />
                      {t("agent.dashboard.sendRemittance")}
                    </ButtonLink>
                  </div>
                </CardContent>
              </Card>

            {/* Activity chart card — direct grid sibling of the hero, so it stretches
                to the same height (see items-stretch on the parent row) */}
            <Card className="overflow-hidden border border-slate-200/80 dark:border-slate-700/50 min-[1441px]:col-span-2">
              <div aria-hidden className="absolute inset-0 -z-10">
                <Image
                  src="/dashboard-topo-bg.webp"
                  alt=""
                  fill
                  priority
                  sizes="100vw"
                  className="object-cover object-center opacity-20 invert dark:opacity-40 dark:invert-0"
                />
                <div className="absolute inset-0 bg-gradient-to-br from-white via-slate-50 to-slate-100/80 dark:from-slate-800/95 dark:via-slate-800/85 dark:to-slate-900/90" />
              </div>

              <CardContent className="relative z-10 flex h-full flex-col">
                <div className="flex shrink-0 items-start justify-between">
                  <h3 className="text-[length:var(--text-base-fixed)] font-bold text-slate-900 dark:text-white">
                    {t("agent.dashboard.activityOverview")}
                  </h3>
                  <span className="inline-flex rounded-full bg-slate-100 px-2.5 py-1 text-xs font-bold text-slate-600 dark:bg-slate-800 dark:text-slate-300">
                    {currency}
                  </span>
                </div>
                <div className="mt-4 min-h-0 flex-1">
                  {isLoading ? (
                    <Skeleton className="h-full w-full rounded-xl" />
                  ) : data?.dashboard_content ? (
                    <ActivityChart
                      categories={data.dashboard_content.categories}
                      series={chartSeries}
                    />
                  ) : null}
                </div>
              </CardContent>
            </Card>
          </div>
        </m.div>

        {/* Mini stats + quick navigation — same equal-height sibling pattern as the row above */}
        <m.div variants={itemVariants}>
          <div className="grid items-stretch gap-6 xl:grid-cols-3">
            <DashboardStatCarousel
              slides={[
                {
                  key: "confirmedTxns",
                  icon: CheckCircle2,
                  label: t("agent.dashboard.confirmedTxns"),
                  value: String(data?.total_confirm_send_remittance ?? 0),
                  accent: "accent",
                },
                {
                  key: "pendingTxns",
                  icon: Clock,
                  label: t("agent.dashboard.pendingTxns"),
                  value: String(pendingCount),
                  accent: "amber",
                },
              ]}
            />

            <Card className="border border-slate-200/80 dark:border-slate-700/50 xl:col-span-2">
              <CardContent>
                <h2 className="mb-4 flex items-center gap-1.5 text-xs font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400">
                  <Pin className="icon-sm" />
                  {t("agent.dashboard.quickActionsTitle")}
                </h2>
                <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-4">
                  {QUICK_NAV_LINKS.map((a) => {
                    const Icon = a.icon;
                    return (
                      <Link
                        key={a.href}
                        href={a.href}
                        className="group relative flex items-center gap-3.5 overflow-hidden rounded-xl bg-white px-4 py-3.5 shadow-sm transition-all duration-200 hover:-translate-y-0.5 hover:shadow-md dark:bg-slate-900/60"
                      >
                        <span className={`grid h-9 w-9 shrink-0 place-items-center rounded-lg bg-gradient-to-br ${ACCENT_STYLES[a.accent]}`}>
                          <Icon className={cn("h-4 w-4", (a.icon === Send || a.icon === ArrowDownLeft || a.icon === ArrowUpRight) && dir === "rtl" && "[transform:scaleX(-1)]")} />
                        </span>
                        <span className={`text-[length:var(--text-sm-fixed)] font-medium text-slate-800 transition-colors dark:text-slate-200 ${ACCENT_ON_HOVER[a.accent]}`}>
                          {t(`agent.dashboard.${a.key}`)}
                        </span>
                        <ArrowUpRight className={cn("ms-auto h-3.5 w-3.5 shrink-0 text-slate-300 transition-all duration-200 group-hover:-translate-y-0.5 dark:text-slate-600", ACCENT_ON_HOVER[a.accent], dir === "rtl" ? "[transform:scaleX(-1)] group-hover:-translate-x-0.5" : "group-hover:translate-x-0.5")} />
                      </Link>
                    );
                  })}
                </div>
              </CardContent>
            </Card>
          </div>
        </m.div>

        {/* Stats */}
        <m.section variants={containerVariants} className="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
          {stats.map((s) => (
            <m.div key={s.label} variants={itemVariants} className="h-full">
              <StatCard
                icon={s.icon}
                label={s.label}
                value={s.value}
                accent={s.accent}
              />
            </m.div>
          ))}
        </m.section>

        {/* Recent transactions — full width */}
        <m.div variants={itemVariants}>
          <Card className="overflow-hidden rounded-3xl border-slate-200/60 shadow-sm backdrop-blur-md dark:border-slate-800/60 dark:bg-slate-900/40">
            <CardContent className="p-0">
              <header className="flex items-center border-b border-slate-100 p-6 sm:p-7 dark:border-slate-800/60">
                <div>
                  <h2 className="text-[length:var(--text-lg-fixed)] font-bold text-slate-900 dark:text-white">
                    {t("agent.dashboard.recentTransactions")}
                  </h2>
                  <p className="mt-1 text-[length:var(--text-sm-fixed)] text-slate-500 dark:text-slate-400">{t("agent.dashboard.latestActivity")}</p>
                </div>
                <Link
                  href="/agent/transactions"
                  className="ms-auto group flex items-center gap-1.5 rounded-full bg-brand-50 px-4 py-2 text-xs font-bold text-brand-600 transition-colors hover:bg-brand-100 dark:bg-brand-500/10 dark:text-brand-300 dark:hover:bg-brand-500/20"
                >
                  {t("agent.dashboard.viewAll")}
                  {dir === "rtl" ? (
                    <ChevronLeft className="h-3.5 w-3.5 transition-transform group-hover:-translate-x-0.5" />
                  ) : (
                    <ChevronRight className="h-3.5 w-3.5 transition-transform group-hover:translate-x-0.5" />
                  )}
                </Link>
              </header>

              <div className="overflow-x-auto">
                <table className="w-full min-w-[780px]">
                  <thead className="bg-slate-50/50 text-[length:var(--text-sm-fixed)] font-semibold capitalize text-slate-500 dark:bg-slate-900/50 dark:text-slate-400">
                    <tr>
                      <th className="px-6 py-4 sm:px-7 text-start font-semibold whitespace-nowrap">{t("agent.dashboard.refDate")}</th>
                      <th className="px-6 py-4 sm:px-7 text-start font-semibold whitespace-nowrap">{t("agent.dashboard.recipientSender")}</th>
                      <th className="px-6 py-4 sm:px-7 text-start font-semibold whitespace-nowrap">{t("agent.dashboard.type")}</th>
                      <th className="px-6 py-4 sm:px-7 text-start font-semibold whitespace-nowrap">{t("agent.dashboard.amount")}</th>
                      <th className="px-6 py-4 sm:px-7 text-start font-semibold whitespace-nowrap">{t("agent.dashboard.fee")}</th>
                      <th className="px-6 py-4 sm:px-7 text-start font-semibold whitespace-nowrap">{t("agent.dashboard.status")}</th>
                    </tr>
                  </thead>
                  <tbody className="divide-y divide-slate-100 dark:divide-slate-800/60">
                    {isLoading ? (
                      Array.from({ length: 6 }).map((_, i) => (
                        <tr key={i}>
                          <td className="px-6 py-4 sm:px-7"><Skeleton className="h-4 w-24" /></td>
                          <td className="px-6 py-4 sm:px-7"><Skeleton className="h-4 w-32" /></td>
                          <td className="px-6 py-4 sm:px-7"><Skeleton className="h-5 w-20 rounded-full" /></td>
                          <td className="px-6 py-4 sm:px-7"><Skeleton className="h-4 w-16" /></td>
                          <td className="px-6 py-4 sm:px-7"><Skeleton className="h-4 w-12" /></td>
                          <td className="px-6 py-4 sm:px-7"><Skeleton className="h-5 w-16 rounded-full" /></td>
                        </tr>
                      ))
                    ) : isError ? (
                      <tr>
                        <td colSpan={6} className="px-6 py-12 text-center text-sm font-medium text-rose-500">
                          {t("agent.dashboard.failedToLoadTransactions")}
                        </td>
                      </tr>
                    ) : !data?.transactions?.length ? (
                      <tr>
                        <td colSpan={6} className="px-6 py-16 text-center text-sm text-slate-400">
                          <div className="mx-auto flex flex-col items-center justify-center">
                            <Receipt className="mb-3 h-10 w-10 text-slate-300 dark:text-slate-600" />
                            <p>{t("agent.dashboard.noTransactionsFound")}</p>
                          </div>
                        </td>
                      </tr>
                    ) : (
                      pageTx.map((tx, index) => (
                        <TxRow key={tx.transaction_id} tx={tx} index={index} />
                      ))
                    )}
                  </tbody>
                </table>
              </div>

              {/* Pagination */}
              {!isLoading && !isError && txTotalPages > 1 && (
                <div className="flex items-center justify-between border-t border-slate-100 px-5 py-3 dark:border-slate-800/60">
                  <p className="text-xs font-semibold text-slate-500 dark:text-slate-400">
                    Page <span className="text-slate-900 dark:text-white">{txSafePage}</span> of{" "}
                    <span className="text-slate-900 dark:text-white">{txTotalPages}</span>
                    <span className="ml-2 text-slate-400">({allTx.length} total)</span>
                  </p>
                  <div className="flex items-center gap-1">
                    <button
                      type="button"
                      onClick={() => setTxPage((p) => Math.max(1, p - 1))}
                      disabled={txSafePage === 1}
                      className="btn-icon-sm rounded-full border border-slate-200 text-slate-600 transition hover:bg-slate-50 disabled:cursor-not-allowed disabled:opacity-40 dark:border-slate-700 dark:text-slate-300 dark:hover:bg-slate-800"
                    >
                      {dir === "rtl" ? <ChevronRight className="icon-md" /> : <ChevronLeft className="icon-md" />}
                    </button>
                    {Array.from({ length: txTotalPages }, (_, i) => i + 1)
                      .filter((p) => p === 1 || p === txTotalPages || Math.abs(p - txSafePage) <= 1)
                      .reduce<(number | "…")[]>((acc, p, idx, arr) => {
                        if (idx > 0 && p - (arr[idx - 1] as number) > 1) acc.push("…");
                        acc.push(p);
                        return acc;
                      }, [])
                      .map((item, idx) =>
                        item === "…" ? (
                          <span key={`ellipsis-${idx}`} className="px-1 text-xs text-slate-400">…</span>
                        ) : (
                          <button
                            key={item}
                            type="button"
                            onClick={() => setTxPage(item as number)}
                            className={cn(
                              "btn-icon-sm rounded-full text-xs font-bold transition",
                              txSafePage === item
                                ? "bg-brand-600 text-white shadow-sm"
                                : "border border-slate-200 text-slate-600 hover:bg-slate-50 dark:border-slate-700 dark:text-slate-300 dark:hover:bg-slate-800",
                            )}
                          >
                            {item}
                          </button>
                        )
                      )}
                    <button
                      type="button"
                      onClick={() => setTxPage((p) => Math.min(txTotalPages, p + 1))}
                      disabled={txSafePage === txTotalPages}
                      className="btn-icon-sm rounded-full border border-slate-200 text-slate-600 transition hover:bg-slate-50 disabled:cursor-not-allowed disabled:opacity-40 dark:border-slate-700 dark:text-slate-300 dark:hover:bg-slate-800"
                    >
                      {dir === "rtl" ? <ChevronLeft className="icon-md" /> : <ChevronRight className="icon-md" />}
                    </button>
                  </div>
                </div>
              )}
            </CardContent>
          </Card>
        </m.div>

        {/* Notifications — full width */}
        <m.div variants={itemVariants}>
          <div className="overflow-hidden rounded-[1.5rem] border border-slate-200/60 bg-white shadow-sm dark:border-slate-800/60 dark:bg-slate-900/40">
            <div className="flex flex-wrap items-center gap-3 border-b border-slate-100 p-5 sm:p-6 dark:border-slate-800/60">
              <div className="flex items-center gap-2.5">
                <div className="grid h-9 w-9 place-items-center rounded-xl bg-brand-50 dark:bg-brand-500/10">
                  <Bell className="h-4 w-4 text-brand-600 dark:text-brand-400" />
                </div>
                <div>
                  <h2 className="text-[length:var(--text-lg-fixed)] font-bold text-slate-900 dark:text-white">{t("agent.dashboard.notifications")}</h2>
                  <p className="text-[length:var(--text-sm-fixed)] text-slate-500 dark:text-slate-400">
                    {notifUnread
                      ? t("agent.dashboard.newUpdates").replace("{n}", String(notifUnread)).replace("{s}", notifUnread !== 1 ? "s" : "")
                      : t("agent.dashboard.allCaughtUp")}
                  </p>
                </div>
              </div>

              <div className="ms-auto w-44">
                <Select<NotifOption>
                  unstyled
                  isSearchable={false}
                  instanceId="notif-filter"
                  aria-label="Filter notifications by type"
                  classNames={NOTIF_SELECT_CLS}
                  options={notifFilterOptions}
                  value={notifFilterOptions.find((o) => o.value === (notifFilter ?? "all"))}
                  onChange={(opt) => {
                    setNotifFilter(opt && opt.value !== "all" ? opt.value : null);
                    setNotifPage(1);
                  }}
                />
              </div>

              <Link
                href="/agent/notifications"
                className="group flex items-center gap-1.5 rounded-full bg-brand-50 px-4 py-2 text-xs font-bold text-brand-600 transition-colors hover:bg-brand-100 dark:bg-brand-500/10 dark:text-brand-300 dark:hover:bg-brand-500/20"
              >
                {t("agent.dashboard.viewAll")}
                {dir === "rtl" ? (
                  <ChevronLeft className="h-3.5 w-3.5 transition-transform group-hover:-translate-x-0.5" />
                ) : (
                  <ChevronRight className="h-3.5 w-3.5 transition-transform group-hover:translate-x-0.5" />
                )}
              </Link>
            </div>

            <div className="grid min-h-[19rem] content-start sm:grid-cols-2 lg:grid-cols-3">
              {notifLoading ? (
                Array.from({ length: 3 }).map((_, i) => (
                  <div key={i} className={cn("flex items-start gap-3 p-5", NOTIF_CELL_BORDER)}>
                    <Skeleton className="h-9 w-9 shrink-0 rounded-xl" />
                    <div className="flex-1 space-y-2">
                      <Skeleton className="h-3.5 w-full" />
                      <Skeleton className="h-2.5 w-20" />
                    </div>
                  </div>
                ))
              ) : filteredNotifs.length > 0 ? (
                pageNotifs.map((notif) => {
                  const date  = new Date(notif.created_at);
                  const key   = notifKey(notif.message);
                  const read  = isRead(key);
                  const cat   = notifCategory(notif.message);

                  const iconEl = cat === "out" ? (
                    <ArrowUpRight className={cn("icon-md", dir === "rtl" && "[transform:scaleX(-1)]")} />
                  ) : cat === "in" ? (
                    <ArrowDownLeft className={cn("icon-md", dir === "rtl" && "[transform:scaleX(-1)]")} />
                  ) : cat === "tx" ? (
                    <Send className={cn("icon-md", dir === "rtl" && "[transform:scaleX(-1)]")} />
                  ) : (
                    <Bell className="icon-md" />
                  );

                  const iconBg = cat === "out"
                    ? "bg-amber-50 text-amber-600 dark:bg-amber-500/10 dark:text-amber-400"
                    : cat === "in"
                    ? "bg-emerald-50 text-emerald-600 dark:bg-emerald-500/10 dark:text-emerald-400"
                    : cat === "tx"
                    ? "bg-brand-50 text-brand-600 dark:bg-brand-500/10 dark:text-brand-400"
                    : "bg-slate-100 text-slate-500 dark:bg-slate-800 dark:text-slate-400";

                  return (
                    <button
                      key={notif.id}
                      type="button"
                      onClick={() => markRead(key)}
                      className={cn(
                        "flex w-full items-start gap-3 p-5 text-left transition-colors hover:bg-slate-50/70 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-brand-500 dark:hover:bg-slate-800/30",
                        NOTIF_CELL_BORDER,
                      )}
                    >
                      <div className={cn("grid h-9 w-9 shrink-0 place-items-center rounded-xl", iconBg)}>
                        {iconEl}
                      </div>
                      <div className="min-w-0 flex-1">
                        <p
                          className={cn(
                            "line-clamp-2 text-[length:var(--text-sm-fixed)] font-medium leading-relaxed",
                            read
                              ? "text-slate-400 dark:text-slate-500"
                              : "text-slate-700 dark:text-slate-300",
                          )}
                        >
                          {notif.message}
                        </p>
                        <p className="mt-1 text-2xs font-semibold text-slate-400 dark:text-slate-500">
                          {relativeTime(date)}
                        </p>
                      </div>
                      {!read && (
                        <span className="mt-1 h-2 w-2 shrink-0 rounded-full bg-brand-500" />
                      )}
                    </button>
                  );
                })
              ) : (
                <div className="col-span-full flex flex-col items-center justify-center gap-2 py-10">
                  <div className="icon-box-md grid place-items-center rounded-2xl bg-slate-100 dark:bg-slate-800">
                    <Bell className="h-5 w-5 text-slate-400 dark:text-slate-500" />
                  </div>
                  <p className="text-xs font-medium text-slate-500 dark:text-slate-400">
                    {notifFilter
                      ? `No ${notifFilterOptions.find((o) => o.value === notifFilter)?.label} notifications`
                      : t("agent.dashboard.allCaughtUpBell")}
                  </p>
                </div>
              )}
            </div>

            {/* Notifications pagination — bar always rendered when items exist so the
                card height stays constant across filters (controls appear only when paged) */}
            {!notifLoading && filteredNotifs.length > 0 && (
              <div className="flex items-center justify-between px-5 py-3">
                <p className="text-xs font-semibold text-slate-500 dark:text-slate-400">
                  Page <span className="text-slate-900 dark:text-white">{notifSafePage}</span> of{" "}
                  <span className="text-slate-900 dark:text-white">{notifTotalPages}</span>
                  <span className="ml-2 text-slate-400">({filteredNotifs.length} total)</span>
                </p>
                {notifTotalPages > 1 && (
                <div className="flex items-center gap-1">
                  <button
                    type="button"
                    onClick={() => setNotifPage((p) => Math.max(1, p - 1))}
                    disabled={notifSafePage === 1}
                    className="btn-icon-sm rounded-full border border-slate-200 text-slate-600 transition hover:bg-slate-50 disabled:cursor-not-allowed disabled:opacity-40 dark:border-slate-700 dark:text-slate-300 dark:hover:bg-slate-800"
                  >
                    {dir === "rtl" ? <ChevronRight className="icon-md" /> : <ChevronLeft className="icon-md" />}
                  </button>
                  {Array.from({ length: notifTotalPages }, (_, i) => i + 1)
                    .filter((p) => p === 1 || p === notifTotalPages || Math.abs(p - notifSafePage) <= 1)
                    .reduce<(number | "…")[]>((acc, p, idx, arr) => {
                      if (idx > 0 && p - (arr[idx - 1] as number) > 1) acc.push("…");
                      acc.push(p);
                      return acc;
                    }, [])
                    .map((item, idx) =>
                      item === "…" ? (
                        <span key={`notif-ellipsis-${idx}`} className="px-1 text-xs text-slate-400">…</span>
                      ) : (
                        <button
                          key={item}
                          type="button"
                          onClick={() => setNotifPage(item as number)}
                          className={cn(
                            "btn-icon-sm rounded-full text-xs font-bold transition",
                            notifSafePage === item
                              ? "bg-brand-600 text-white shadow-sm"
                              : "border border-slate-200 text-slate-600 hover:bg-slate-50 dark:border-slate-700 dark:text-slate-300 dark:hover:bg-slate-800",
                          )}
                        >
                          {item}
                        </button>
                      )
                    )}
                  <button
                    type="button"
                    onClick={() => setNotifPage((p) => Math.min(notifTotalPages, p + 1))}
                    disabled={notifSafePage === notifTotalPages}
                    className="btn-icon-sm rounded-full border border-slate-200 text-slate-600 transition hover:bg-slate-50 disabled:cursor-not-allowed disabled:opacity-40 dark:border-slate-700 dark:text-slate-300 dark:hover:bg-slate-800"
                  >
                    {dir === "rtl" ? <ChevronLeft className="icon-md" /> : <ChevronRight className="icon-md" />}
                  </button>
                </div>
                )}
              </div>
            )}
          </div>
        </m.div>
      </m.div>
    </Container>
  );
}
