"use client";

import { useCallback, useEffect, useState } from "react";
import { useRouter } from "next/navigation";

import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import CircularProgress from "@mui/material/CircularProgress";
import List from "@mui/material/List";
import ListItemButton from "@mui/material/ListItemButton";
import Popover from "@mui/material/Popover";
import Typography from "@mui/material/Typography";
import { alpha, useTheme } from "@mui/material/styles";

import { useAppLanguage } from "@/components/providers/app-language-provider";
import { getNotificationDetailUrl } from "@/components/layout/header/notification-detail-url";
import {
  markSystemNotificationAsRead,
  type SystemNotification,
} from "@/features/system-notifications/system-notifications-service";
import { useSystemNotifications } from "@/features/system-notifications/use-system-notifications";

type NotificationDropdownProps = {
  anchorEl: HTMLElement | null;
  open: boolean;
  onClose: () => void;
};

function getSenderName(notification: SystemNotification): string {
  if (notification.type === "RGC_DECISION_SUBMITTED") {
    return (
      notification.data?.ministryName?.trim() ||
      notification.data?.senderName?.trim() ||
      notification.title?.trim() ||
      "Ministry"
    );
  }

  const fallback =
    notification.type === "MEETING_SCHEDULED" ? "Ministry" : "Private Sector";

  return (
    notification.data?.senderName?.trim() ||
    notification.title?.trim() ||
    fallback
  );
}

function getNotificationMessage(notification: SystemNotification): string {
  if (notification.type === "RGC_DECISION_SUBMITTED") {
    const ministryName = notification.data?.ministryName?.trim() || "Ministry";
    const plenaryName = notification.data?.plenaryName?.trim() || "Plenary";

    return (
      notification.message?.trim() ||
      `${ministryName} submitted an RGC Decision for "${plenaryName}".`
    );
  }

  if (notification.type === "MEETING_SCHEDULED") {
    return (
      notification.message?.trim() ||
      notification.data?.meetingTitle?.trim() ||
      "Meeting scheduled."
    );
  }

  return (
    notification.message?.trim() ||
    notification.data?.meetingTitle?.trim() ||
    notification.data?.meetingRequestTitle?.trim() ||
    "Notification"
  );
}

function getInitials(value: string): string {
  const words = value.trim().split(/\s+/).filter(Boolean);

  if (words.length === 0) {
    return "N";
  }

  if (words.length === 1) {
    return words[0].slice(0, 2).toUpperCase();
  }

  return `${words[0][0]}${words[1][0]}`.toUpperCase();
}

function formatDate(value: string): string {
  const date = new Date(value);

  if (Number.isNaN(date.getTime())) {
    return "";
  }

  return date.toLocaleDateString("en-US", {
    month: "short",
    day: "2-digit",
    year: "numeric",
  });
}

function formatTimeAgo(value: string): string {
  const createdAt = new Date(value).getTime();

  if (Number.isNaN(createdAt)) {
    return "";
  }

  const difference = Math.max(Date.now() - createdAt, 0);
  const minutes = Math.floor(difference / 60_000);
  const hours = Math.floor(difference / 3_600_000);
  const days = Math.floor(difference / 86_400_000);

  if (minutes < 1) {
    return "Just now";
  }

  if (minutes < 60) {
    return `${minutes} min ago`;
  }

  if (hours < 24) {
    return `${hours} hour${hours > 1 ? "s" : ""} ago`;
  }

  return `${days} day${days > 1 ? "s" : ""} ago`;
}

function hasDetailView(notification: SystemNotification): boolean {
  return getNotificationDetailUrl(notification) !== "/";
}

function getAvatarColor(notification: SystemNotification) {
  if (notification.type === "RGC_DECISION_SUBMITTED") {
    return {
      backgroundColor: "#DBEAFE",
      color: "#1D4ED8",
    };
  }

  if (notification.type === "MEETING_SCHEDULED") {
    return {
      backgroundColor: "#D1FAE5",
      color: "#065F46",
    };
  }

  return {
    backgroundColor: "#E0F2FE",
    color: "#075985",
  };
}

