"use client";

import { useRef } from "react";
import { useRouter } from "next/navigation";
import { useDispatch, useSelector } from "react-redux";
import type { AppDispatch, RootState } from "@/state/store";
import { markNotificationsAsRead } from "@/state/notification/notificationSlice";
import { useClickOutside } from "@/hooks/useClickOutside";
import type { NotificationItem } from "@/types/notification";
import {
  BoxPlusIcon,
  CheckCircleIcon,
  QuestionsIcon,
  ReceiptIcon,
  TagIcon,
  TrashIcon,
  UserFilledIcon,
  XCircleIcon,
} from "./icons";
import { getImageUrl, handleImageError, AVATAR_PLACEHOLDER_SVG } from "@/lib/imageUrl";

const visualByType: Record<string, { icon: React.ComponentType<{ className?: string }>; filled: boolean }> = {
  seller_registered: { icon: UserFilledIcon, filled: true },
  sellerRegistered: { icon: UserFilledIcon, filled: true },
  quote_received: { icon: ReceiptIcon, filled: false },
  quoteReceived: { icon: ReceiptIcon, filled: false },
  offer_submitted: { icon: TagIcon, filled: false },
  offerSubmitted: { icon: TagIcon, filled: false },
  product_listed: { icon: BoxPlusIcon, filled: false },
  productListed: { icon: BoxPlusIcon, filled: false },
  question_asked: { icon: QuestionsIcon, filled: false },
  questionAsked: { icon: QuestionsIcon, filled: false },
  offer_accepted: { icon: CheckCircleIcon, filled: false },
  offerAccepted: { icon: CheckCircleIcon, filled: false },
  offer_declined: { icon: XCircleIcon, filled: false },
  offerDeclined: { icon: XCircleIcon, filled: false },
  product_removed: { icon: TrashIcon, filled: false },
  productRemoved: { icon: TrashIcon, filled: false },
};

function getNotificationLink(notification: NotificationItem): string | null {
  const { entityType, entityId, metadata } = notification;
  const meta = metadata || {};

  // 1. Enquiries / Questions
  if (entityType === "enquiry" || meta.enquiryId) {
    const id = meta.enquiryId || entityId;
    return id ? `/questions?id=${encodeURIComponent(id)}` : "/questions";
  }

  // 2. Offers
  if (entityType === "offer" || meta.offerId) {
    const id = meta.offerId || entityId;
    return id ? `/offers?id=${encodeURIComponent(id)}` : "/offers";
  }

  // 3. Quotes
  if (entityType === "quote" || meta.quoteId) {
    const id = meta.quoteId || entityId;
    return id ? `/quotes?id=${encodeURIComponent(id)}` : "/quotes";
  }

  // 4. Sellers
  if (entityType === "seller" || meta.sellerId) {
    const id = meta.sellerId || entityId;
    return id ? `/sellers/${encodeURIComponent(id)}` : "/sellers";
  }

  // 5. Listings / Products
  if (entityType === "listing" || meta.listingId) {
    const isUsed =
      meta.productType === "used-product" ||
      meta.listingType === "used" ||
      notification.type === "used_product_listed";
    return isUsed ? "/products/used" : "/products/new";
  }

  return null;
}

