"use client";

import Link from "next/link";
import { useCallback, useEffect, useRef, useState } from "react";
import {
  InboxNotification,
  apiGet,
  apiPatch,
  apiPost,
} from "@/lib/api";

function formatRelativeTime(iso?: string | null): string {
  if (!iso) return "";
  const date = new Date(iso);
  const diffMs = Date.now() - date.getTime();
  const minutes = Math.floor(diffMs / 60000);
  if (minutes < 1) return "همین الان";
  if (minutes < 60) return `${minutes} دقیقه پیش`;
  const hours = Math.floor(minutes / 60);
  if (hours < 24) return `${hours} ساعت پیش`;
  return date.toLocaleDateString("fa-IR");
}

export function NotificationBell() {
  const rootRef = useRef<HTMLDivElement>(null);
  const [open, setOpen] = useState(false);
  const [unreadCount, setUnreadCount] = useState(0);
  const [items, setItems] = useState<InboxNotification[]>([]);
  const [loading, setLoading] = useState(false);

  const loadCount = useCallback(async () => {
    try {
      const data = await apiGet<{ count: number }>("/notifications/inbox/unread-count");
      setUnreadCount(data.count);
    } catch {
      /* ignore polling errors */
    }
  }, []);

  const loadItems = useCallback(async () => {
    setLoading(true);
    try {
      const data = await apiGet<{ data: InboxNotification[] }>("/notifications/inbox?per_page=15");
      setItems(data.data);
    } catch {
      setItems([]);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    void loadCount();
    const timer = window.setInterval(() => void loadCount(), 60000);
    return () => window.clearInterval(timer);
  }, [loadCount]);

  useEffect(() => {
    if (!open) return;
    void loadItems();
    const close = (event: MouseEvent) => {
      if (rootRef.current && !rootRef.current.contains(event.target as Node)) {
        setOpen(false);
      }
    };
    window.addEventListener("click", close);
    return () => window.removeEventListener("click", close);
  }, [open, loadItems]);

  const markRead = async (item: InboxNotification) => {
    if (!item.read_at) {
      try {
        await apiPatch(`/notifications/inbox/${item.id}/read`, {});
        setUnreadCount((count) => Math.max(0, count - 1));
        setItems((current) =>
          current.map((row) => (row.id === item.id ? { ...row, read_at: new Date().toISOString() } : row)),
        );
      } catch {
        /* ignore */
      }
    }
  };

  const markAllRead = async () => {
    try {
      await apiPost("/notifications/inbox/read-all", {});
      setUnreadCount(0);
      setItems((current) => current.map((row) => ({ ...row, read_at: row.read_at ?? new Date().toISOString() })));
    } catch {
      /* ignore */
    }
  };

  return (
    <div ref={rootRef} className="relative shrink-0">
      <button
        type="button"
        className="relative flex h-9 w-9 items-center justify-center rounded-xl bg-white/15 transition hover:bg-white/25"
        aria-label="اعلان‌ها"
        aria-expanded={open}
        onClick={(event) => {
          event.stopPropagation();
          setOpen((value) => !value);
        }}
      >
        <svg viewBox="0 0 24 24" className="h-5 w-5" fill="currentColor" aria-hidden>
          <path d="M12 22a2.5 2.5 0 0 0 2.45-2h-4.9A2.5 2.5 0 0 0 12 22zm7-6v-5a7 7 0 1 0-14 0v5l-2 2v1h18v-1l-2-2z" />
        </svg>
        {unreadCount > 0 ? (
          <span className="absolute -left-0.5 -top-0.5 flex h-4 min-w-4 items-center justify-center rounded-full bg-red-500 px-1 text-[10px] font-bold text-white">
            {unreadCount > 99 ? "99+" : unreadCount}
          </span>
        ) : null}
      </button>

      {open ? (
        <div className="absolute left-0 top-full z-50 mt-2 w-[min(22rem,calc(100vw-2rem))] overflow-hidden rounded-2xl border border-[var(--border)] bg-white text-foreground shadow-xl">
          <div className="flex items-center justify-between border-b border-[var(--border)] px-4 py-3">
            <p className="text-sm font-bold">اعلان‌ها</p>
            {unreadCount > 0 ? (
              <button
                type="button"
                className="text-xs font-semibold text-primary"
                onClick={() => void markAllRead()}
              >
                خواندن همه
              </button>
            ) : null}
          </div>

          <div className="max-h-80 overflow-y-auto">
            {loading ? (
              <p className="p-4 text-sm text-[var(--muted)]">در حال بارگذاری…</p>
            ) : items.length === 0 ? (
              <p className="p-4 text-sm text-[var(--muted)]">اعلانی وجود ندارد.</p>
            ) : (
              <ul>
                {items.map((item) => {
                  const href = typeof item.meta?.href === "string" ? item.meta.href : null;
                  const content = (
                    <>
                      <p className={`text-sm ${item.read_at ? "font-medium text-slate-700" : "font-bold text-slate-900"}`}>
                        {item.title}
                      </p>
                      <p className="mt-1 text-xs leading-6 text-[var(--muted)]">{item.body}</p>
                      <p className="mt-1 text-[10px] text-[var(--muted)]">{formatRelativeTime(item.created_at)}</p>
                    </>
                  );

                  return (
                    <li key={item.id} className="border-b border-[var(--border)] last:border-b-0">
                      {href ? (
                        <Link
                          href={href}
                          className="block px-4 py-3 hover:bg-slate-50"
                          onClick={() => {
                            void markRead(item);
                            setOpen(false);
                          }}
                        >
                          {content}
                        </Link>
                      ) : (
                        <button
                          type="button"
                          className="block w-full px-4 py-3 text-right hover:bg-slate-50"
                          onClick={() => void markRead(item)}
                        >
                          {content}
                        </button>
                      )}
                    </li>
                  );
                })}
              </ul>
            )}
          </div>
        </div>
      ) : null}
    </div>
  );
}