export function NotificationDropdown({
  anchorEl,
  open,
  onClose,
}: NotificationDropdownProps) {
  const theme = useTheme();
  const router = useRouter();
  const { t } = useAppLanguage();

  const {
    notifications,
    unreadCount,
    isLoading: loading,
    error,
    refetch,
  } = useSystemNotifications();

  /* Errors from opening a notification, kept apart from loading errors. */
  const [openErrorMessage, setOpenErrorMessage] = useState("");

  const errorMessage = openErrorMessage || error || "";

  /* Show the newest list every time the user opens the dropdown. */
  useEffect(() => {
    if (open) {
      refetch();
    }
  }, [open, refetch]);

  const handleViewDetail = useCallback(
    async (notification: SystemNotification) => {
      try {
        setOpenErrorMessage("");

        const detailUrl = getNotificationDetailUrl(notification);

        /*
         * Marking as read also tells the shared notification hook to reload,
         * so the list and every unread count update on their own.
         */
        await markSystemNotificationAsRead(notification.id);

        onClose();

        if (detailUrl && detailUrl !== "/") {
          router.push(detailUrl);
        }
      } catch (openError) {
        console.error("Open notification failed:", openError);

        setOpenErrorMessage(
          openError instanceof Error
            ? openError.message
            : "Failed to open notification.",
        );
      }
    },
    [onClose, router],
  );

  const unreadLabel =
    unreadCount > 99 ? "99+" : unreadCount > 0 ? `+${unreadCount}` : "0";

  return (
    <Popover
      open={open}
      anchorEl={anchorEl}
      onClose={onClose}
      anchorOrigin={{
        vertical: "bottom",
        horizontal: "right",
      }}
      transformOrigin={{
        vertical: "top",
        horizontal: "right",
      }}
      elevation={0}
      slotProps={{
        paper: {
          sx: {
            mt: 1,
            width: 430,
            maxWidth: "calc(100vw - 24px)",
            borderRadius: "14px",
            border: `1px solid ${theme.palette.divider}`,
            backgroundColor: theme.palette.background.paper,
            overflow: "hidden",
            boxShadow:
              theme.palette.mode === "dark"
                ? "0 16px 36px rgba(0, 0, 0, 0.42)"
                : "0 12px 32px rgba(16, 24, 40, 0.14)",
          },
        },
      }}
    >
      <Box sx={{ px: 2, pt: 2, pb: 1 }}>
        <Typography
          sx={{
            mb: 2,
            fontSize: 14,
            fontWeight: 600,
            color: theme.palette.text.primary,
          }}
        >
          {t("notification") || "Notification"}
        </Typography>

        <Box
          sx={{
            display: "flex",
            alignItems: "center",
            gap: 1,
            borderBottom: `1px solid ${theme.palette.divider}`,
            pb: 1,
          }}
        >
          <Typography
            sx={{
              position: "relative",
              pb: 0.5,
              fontSize: 13,
              fontWeight: 500,
              color: theme.palette.text.secondary,
              "&::after": {
                content: '""',
                position: "absolute",
                left: 0,
                bottom: -9,
                width: "100%",
                height: 2,
                borderRadius: 999,
                backgroundColor: theme.palette.primary.main,
              },
            }}
          >
            {t("all") || "All"}
          </Typography>

          <Box
            sx={{
              minWidth: 24,
              px: 0.75,
              py: 0.1,
              borderRadius: "999px",
              textAlign: "center",
              backgroundColor: "#FEE4E2",
              color: "#F04438",
              fontSize: 11,
              fontWeight: 600,
              lineHeight: 1.6,
            }}
          >
            {unreadLabel}
          </Box>
        </Box>
      </Box>

      {loading && notifications.length === 0 ? (
        <Box sx={{ height: 190, display: "grid", placeItems: "center" }}>
          <CircularProgress size={25} />
        </Box>
      ) : errorMessage && notifications.length === 0 ? (
        <Box sx={{ px: 3, py: 5, textAlign: "center" }}>
          <Typography
            sx={{
              mb: 1.5,
              fontSize: 13,
              color: theme.palette.error.main,
            }}
          >
            {errorMessage}
          </Typography>

          <Button
            size="small"
            variant="outlined"
            onClick={() => {
              setOpenErrorMessage("");
              refetch();
            }}
            sx={{ textTransform: "none" }}
          >
            Retry
          </Button>
        </Box>
      ) : notifications.length === 0 ? (
        <Box sx={{ px: 2, py: 5, textAlign: "center" }}>
          <Typography
            sx={{
              fontSize: 13,
              color: theme.palette.text.secondary,
            }}
          >
            No notifications found.
          </Typography>
        </Box>
      ) : (
        <List
          disablePadding
          sx={{
            px: 2,
            pt: 0.5,
            pb: 1.5,
            maxHeight: 480,
            overflowY: "auto",
          }}
        >
          {notifications.map((notification) => {
            const senderName = getSenderName(notification);
            const notificationMessage = getNotificationMessage(notification);
            const avatarColor = getAvatarColor(notification);

            return (
              <ListItemButton
                key={notification.id}
                onClick={() => {
                  void handleViewDetail(notification);
                }}
                sx={{
                  alignItems: "flex-start",
                  mb: 1,
                  px: 0.75,
                  py: 1.5,
                  borderRadius: "12px",
                  backgroundColor: alpha(theme.palette.primary.main, 0.055),
                  "&:hover": {
                    backgroundColor: alpha(theme.palette.primary.main, 0.09),
                  },
                }}
              >
                <Box sx={{ display: "flex", width: "100%", gap: 1.25 }}>
                  <Box
                    sx={{
                      width: 32,
                      height: 32,
                      flexShrink: 0,
                      mt: 0.25,
                      borderRadius: "50%",
                      border: `1px solid ${theme.palette.divider}`,
                      display: "grid",
                      placeItems: "center",
                      backgroundColor: avatarColor.backgroundColor,
                      color: avatarColor.color,
                      fontSize: 10,
                      fontWeight: 700,
                    }}
                  >
                    {getInitials(senderName)}
                  </Box>

                  <Box sx={{ flex: 1, minWidth: 0 }}>
                    <Box
                      sx={{
                        display: "flex",
                        justifyContent: "space-between",
                        gap: 1,
                      }}
                    >
                      <Typography
                        sx={{
                          minWidth: 0,
                          fontSize: 12.5,
                          fontWeight: 700,
                          color: theme.palette.text.primary,
                          overflowWrap: "anywhere",
                        }}
                      >
                        {senderName}
                      </Typography>

                      <Typography
                        sx={{
                          flexShrink: 0,
                          fontSize: 11,
                          color: theme.palette.text.secondary,
                          whiteSpace: "nowrap",
                        }}
                      >
                        • {formatDate(notification.createdAt)}
                      </Typography>
                    </Box>

                    <Typography
                      sx={{
                        mt: 0.35,
                        mb: 1,
                        fontSize: 12,
                        lineHeight: 1.5,
                        color: theme.palette.text.secondary,
                        overflowWrap: "anywhere",
                      }}
                    >
                      {notificationMessage}
                    </Typography>

                    {hasDetailView(notification) ? (
                      <Button
                        variant="contained"
                        size="small"
                        onClick={(event) => {
                          event.stopPropagation();
                          void handleViewDetail(notification);
                        }}
                        sx={{
                          minWidth: 86,
                          height: 32,
                          px: 1.5,
                          borderRadius: "6px",
                          textTransform: "none",
                          boxShadow: "none",
                          fontSize: 12,
                        }}
                      >
                        {t("viewDetail") || "View Detail"}
                      </Button>
                    ) : null}

                    <Typography
                      sx={{
                        mt: 1.25,
                        fontSize: 11,
                        color: theme.palette.text.secondary,
                      }}
                    >
                      {formatTimeAgo(notification.createdAt)}
                    </Typography>
                  </Box>
                </Box>
              </ListItemButton>
            );
          })}
        </List>
      )}
    </Popover>
  );
}
