"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,

    // Notification Setting state
    systemNotificationEnabled,
    settingLoading,
  } = useSystemNotifications();

  /*
   * Keep errors from opening a notification separate
   * from API loading errors.
   */
  const [
    openErrorMessage,
    setOpenErrorMessage,
  ] = useState("");

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

  /*
   * Refresh notifications whenever dropdown opens.
   *
   * Do not fetch when:
   * - notification setting is still loading
   * - system notifications are disabled
   */
  useEffect(() => {
    if (
      open &&
      systemNotificationEnabled &&
      !settingLoading
    ) {
      refetch();
    }
  }, [
    open,
    refetch,
    settingLoading,
    systemNotificationEnabled,
  ]);

  /*
   * Close dropdown immediately when the user disables
   * System Notification from Notification Settings.
   */
  useEffect(() => {
    if (
      open &&
      !settingLoading &&
      !systemNotificationEnabled
    ) {
      onClose();
    }
  }, [
    onClose,
    open,
    settingLoading,
    systemNotificationEnabled,
  ]);

  const handleViewDetail = useCallback(
    async (
      notification: SystemNotification,
    ) => {
      /*
       * Prevent notification actions when
       * System Notification is disabled.
       */
      if (!systemNotificationEnabled) {
        onClose();
        return;
      }

      try {
        setOpenErrorMessage("");

        const detailUrl =
          getNotificationDetailUrl(
            notification,
          );

        /*
         * Mark as read and notify all shared
         * notification views to reload.
         */
        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,
      systemNotificationEnabled,
    ],
  );

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

  const dropdownOpen =
    open &&
    systemNotificationEnabled &&
    !settingLoading;

  return (
    <Popover
      open={dropdownOpen}
      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("");

              if (
                systemNotificationEnabled
              ) {
                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>
  );
}