import type { CoreMemberAccountType } from "@/lib/features/members/types";
import { searchMemberAccountTypes } from "@/lib/features/members/query";
import {
  deleteCampaign,
  sendCampaign,
  stopCampaign,
  resumeCampaign,
  activateCampaign,
} from "@/lib/features/notifications/action";
import {
  Button,
  Flex,
  Group,
  Select,
  Stack,
  TextInput,
  Title,
  Pagination,
  Text,
  Drawer,
  Tabs,
  Card,
  Checkbox,
  Table,
  Grid,
  Box,
  Badge,
  SimpleGrid,
  Tooltip,
  SegmentedControl,
  Skeleton,
  Collapse,
} from "@mantine/core";
import { useDebouncedValue, useDisclosure } from "@mantine/hooks";
import { notifications } from "@mantine/notifications";
import {
  IconRefresh,
  IconSearch,
  IconPlus,
  IconHistory,
  IconTrash,
  IconArrowLeft,
  IconSettings,
  IconExclamationCircleFilled,
  IconMail,
  IconDeviceAnalytics,
  IconSend,
  IconEye,
  IconEyeOff,
  IconFilter,
  IconCalendar,
  IconChevronDown,
  IconChevronUp,
} from "@tabler/icons-react";
import { useCampaignSocket } from "@/hooks/useCampaignSocket";
import React, { useEffect, useState, useMemo, useRef } from "react";

// Survives remounts but not a real page load, which is exactly the lifetime we
// want: reset the filters once per hard reload and never again.
let hasHandledReload = false;

import ReactECharts from "echarts-for-react";
import { useNavigate, useSearchParams } from "react-router";
import AddNotification from "./(widgets)/addNotification";
import CampaignsTable from "./(widgets)/CampaignsTable";
import Filters, { type FilterState } from "./(widgets)/CampaignsTable/Filters";
import type { Campaign } from "./(widgets)/CampaignsTable/types";
import { RecipientsDrawer } from "./(widgets)/RecipientsDrawer";
import { ContextualLogs } from "@/components/blocks/activity-logs/ContextualLogs";
import ConfirmAlert from "@/components/blocks/ConfirmAlert/confirmAlert";

import { DatePickerInput } from "@mantine/dates";
import {
  listCampaigns,
  getCampaignAnalytics,
  type CampaignAnalytics,
} from "@/lib/features/notifications/action";

interface NotificationsClientsPageProps {
  initialCampaigns: Campaign[];
  totalCount: number;
  accountTypes?: CoreMemberAccountType[];
}

