"use client";

import { useState, useEffect, useCallback } from "react";
import {
  Bell,
  CheckCheck,
  Film,
  MessageSquare,
  CheckCircle2,
  XCircle,
  AlertCircle,
  UserPlus,
  Clock,
  CornerDownRight,
  X,
  Trash2,
} from "lucide-react";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Button } from "@/components/ui/button";
import { ScrollArea } from "@/components/ui/scroll-area";
import { formatRelativeDate } from "@/lib/utils";
import { cn } from "@/lib/utils";
import Link from "next/link";

interface Notification {
  id: string;
  type: string;
  title: string;
  message: string;
  data: Record<string, string> | null;
  isRead: boolean;
  createdAt: string;
}

const TYPE_CONFIG: Record<
  string,
  { icon: React.ElementType; color: string; bg: string }
> = {
  VERSION_UPLOADED:       { icon: Film,            color: "text-blue-400",    bg: "bg-blue-500/10" },
  FEEDBACK_ADDED:         { icon: MessageSquare,   color: "text-amber-400",   bg: "bg-amber-500/10" },
  SHOT_APPROVED:          { icon: CheckCircle2,    color: "text-emerald-400", bg: "bg-emerald-500/10" },
  SHOT_REJECTED:          { icon: XCircle,         color: "text-red-400",     bg: "bg-red-500/10" },
  REVISION_REQUESTED:     { icon: AlertCircle,     color: "text-orange-400",  bg: "bg-orange-500/10" },
  COMMENT_REPLY:          { icon: CornerDownRight, color: "text-zinc-400",    bg: "bg-zinc-500/10" },
  MENTION:                { icon: MessageSquare,   color: "text-sky-400",     bg: "bg-sky-500/10" },
  TASK_ASSIGNED:          { icon: UserPlus,        color: "text-sky-400",     bg: "bg-sky-500/10" },
  TASK_READY_FOR_REVIEW:  { icon: Clock,           color: "text-purple-400",  bg: "bg-purple-500/10" },
  TASK_APPROVED:          { icon: CheckCircle2,    color: "text-emerald-400", bg: "bg-emerald-500/10" },
  TASK_CHANGES_REQUESTED: { icon: AlertCircle,     color: "text-orange-400",  bg: "bg-orange-500/10" },
  TASK_OVERDUE:           { icon: AlertCircle,     color: "text-red-400",     bg: "bg-red-500/10" },
};

function getNotificationHref(n: Notification): string | null {
  const data = n.data as Record<string, string> | null;
  if (data?.versionId) return `/review/${data.versionId}`;
  if (data?.taskId) return `/tasks?highlight=${data.taskId}`;
  return null;
}