export default function NotificationMenu({ open, onClose }: { open: boolean; onClose: () => void }) {
  const router = useRouter();
  const menuRef = useRef<HTMLDivElement | null>(null);
  const dispatch = useDispatch<AppDispatch>();
  const { notifications, loading } = useSelector((state: RootState) => state.notification);

  useClickOutside(menuRef, onClose, open);

  if (!open) return null;

  const handleMarkAllAsRead = () => {
    dispatch(markNotificationsAsRead({ all: true }));
  };

  const handleItemClick = (notification: NotificationItem) => {
    if (!notification.isRead) {
      dispatch(markNotificationsAsRead({ ids: [notification.id] }));
    }

    const targetUrl = getNotificationLink(notification);
    if (targetUrl) {
      onClose();
      router.push(targetUrl);
    }
  };

  return (
    <div
      ref={menuRef}
      className="absolute right-0 top-[calc(100%+10px)] z-50 flex max-h-[calc(100vh-120px)] w-[640px] flex-col overflow-hidden rounded-xl border border-[#E4E7EC] bg-white shadow-[0_18px_40px_rgba(15,23,42,0.16)]"
    >
      <div className="flex-shrink-0 border-b border-[#E4E7EC] px-4 py-3">
        <div className="flex items-start justify-between gap-3">
          <div>
            <h3 className="text-[14px] font-semibold text-[#101828]">Notifications</h3>
            <p className="mt-0.5 text-[11px] text-[#667085]">
              Stay informed about new registrations, quotes, offers, and deals across the platform.
            </p>
          </div>
          {notifications.some((n) => !n.isRead) && (
            <button
              type="button"
              onClick={handleMarkAllAsRead}
              className="shrink-0 text-[11px] font-medium text-[#1657D9] hover:underline cursor-pointer"
            >
              Mark all as Read
            </button>
          )}
        </div>
      </div>

      <div className="thin-scrollbar min-h-0 flex-1 overflow-y-auto">
        {loading && notifications.length === 0 ? (
          <div className="space-y-3 p-4">
            {[1, 2, 3].map((i) => (
              <div key={i} className="flex gap-3">
                <div className="h-8 w-8 animate-pulse rounded-full bg-[#F2F4F7]" />
                <div className="flex-1 space-y-1.5">
                  <div className="h-3.5 w-40 animate-pulse rounded bg-[#F2F4F7]" />
                  <div className="h-3 w-full animate-pulse rounded bg-[#F2F4F7]" />
                </div>
              </div>
            ))}
          </div>
        ) : notifications.length === 0 ? (
          <div className="p-8 text-center text-[13px] text-[#667085]">
            No notifications from the past 7 days.
          </div>
        ) : (
          notifications.map((notification) => {
            const visual = visualByType[notification.type] || {
              icon: BellFallbackIcon,
              filled: false,
            };
            const Icon = visual.icon;

            return (
              <button
                key={notification.id}
                type="button"
                onClick={() => handleItemClick(notification)}
                className={`flex w-full items-start gap-3 border-b border-[#F2F4F7] px-4 py-3 text-left transition-colors last:border-b-0 hover:bg-[#F9FBFF] cursor-pointer ${
                  notification.isRead ? "bg-white" : "bg-[#F4F8FF]"
                }`}
              >
                {notification.image ? (
                  // eslint-disable-next-line @next/next/no-img-element
                  <img
                    src={getImageUrl(notification.image)}
                    alt=""
                    className="h-8 w-8 shrink-0 rounded-full border border-[#E4E7EC] object-cover"
                    onError={(e) => handleImageError(e, AVATAR_PLACEHOLDER_SVG)}
                  />
                ) : (
                  <span
                    className={`flex h-8 w-8 shrink-0 items-center justify-center rounded-full ${
                      visual.filled ? "bg-[#0F2A5C]" : "border border-[#E4E7EC] bg-white text-[#475467]"
                    }`}
                  >
                    <Icon className={visual.filled ? "" : undefined} />
                  </span>
                )}

                <span className="min-w-0 flex-1">
                  <span className="flex items-start justify-between gap-3">
                    <span className="text-[13px] font-semibold text-[#101828]">
                      {notification.title}
                    </span>
                    <span className="shrink-0 text-[11px] text-[#98A2B3]">
                      {notification.timeAgo}
                    </span>
                  </span>
                  <span className="mt-0.5 block text-[12px] leading-5 text-[#667085]">
                    {notification.message}
                  </span>
                </span>
              </button>
            );
          })
        )}
      </div>
    </div>
  );
}

function BellFallbackIcon({ className }: { className?: string }) {
  return (
    <svg width="15" height="15" viewBox="0 0 20 20" fill="none" className={className} aria-hidden="true">
      <path
        d="M5 8a5 5 0 0 1 10 0c0 3.4 1 4.7 1.5 5.3H3.5C4 12.7 5 11.4 5 8Z"
        stroke="currentColor"
        strokeWidth="1.4"
        strokeLinejoin="round"
      />
      <path d="M8.5 16.5a1.5 1.5 0 0 0 3 0" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" />
    </svg>
  );
}