const NotificationsClientsPage: React.FC<NotificationsClientsPageProps> = ({
  initialCampaigns,
  totalCount: initialTotalCount,
  accountTypes: initialAccountTypes,
}) => {
  const navigate = useNavigate();
  const [searchParams, setSearchParams] = useSearchParams();

  const [campaigns, setCampaigns] = useState<Campaign[]>(initialCampaigns);
  const [totalCount, setTotalCount] = useState(initialTotalCount);
  const [accountTypes, setAccountTypes] = useState<CoreMemberAccountType[]>(
    (initialAccountTypes ?? []).filter((t: any) => t.name !== "Karma Lite"),
  );

  useEffect(() => {
    if (initialAccountTypes) return;
    let cancelled = false;
    (async () => {
      try {
        const res = await searchMemberAccountTypes(1, 100);
        if (res.success && !cancelled) {
          const types = res.data?.account_types ?? [];
          setAccountTypes(types.filter((t: any) => t.name !== "Karma Lite"));
        }
      } catch (err) {
        console.error("Failed to load account types:", err);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [initialAccountTypes]);

  // NOTE: deliberately no effect syncing `initialCampaigns` into state. The
  // loader hands back a hardcoded empty list, so re-running it used to blank
  // the table (`campaigns = []`) and only the fetch effect below could refill
  // it — which it wouldn't unless a URL param happened to change. That's what
  // left the list showing empty after creating a campaign. The loader values
  // are used once, for the initial useState above.

  const { generalUpdate, generalStatusUpdate } = useCampaignSocket();

  useEffect(() => {
    if (generalUpdate) {
      setCampaigns((prev) =>
        prev.map((c) =>
          c.id === generalUpdate.campaignId
            ? {
                ...c,
                sent_count: generalUpdate.sent,
                total_count: generalUpdate.total,
              }
            : c,
        ),
      );
    }
  }, [generalUpdate]);

  useEffect(() => {
    if (generalStatusUpdate) {
      setCampaigns((prev) =>
        prev.map((c) => {
          if (c.id === generalStatusUpdate.campaignId) {
            const updated = { ...c, status: generalStatusUpdate.status };
            if (
              generalStatusUpdate.status === "SENT" ||
              generalStatusUpdate.status === "COMPLETED"
            ) {
              updated.updated_at = new Date().toISOString();
            }
            return updated;
          }
          return c;
        }),
      );
    }
  }, [generalStatusUpdate]);

  const [loading, setLoading] = useState(false);
  const [refreshing, setRefreshing] = useState(false);
  const [sendingId, setSendingId] = useState<string | null>(null);

  const page = parseInt(searchParams.get("page") || "1", 10);
  const pageSize = searchParams.get("pageSize") || "10";
  const search = searchParams.get("search") || "";
  const status = searchParams.get("status") || null;

  const fromDate = searchParams.get("fromDate") || null;
  const toDate = searchParams.get("toDate") || null;

  const [localSearch, setLocalSearch] = useState(search);
  const [debouncedSearch] = useDebouncedValue(localSearch, 200);

  // Derived from the URL, never held separately. Previously `filterState` was
  // its own useState, so when the URL lost its `status` param the server-side
  // filter vanished while the client-side one survived — the table then filtered
  // a full page of mixed campaigns down to nothing. One source of truth avoids
  // that class of divergence entirely, and makes filters shareable + reset on
  // reload for free.
  const platformParam = searchParams.get("platform") || "";
  const filterState: FilterState = useMemo(
    () => ({
      platform: platformParam ? platformParam.split(",") : [],
      status: status ? status.split(",") : [],
    }),
    [platformParam, status],
  );

  const handleFiltersChange = (filters: FilterState) => {
    updateParams({
      status: filters.status.length > 0 ? filters.status.join(",") : null,
      platform: filters.platform.length > 0 ? filters.platform.join(",") : null,
      page: 1,
    });
  };

  // Graph + summary cards are backed by a dedicated analytics endpoint,
  // scoped to the selected date window and independent of the campaigns
  // table's own page/pageSize/search/status filters.
  const [analytics, setAnalytics] = useState<CampaignAnalytics>({
    buckets: [],
    summary: {
      campaignsSent: 0,
      sends: 0,
      received: 0,
      impressions: 0,
      opens: 0,
    },
  });
  const campaignStats = analytics.summary;
  const dailyChartData = analytics.buckets;

  const [showSends, setShowSends] = useState(true);
  const [showReceived, setShowReceived] = useState(true);
  const [showImpressions, setShowImpressions] = useState(true);
  const [showOpens, setShowOpens] = useState(true);
  const [timeRange, setTimeRange] = useState<"7d" | "30d" | "90d">("30d");
  const [graphReady, setGraphReady] = useState(false);
  const [analyticsExpanded, setAnalyticsExpanded] = useState(false);

  const [dateRange, setDateRange] = useState<[Date | null, Date | null]>([
    fromDate ? new Date(`${fromDate}T00:00:00`) : null,
    toDate ? new Date(`${toDate}T00:00:00`) : null,
  ]);
  const isCustomActive = !!(dateRange[0] && dateRange[1]);

  // A hard reload starts from a clean slate. Nothing wipes the URL any more, so
  // the old cache-and-restore dance (stashing searchParams in a module variable
  // and putting them back after a navigate) is gone — it existed only to undo
  // the param loss described in refreshData below, and it cost an extra fetch
  // with the wrong params every time.
  useEffect(() => {
    const navEntries = performance.getEntriesByType("navigation");
    const isReload =
      navEntries.length > 0 &&
      (navEntries[0] as PerformanceNavigationTiming).type === "reload";

    if (isReload && !hasHandledReload) {
      hasHandledReload = true;
      setSearchParams(new URLSearchParams(), { replace: true });
      setDateRange([null, null]);
      setLocalSearch("");
    }
  }, [setSearchParams]);

  // ref to imperatively open the hidden DatePickerInput popover
  const datePickerRef = useRef<HTMLButtonElement>(null);
  const [pickerOpen, setPickerOpen] = useState(false);

  const formatDate = (date: Date) => {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
    return `${year}-${month}-${day}`;
  };

  const formatShort = (date: Date) =>
    date.toLocaleDateString("en-GB", {
      day: "numeric",
      month: "short",
      year: "2-digit",
    });

  const [chartExpanded, setChartExpanded] = useState(false);
  const chartRef = useRef<any>(null);
  useEffect(() => {
    const chart = chartRef.current?.getEchartsInstance();
    if (chart) {
      setTimeout(() => {
        chart.resize();
      }, 100);
    }
  }, [chartExpanded]);

  const formatStatNumber = (num: number) => {
    if (num >= 1000000)
      return (num / 1000000).toFixed(1).replace(/\.0$/, "") + "m";
    if (num >= 1000) return (num / 1000).toFixed(1).replace(/\.0$/, "") + "k";
    return num.toString();
  };

  useEffect(() => {
    if (!analyticsExpanded) return;
    let cancelled = false;
    const fetchAnalytics = async () => {
      setGraphReady(false);
      try {
        const params =
          dateRange[0] && dateRange[1]
            ? {
                fromDate: formatDate(dateRange[0]),
                toDate: formatDate(dateRange[1]),
              }
            : { range: timeRange };
        const res = await getCampaignAnalytics(params);
        if (!cancelled && res.success) {
          setAnalytics(res.data as CampaignAnalytics);
        }
      } catch (error) {
        console.error("Failed fetching campaign analytics:", error);
      } finally {
        if (!cancelled) setGraphReady(true);
      }
    };
    fetchAnalytics();
    return () => {
      cancelled = true;
    };
  }, [timeRange, dateRange, analyticsExpanded]);

  const chartData = useMemo(() => {
    const chartHeaders = ["Date"];
    if (showSends) chartHeaders.push("Sends");
    if (showReceived) chartHeaders.push("Received");
    if (showImpressions) chartHeaders.push("Impressions");
    if (showOpens) chartHeaders.push("Open count");

    const chartRows = dailyChartData.map((d) => {
      const row: (string | number)[] = [d.date];
      if (showSends) row.push(d.sends);
      if (showReceived) row.push(d.received);
      if (showImpressions) row.push(d.impressions);
      if (showOpens) row.push(d.opens);
      return row;
    });

    return [chartHeaders, ...chartRows];
  }, [dailyChartData, showSends, showReceived, showImpressions, showOpens]);

  useEffect(() => {
    if (debouncedSearch !== search) {
      updateParams({ search: debouncedSearch, page: 1 });
    }
  }, [debouncedSearch]);

  const updateParams = (
    newParams: Record<string, string | number | undefined | null>,
  ) => {
    const current = new URLSearchParams(searchParams);
    Object.keys(newParams).forEach((key) => {
      if (
        newParams[key] === undefined ||
        newParams[key] === null ||
        newParams[key] === ""
      ) {
        current.delete(key);
      } else {
        current.set(key, String(newParams[key]));
      }
    });
    if (
      newParams.page === undefined &&
      (newParams.search !== undefined ||
        newParams.status !== undefined ||
        newParams.fromDate !== undefined)
    ) {
      current.set("page", "1");
    }
    setSearchParams(current);
  };

  /**
   * Refetch the current view without touching the URL.
   *
   * Every mutation used to call `navigate(".", { replace: true })` to force a
   * reload. But `navigate(".")` resolves to the pathname alone and DISCARDS the
   * search string, so search / pageSize / status / sort were all thrown away —
   * which is why a keyword search cleared itself and a pageSize of 100 snapped
   * back to the default 10 the moment you created a campaign. Bumping a key the
   * fetch effect depends on refetches the exact same view instead.
   */
  const [refreshKey, setRefreshKey] = useState(0);
  const refreshData = () => setRefreshKey((k) => k + 1);

  const sortBy = searchParams.get("sortBy") || undefined;
  const sortOrder = searchParams.get("sortOrder") || undefined;

  useEffect(() => {
    const fetchData = async () => {
      setLoading(true);
      try {
        const res = await listCampaigns(
          (page - 1) * Number(pageSize),
          Number(pageSize),
          {
            search,
            status: status || undefined,
            platform: platformParam || undefined,
            fromDate: fromDate || undefined,
            toDate: toDate || undefined,
            sortBy,
            sortOrder,
          },
        );
        if (res.success) {
          setCampaigns((res.data as any).items);
          setTotalCount((res.data as any).total);
        }
      } catch (error) {
        console.error("Failed fetching records:", error);
      } finally {
        setLoading(false);
        setRefreshing(false); // fetch settled → stop the Refresh button spinner
      }
    };
    fetchData();
  }, [
    page,
    pageSize,
    search,
    status,
    platformParam,
    fromDate,
    toDate,
    sortBy,
    sortOrder,
    refreshKey,
  ]);

  const [addDrawerOpened, { open: openAddDrawer, close: closeAddDrawer }] =
    useDisclosure(false);
  const [duplicateData, setDuplicateData] = useState<Campaign | null>(null);
  const [recipientsOpened, { open: openRecipients, close: closeRecipients }] =
    useDisclosure(false);
  const [selectedCampaign, setSelectedCampaign] = useState<Campaign | null>(
    null,
  );
  const [historyOpened, { open: openHistory, close: closeHistory }] =
    useDisclosure(false);
  const [confirmOpened, { open: openConfirm, close: closeConfirm }] =
    useDisclosure(false);
  const [confirmConfig, setConfirmConfig] = useState<{
    title: string;
    message: string;
    onConfirm: () => void;
  }>({ title: "", message: "", onConfirm: () => {} });

  const showConfirm = (
    title: string,
    message: string,
    onConfirm: () => void,
  ) => {
    setConfirmConfig({ title, message, onConfirm });
    openConfirm();
  };

  const handleDelete = async (id: string) => {
    showConfirm(
      "Delete Campaign",
      "Are you sure you want to delete this campaign?",
      async () => {
        try {
          const res = await deleteCampaign(id);
          if (res.success) {
            notifications.show({
              title: "Success",
              message: "Campaign deleted successfully",
              color: "green",
            });
            refreshData();
          } else {
            notifications.show({
              title: "Error",
              message: res.message || "Failed to delete campaign",
              color: "red",
            });
          }
        } catch (e) {
          notifications.show({
            title: "Error",
            message: "An unexpected error occurred",
            color: "red",
          });
        } finally {
          closeConfirm();
        }
      },
    );
  };

  const handleActivate = async (id: string) => {
    showConfirm(
      "Restore Campaign",
      "Are you sure you want to restore this campaign?",
      async () => {
        try {
          const res = await activateCampaign(id);
          if (res.success) {
            notifications.show({
              title: "Success",
              message: "Campaign restored successfully",
              color: "green",
            });
            refreshData();
          } else {
            notifications.show({
              title: "Error",
              message: res.message || "Failed to restore campaign",
              color: "red",
            });
          }
        } catch (e) {
          notifications.show({
            title: "Error",
            message: "An unexpected error occurred",
            color: "red",
          });
        } finally {
          closeConfirm();
        }
      },
    );
  };

  const handleDuplicate = (campaign: Campaign) => {
    setDuplicateData(campaign);
    openAddDrawer();
  };
  const handleAddNew = () => {
    setDuplicateData(null);
    openAddDrawer();
  };

  const handleSendNow = async (id: string) => {
    setSendingId(id);
    try {
      const res = await sendCampaign(id);
      if (res.success) {
        notifications.show({
          title: "Success",
          message: "Campaign sending initiated",
          color: "green",
        });
        refreshData();
      } else {
        notifications.show({
          title: "Error",
          message: res.message || "Failed to send campaign",
          color: "red",
        });
      }
    } catch (e) {
      notifications.show({
        title: "Error",
        message: "Failed to send campaign",
        color: "red",
      });
    } finally {
      setSendingId(null);
    }
  };

  const handleStop = async (id: string) => {
    try {
      const res = await stopCampaign(id);
      if (res.success) {
        notifications.show({
          title: "Success",
          message: "Campaign stopped",
          color: "green",
        });
        refreshData();
      } else {
        notifications.show({
          title: "Error",
          message: "Failed to stop campaign",
          color: "red",
        });
      }
    } catch (e) {
      notifications.show({
        title: "Error",
        message: "Failed to stop campaign",
        color: "red",
      });
    }
  };

  const handleResume = async (id: string) => {
    setSendingId(id);
    try {
      const res = await resumeCampaign(id);
      if (res.success) {
        notifications.show({
          title: "Success",
          message: "Campaign resumed",
          color: "green",
        });
        refreshData();
      } else {
        notifications.show({
          title: "Error",
          message: res.message || "Failed to resume campaign",
          color: "red",
        });
      }
    } catch (e) {
      notifications.show({
        title: "Error",
        message: "Failed to resume campaign",
        color: "red",
      });
    } finally {
      setSendingId(null);
    }
  };

  const handleViewRecipients = (campaign: Campaign) => {
    setSelectedCampaign(campaign);
    openRecipients();
  };
  const handleManualRefresh = () => {
    setRefreshing(true);
    refreshData();
  };

  return (
    <Stack px={28} py={20} gap="lg">
      <Flex justify={"space-between"} align="center">
        <Title order={3}>Messaging</Title>
        <Group>
          {status === "DELETED" ? (
            <Button
              variant="light"
              color="blue"
              leftSection={<IconArrowLeft size={16} />}
              onClick={() => updateParams({ status: null, page: 1 })}
            >
              Back to Active
            </Button>
          ) : (
            <Button
              variant="light"
              color="red"
              leftSection={<IconTrash size={16} />}
              onClick={() => updateParams({ status: "DELETED", page: 1 })}
            >
              Deleted Campaigns
            </Button>
          )}
          <Button
            variant="light"
            leftSection={<IconRefresh size={16} />}
            onClick={handleManualRefresh}
            loading={refreshing}
          >
            Refresh
          </Button>
          <Button
            variant="outline"
            color="gray"
            leftSection={<IconSettings size={16} />}
            onClick={() => navigate("settings")}
          >
            Settings
          </Button>
          <AddNotification
            accountTypes={accountTypes}
            opened={addDrawerOpened}
            onClose={closeAddDrawer}
            initialData={duplicateData}
            onSuccess={refreshData}
          />
          <Button
            size="compact-lg"
            fz={12}
            variant="filled"
            color={"blue.1"}
            autoContrast
            leftSection={
              <IconPlus style={{ height: "12px", marginRight: "-10px" }} />
            }
            onClick={handleAddNew}
          >
            Create a new campaign
          </Button>
        </Group>
      </Flex>

      {/* Metrics Chart Card */}
      <Card
        padding="xl"
        radius="lg"
        withBorder
        style={
          chartExpanded
            ? {
                position: "fixed",
                top: 0,
                left: 60,
                right: 0,
                bottom: 0,
                zIndex: 200,
                overflowY: "auto",
                boxShadow: "0 8px 24px rgba(0,0,0,0.04)",
                borderRadius: 0,
              }
            : { boxShadow: "0 8px 24px rgba(0,0,0,0.04)" }
        }
      >
        <Group justify="space-between" mb={analyticsExpanded ? "lg" : 0}>
          <Group
            gap="xs"
            style={{ cursor: "pointer" }}
            onClick={() => setAnalyticsExpanded((prev) => !prev)}
          >
            <IconDeviceAnalytics
              size={20}
              color="var(--mantine-color-blue-6)"
            />
            <Text fw={600} size="md">
              Campaign Analytics
            </Text>
            {analyticsExpanded ? (
              <IconChevronUp size={16} color="gray" />
            ) : (
              <IconChevronDown size={16} color="gray" />
            )}
          </Group>

          {analyticsExpanded && (
            <Group
              gap={0}
              align="center"
              style={{
                width: "fit-content",
                backgroundColor: "var(--mantine-color-gray-1)",
                borderRadius: "999px",
                padding: "4px",
                position: "relative",
              }}
            >
              <SegmentedControl
                value={isCustomActive || pickerOpen ? "__none__" : timeRange}
                onChange={(val: any) => {
                  setTimeRange(val);
                  setDateRange([null, null]);
                  if (fromDate || toDate) {
                    updateParams({
                      fromDate: undefined,
                      toDate: undefined,
                      page: 1,
                    });
                  }
                }}
                data={[
                  { label: "Week (7d)", value: "7d" },
                  { label: "Month (30d)", value: "30d" },
                  { label: "Quarter (90d)", value: "90d" },
                ]}
                radius="xl"
                size="sm"
                styles={{
                  root: {
                    backgroundColor: "transparent",
                    padding: 0,
                    border: "none",
                    boxShadow: "none",
                  },
                  indicator: {
                    borderRadius: "999px",
                    boxShadow: "var(--mantine-shadow-xs)",
                  },
                  label: { fontWeight: 500, fontSize: "13px" },
                }}
              />

              {/* Custom button — mirrors SegmentedControl active indicator exactly */}
              <Box
                style={{
                  position: "relative",
                  height: "32px",
                  display: "flex",
                  alignItems: "center",
                }}
              >
                {/* Active indicator background — same style as SegmentedControl indicator */}
                {(isCustomActive || pickerOpen) && (
                  <Box
                    style={{
                      position: "absolute",
                      inset: 0,
                      borderRadius: "999px",
                      backgroundColor: "white",
                      boxShadow: "var(--mantine-shadow-xs)",
                    }}
                  />
                )}
                <Box
                  onClick={() => datePickerRef.current?.click()}
                  style={{
                    position: "relative",
                    display: "inline-flex",
                    alignItems: "center",
                    gap: "6px",
                    height: "32px",
                    padding:
                      isCustomActive || pickerOpen ? "0 28px 0 12px" : "0 12px",
                    borderRadius: "999px",
                    cursor: "pointer",
                    fontWeight: 500,
                    fontSize: "13px",
                    color:
                      isCustomActive || pickerOpen
                        ? "var(--mantine-color-dark-6)"
                        : "var(--mantine-color-gray-6)",
                    whiteSpace: "nowrap",
                    userSelect: "none",
                  }}
                >
                  <IconCalendar
                    size={13}
                    style={{ opacity: 0.7, flexShrink: 0 }}
                  />
                  {isCustomActive
                    ? `${formatShort(dateRange[0]!)} – ${formatShort(dateRange[1]!)}`
                    : "Custom"}
                </Box>

                {/* Clear ✕ when a custom range is active */}
                {isCustomActive && (
                  <Box
                    onClick={(e) => {
                      e.stopPropagation();
                      setDateRange([null, null]);
                      updateParams({
                        fromDate: undefined,
                        toDate: undefined,
                        page: 1,
                      });
                    }}
                    style={{
                      position: "absolute",
                      top: "50%",
                      right: "8px",
                      transform: "translateY(-50%)",
                      width: "16px",
                      height: "16px",
                      display: "flex",
                      alignItems: "center",
                      justifyContent: "center",
                      borderRadius: "50%",
                      backgroundColor: "var(--mantine-color-gray-4)",
                      color: "white",
                      fontSize: "10px",
                      cursor: "pointer",
                      lineHeight: 1,
                      fontWeight: 700,
                      zIndex: 1,
                    }}
                  >
                    ×
                  </Box>
                )}

                {/* Invisible DatePickerInput — only provides the calendar popover */}
                <Box
                  style={{
                    position: "absolute",
                    top: 0,
                    left: 0,
                    width: "100%",
                    height: "100%",
                    opacity: 0,
                    pointerEvents: "none",
                    overflow: "hidden",
                  }}
                >
                  <DatePickerInput
                    ref={datePickerRef}
                    type="range"
                    value={[dateRange[0], dateRange[1]]}
                    onChange={(value) => {
                      const [start, end] = value as [
                        Date | string | null,
                        Date | string | null,
                      ];
                      const startDate = start
                        ? new Date(`${start}T00:00:00`)
                        : null;
                      const endDate = end ? new Date(`${end}T00:00:00`) : null;
                      setDateRange([startDate, endDate]);

                      if (start && end) {
                        const newFrom =
                          typeof start === "string" ? start : formatDate(start);
                        const newTo =
                          typeof end === "string" ? end : formatDate(end);
                        if (newFrom === fromDate && newTo === toDate) return; // already applied — skip duplicate fetch
                        updateParams({
                          fromDate: newFrom,
                          toDate: newTo,
                          page: 1,
                        });
                      } else if (!start && !end && (fromDate || toDate)) {
                        updateParams({
                          fromDate: undefined,
                          toDate: undefined,
                          page: 1,
                        });
                      }
                    }}
                    minDate={
                      dateRange[0] && !dateRange[1]
                        ? (() => {
                            const d = new Date(dateRange[0]);
                            d.setDate(d.getDate() - 89);
                            return d;
                          })()
                        : undefined
                    }
                    maxDate={
                      dateRange[0] && !dateRange[1]
                        ? (() => {
                            const d = new Date(dateRange[0]);
                            d.setDate(d.getDate() + 89);
                            return d;
                          })()
                        : undefined
                    }
                    popoverProps={{
                      onOpen: () => setPickerOpen(true),
                      onClose: () => setPickerOpen(false),
                    }}
                    clearable
                    size="sm"
                    style={{ pointerEvents: "all" }}
                  />
                </Box>
              </Box>
            </Group>
          )}
        </Group>

        <Collapse in={analyticsExpanded}>
          <Grid gutter="xl" align="center">
            <Grid.Col span={{ base: 12, md: 3 }}>
              <Stack gap="md">
                <Group align="flex-start" gap="sm" wrap="nowrap">
                  <Checkbox
                    checked={showSends}
                    onChange={(e) => setShowSends(e.currentTarget.checked)}
                    color="blue"
                    size="sm"
                    styles={{ input: { cursor: "pointer" } }}
                    mt={4}
                  />
                  <Stack gap={0}>
                    <Group gap={4} align="center">
                      <Text
                        size="sm"
                        fw={600}
                        style={{ color: "var(--mantine-color-gray-7)" }}
                      >
                        Sends
                      </Text>
                      <Tooltip label="Total push notifications dispatched">
                        <Text size="xs" c="dimmed" style={{ cursor: "help" }}>
                          ⓘ
                        </Text>
                      </Tooltip>
                    </Group>
                    <Text
                      size="26px"
                      fw={800}
                      style={{ color: "#228be6", lineHeight: 1.1 }}
                    >
                      {formatStatNumber(campaignStats.sends)}
                    </Text>
                  </Stack>
                </Group>
                <Group align="flex-start" gap="sm" wrap="nowrap">
                  <Checkbox
                    checked={showReceived}
                    onChange={(e) => setShowReceived(e.currentTarget.checked)}
                    color="orange"
                    size="sm"
                    styles={{ input: { cursor: "pointer" } }}
                    mt={4}
                  />
                  <Stack gap={0}>
                    <Group gap={4} align="center">
                      <Text
                        size="sm"
                        fw={600}
                        style={{ color: "var(--mantine-color-gray-7)" }}
                      >
                        Received
                      </Text>
                      <Tooltip label="Estimated push notifications delivered to devices">
                        <Text size="xs" c="dimmed" style={{ cursor: "help" }}>
                          ⓘ
                        </Text>
                      </Tooltip>
                    </Group>
                    <Text
                      size="26px"
                      fw={800}
                      style={{ color: "#fd7e14", lineHeight: 1.1 }}
                    >
                      {formatStatNumber(campaignStats.received)}
                    </Text>
                  </Stack>
                </Group>
                <Group align="flex-start" gap="sm" wrap="nowrap">
                  <Checkbox
                    checked={showImpressions}
                    onChange={(e) =>
                      setShowImpressions(e.currentTarget.checked)
                    }
                    color="pink"
                    size="sm"
                    styles={{ input: { cursor: "pointer" } }}
                    mt={4}
                  />
                  <Stack gap={0}>
                    <Group gap={4} align="center">
                      <Text
                        size="sm"
                        fw={600}
                        style={{ color: "var(--mantine-color-gray-7)" }}
                      >
                        Impressions
                      </Text>
                      <Tooltip label="Total notifications visible on device lockscreens">
                        <Text size="xs" c="dimmed" style={{ cursor: "help" }}>
                          ⓘ
                        </Text>
                      </Tooltip>
                    </Group>
                    <Text
                      size="26px"
                      fw={800}
                      style={{ color: "#e64980", lineHeight: 1.1 }}
                    >
                      {formatStatNumber(campaignStats.impressions)}
                    </Text>
                  </Stack>
                </Group>
                <Group align="flex-start" gap="sm" wrap="nowrap">
                  <Checkbox
                    checked={showOpens}
                    onChange={(e) => setShowOpens(e.currentTarget.checked)}
                    color="cyan"
                    size="sm"
                    styles={{ input: { cursor: "pointer" } }}
                    mt={4}
                  />
                  <Stack gap={0}>
                    <Group gap={4} align="center">
                      <Text
                        size="sm"
                        fw={600}
                        style={{ color: "var(--mantine-color-gray-7)" }}
                      >
                        Open count
                      </Text>
                      <Tooltip label="Total notifications tapped or viewed by members">
                        <Text size="xs" c="dimmed" style={{ cursor: "help" }}>
                          ⓘ
                        </Text>
                      </Tooltip>
                    </Group>
                    <Text
                      size="26px"
                      fw={800}
                      style={{ color: "#0c8599", lineHeight: 1.1 }}
                    >
                      {formatStatNumber(campaignStats.opens)}
                    </Text>
                  </Stack>
                </Group>
              </Stack>
            </Grid.Col>
            <Grid.Col span={{ base: 12, md: 9 }}>
              {!graphReady ? (
                <Skeleton height={320} radius="md" />
              ) : campaignStats.campaignsSent === 0 ? (
                <Stack align="center" justify="center" mih={280}>
                  <IconDeviceAnalytics
                    size={48}
                    stroke={1.2}
                    opacity={0.3}
                    color="var(--mantine-color-blue-5)"
                  />
                  <Text c="dimmed" size="sm">
                    No push notifications sent yet to map trend.
                  </Text>
                </Stack>
              ) : chartData.length <= 1 ? (
                <Stack align="center" justify="center" mih={280}>
                  <Text c="dimmed" size="sm">
                    Selecting metrics to display...
                  </Text>
                </Stack>
              ) : (
                <ReactECharts
                  ref={chartRef}
                  style={{
                    height: chartExpanded ? "calc(100vh - 200px)" : "320px",
                    width: "100%",
                    transition: "height 0.3s ease",
                  }}
                  opts={{ height: chartExpanded ? 500 : 320 }}
                  option={{
                    backgroundColor: "#ffffff",
                    legend: { show: false },
                    toolbox: {
                      right: 10,
                      top: 10,
                      feature: {
                        myFullScreen: {
                          show: true,
                          title: chartExpanded
                            ? "Exit Full Screen"
                            : "Full Screen",
                          icon: chartExpanded
                            ? "path://M7,7 L11,7 L11,9 L9,9 L9,11 L7,11 Z M13,7 L17,7 L17,11 L15,11 L15,9 L13,9 Z M7,13 L9,13 L9,15 L11,15 L11,17 L7,17 Z M15,13 L17,13 L17,17 L13,17 L13,15 L15,15 Z"
                            : "path://M3,3 L9,3 L9,5 L5,5 L5,9 L3,9 Z M15,3 L21,3 L21,9 L19,9 L19,5 L15,5 Z M3,15 L5,15 L5,19 L9,19 L9,21 L3,21 Z M19,15 L21,15 L21,21 L15,21 L15,19 L19,19 Z",
                          onclick: () => {
                            setChartExpanded((prev) => !prev);
                          },
                        },
                      },
                    },
                    xAxis: {
                      type: "category",
                      data: dailyChartData.map((d) => d.date),
                      axisLine: { lineStyle: { color: "#dee2e6" } },
                      axisLabel: { color: "#adb5bd", fontSize: 10 },
                    },
                    yAxis: {
                      type: "value",
                      splitLine: { lineStyle: { color: "#f1f3f5" } },
                      axisLabel: { color: "#adb5bd", fontSize: 10 },
                    },
                    series: [
                      showSends && {
                        name: "Sends",
                        type: "line",
                        smooth: true,
                        data: dailyChartData.map((d) => d.sends),
                        itemStyle: { color: "#228be6" },
                        lineStyle: { width: 2 },
                        symbolSize: 4,
                      },
                      showReceived && {
                        name: "Received",
                        type: "line",
                        smooth: true,
                        data: dailyChartData.map((d) => d.received),
                        itemStyle: { color: "#fd7e14" },
                        lineStyle: { width: 2 },
                        symbolSize: 4,
                      },
                      showImpressions && {
                        name: "Impressions",
                        type: "line",
                        smooth: true,
                        data: dailyChartData.map((d) => d.impressions),
                        itemStyle: { color: "#e64980" },
                        lineStyle: { width: 2 },
                        symbolSize: 4,
                      },
                      showOpens && {
                        name: "Open count",
                        type: "line",
                        smooth: true,
                        data: dailyChartData.map((d) => d.opens),
                        itemStyle: { color: "#0c8599" },
                        lineStyle: { width: 2 },
                        symbolSize: 4,
                      },
                    ].filter(Boolean),
                    tooltip: { trigger: "axis" },
                    grid: {
                      left: "15%",
                      right: "4%",
                      bottom: "3%",
                      containLabel: true,
                    },
                  }}
                  className="echarts-line-chart"
                />
              )}
            </Grid.Col>
          </Grid>
        </Collapse>
      </Card>

      {/* Campaigns Listing */}
      <Stack gap="lg">
        <Group
          justify="space-between"
          align="center"
          style={{
            backgroundColor: "var(--mantine-color-gray-0)",
            padding: "16px",
            borderRadius: "12px",
          }}
        >
          <TextInput
            placeholder="Search by title or name..."
            value={localSearch}
            onChange={(e) => setLocalSearch(e.currentTarget.value)}
            leftSection={<IconSearch size={18} stroke={1.5} />}
            size="sm"
            radius="md"
            variant="filled"
            style={{ flex: 1, maxWidth: 400 }}
          />
        </Group>

        <Stack gap="md">
          <CampaignsTable
            campaigns={campaigns}
            loading={loading}
            sendingId={sendingId}
            onSendNow={handleSendNow}
            onDuplicate={handleDuplicate}
            onDelete={handleDelete}
            onStop={handleStop}
            onResume={handleResume}
            onViewRecipients={handleViewRecipients}
            onActivate={handleActivate}
            filterState={filterState}
            onFiltersChange={handleFiltersChange}
            sortBy={sortBy}
            sortOrder={sortOrder as "asc" | "desc" | undefined}
            onSort={(column) => {
              const newOrder =
                sortBy === column && sortOrder === "asc" ? "desc" : "asc";
              updateParams({ sortBy: column, sortOrder: newOrder, page: 1 });
            }}
          />

          <Flex justify="space-between" align="center">
            <Group gap="xs">
              <Select
                style={{ width: 80 }}
                data={["5", "10", "20", "30", "40", "50", "100"]}
                value={pageSize}
                onChange={(val) => updateParams({ pageSize: val, page: 1 })}
              />
              <Text size="sm" c="dimmed">
                Entries per page
              </Text>
            </Group>
            <Pagination
              total={Math.ceil(totalCount / parseInt(pageSize || "10", 10))}
              value={page}
              onChange={(val) => updateParams({ page: val })}
            />
          </Flex>
        </Stack>
      </Stack>

      <RecipientsDrawer
        opened={recipientsOpened}
        onClose={closeRecipients}
        campaign={selectedCampaign}
      />
      <Drawer
        opened={historyOpened}
        onClose={closeHistory}
        title="Notification History"
        position="right"
        size="md"
      >
        <ContextualLogs title="Recent Notification Activity" />
      </Drawer>

      <ConfirmAlert
        title={confirmConfig.title}
        titleIcon={<IconExclamationCircleFilled color="orange" />}
        message={confirmConfig.message}
        handleConfirm={confirmConfig.onConfirm}
        modalProps={{ opened: confirmOpened, onClose: closeConfirm }}
      />
    </Stack>
  );
};

export default NotificationsClientsPage;