export function NotificationBell() {
  const [notifications, setNotifications] = useState<Notification[]>([]);
  const [unreadCount, setUnreadCount] = useState(0);
  const [isLoading, setIsLoading] = useState(false);
  const [open, setOpen] = useState(false);

  const fetchNotifications = useCallback(async () => {
    setIsLoading(true);
    try {
      const res = await fetch("/api/notifications");
      if (res.ok) {
        const data = await res.json();
        setNotifications(data.notifications ?? []);
        setUnreadCount(data.unreadCount ?? 0);
      }
    } catch {
      // silent
    } finally {
      setIsLoading(false);
    }
  }, []);

  // Initial load + poll every 30s (skip while panel is open to avoid flicker)
  useEffect(() => {
    fetchNotifications();
    const interval = setInterval(() => {
      if (!open) fetchNotifications();
    }, 30_000);
    return () => clearInterval(interval);
  }, [fetchNotifications, open]);

  // Refresh full list whenever the panel opens
  useEffect(() => {
    if (open) fetchNotifications();
  }, [open, fetchNotifications]);

  const markAllRead = async () => {
    try {
      await fetch("/api/notifications", { method: "PATCH" });
      setNotifications((prev) => prev.map((n) => ({ ...n, isRead: true })));
      setUnreadCount(0);
    } catch {
      // silent
    }
  };

  const markOneRead = useCallback(
    async (id: string) => {
      const n = notifications.find((n) => n.id === id);
      if (!n || n.isRead) return;
      try {
        await fetch(`/api/notifications/${id}`, { method: "PATCH" });
        setNotifications((prev) =>
          prev.map((n) => (n.id === id ? { ...n, isRead: true } : n))
        );
        setUnreadCount((prev) => Math.max(0, prev - 1));
      } catch {
        // silent
      }
    },
    [notifications]
  );

  const dismiss = async (e: React.MouseEvent, id: string) => {
    e.preventDefault();
    e.stopPropagation();
    const wasUnread = notifications.find((n) => n.id === id)?.isRead === false;
    try {
      await fetch(`/api/notifications/${id}`, { method: "DELETE" });
      setNotifications((prev) => prev.filter((n) => n.id !== id));
      if (wasUnread) setUnreadCount((prev) => Math.max(0, prev - 1));
    } catch {
      // silent
    }
  };

  const clearAll = async () => {
    try {
      await fetch("/api/notifications", { method: "DELETE" });
      setNotifications([]);
      setUnreadCount(0);
    } catch {
      // silent
    }
  };

  return (
    <DropdownMenu open={open} onOpenChange={setOpen}>
      <DropdownMenuTrigger asChild>
        <Button variant="ghost" size="icon-sm" className="relative">
          <Bell className="h-4 w-4" />
          {unreadCount > 0 && (
            <span className="absolute -top-0.5 -right-0.5 flex h-4 w-4 items-center justify-center rounded-full bg-primary text-[9px] font-bold text-primary-foreground">
              {unreadCount > 9 ? "9+" : unreadCount}
            </span>
          )}
        </Button>
      </DropdownMenuTrigger>

      <DropdownMenuContent align="end" className="w-96 p-0">
        {/* Header */}
        <div className="flex items-center justify-between px-4 py-3 border-b border-border">
          <div className="flex items-center gap-2">
            <span className="text-sm font-semibold">Notifications</span>
            {unreadCount > 0 && (
              <span className="inline-flex items-center justify-center h-5 min-w-5 px-1.5 rounded-full bg-primary text-[10px] font-bold text-primary-foreground">
                {unreadCount}
              </span>
            )}
          </div>
          {unreadCount > 0 && (
            <Button
              variant="ghost"
              size="sm"
              className="h-7 px-2 text-xs text-muted-foreground hover:text-foreground"
              onClick={markAllRead}
            >
              <CheckCheck className="h-3 w-3 mr-1" />
              Mark all read
            </Button>
          )}
        </div>

        {/* Notification list */}
        <ScrollArea className="max-h-[480px]">
          {isLoading && notifications.length === 0 ? (
            <div className="flex items-center justify-center py-10">
              <div className="h-5 w-5 animate-spin rounded-full border-2 border-primary border-t-transparent" />
            </div>
          ) : notifications.length === 0 ? (
            <div className="flex flex-col items-center justify-center py-12 text-muted-foreground gap-2">
              <Bell className="h-8 w-8 opacity-20" />
              <p className="text-sm">You&rsquo;re all caught up</p>
            </div>
          ) : (
            <div>
              {notifications.map((n) => {
                const href = getNotificationHref(n);
                const cfg = TYPE_CONFIG[n.type] ?? {
                  icon: Bell,
                  color: "text-zinc-400",
                  bg: "bg-zinc-500/10",
                };
                const Icon = cfg.icon;

                const inner = (
                  <div
                    className={cn(
                      "flex gap-3 px-4 py-3 border-b border-border/50 last:border-0 group/row relative transition-colors",
                      !n.isRead ? "bg-primary/5" : "",
                      (href || !n.isRead) && "hover:bg-secondary/40"
                    )}
                  >
                    {/* Type icon */}
                    <div className={cn("mt-0.5 shrink-0 rounded-full p-1.5", cfg.bg)}>
                      <Icon className={cn("h-3.5 w-3.5", cfg.color)} />
                    </div>

                    {/* Message + time */}
                    <div className="flex-1 min-w-0 pr-5">
                      <p
                        className={cn(
                          "text-xs leading-relaxed text-foreground",
                          !n.isRead && "font-medium"
                        )}
                      >
                        {n.message}
                      </p>
                      <p className="text-[11px] text-muted-foreground mt-0.5">
                        {formatRelativeDate(new Date(n.createdAt))}
                      </p>
                    </div>

                    {/* Unread dot */}
                    {!n.isRead && (
                      <div className="absolute right-7 top-4 h-1.5 w-1.5 rounded-full bg-primary shrink-0" />
                    )}

                    {/* Dismiss button */}
                    <button
                      onClick={(e) => dismiss(e, n.id)}
                      className="absolute right-2 top-2.5 opacity-0 group-hover/row:opacity-100 p-0.5 rounded text-muted-foreground hover:text-foreground transition-all"
                      title="Dismiss"
                    >
                      <X className="h-3 w-3" />
                    </button>
                  </div>
                );

                if (href) {
                  return (
                    <Link
                      key={n.id}
                      href={href}
                      className="block"
                      onClick={() => markOneRead(n.id)}
                    >
                      {inner}
                    </Link>
                  );
                }

                return (
                  <div
                    key={n.id}
                    onClick={() => markOneRead(n.id)}
                    className="cursor-default"
                  >
                    {inner}
                  </div>
                );
              })}
            </div>
          )}
        </ScrollArea>

        {/* Footer */}
        {notifications.length > 0 && (
          <div className="flex items-center justify-center px-4 py-2 border-t border-border">
            <button
              onClick={clearAll}
              className="flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground transition-colors"
            >
              <Trash2 className="h-3 w-3" />
              Clear all
            </button>
          </div>
        )}
      </DropdownMenuContent>
    </DropdownMenu>
  );
}
