"use client";

import { useEffect } from "react";
import { useQuery } from "@tanstack/react-query";
import { fetchNotifications } from "@/lib/api/notifications";
import { useAuthStore } from "@/lib/stores/auth.store";
import { useNotifPrefs } from "@/lib/notifications/notification-prefs.store";

const ICON_REL = "icon";
const PREFIX_RE = /^\(\d+\+?\)\s*/;

function stripCount(title: string): string {
  return title.replace(PREFIX_RE, "");
}

function ensureFaviconLink(): HTMLLinkElement | null {
  if (typeof document === "undefined") return null;
  let link = document.querySelector<HTMLLinkElement>('link[rel~="icon"]');
  if (!link) {
    link = document.createElement("link");
    link.rel = ICON_REL;
    document.head.appendChild(link);
  }
  return link;
}

/** Draw the base icon with a red count badge onto a 64px canvas; returns a data URL. */
function buildBadgedFavicon(baseSrc: string, count: number): Promise<string> {
  return new Promise((resolve, reject) => {
    const size = 64;
    const canvas = document.createElement("canvas");
    canvas.width = size;
    canvas.height = size;
    const ctx = canvas.getContext("2d");
    if (!ctx) {
      reject(new Error("no 2d context"));
      return;
    }
    const draw = (drawBase?: () => void) => {
      drawBase?.();
      // Badge bubble (top-end corner).
      const r = 22;
      const cx = size - r + 2;
      const cy = r - 2;
      ctx.beginPath();
      ctx.arc(cx, cy, r, 0, Math.PI * 2);
      ctx.fillStyle = "#DC2626";
      ctx.fill();
      ctx.lineWidth = 4;
      ctx.strokeStyle = "#ffffff";
      ctx.stroke();
      // Count text.
      const label = count > 9 ? "9+" : String(count);
      ctx.fillStyle = "#ffffff";
      ctx.font = "bold 30px Arial, sans-serif";
      ctx.textAlign = "center";
      ctx.textBaseline = "middle";
      ctx.fillText(label, cx, cy + 1);
      resolve(canvas.toDataURL("image/png"));
    };

    const img = new Image();
    img.onload = () => draw(() => ctx.drawImage(img, 0, 0, size, size));
    img.onerror = () =>
      // Fall back to a Meezi-green rounded square if the base icon can't load.
      draw(() => {
        ctx.fillStyle = "#0F6E56";
        ctx.beginPath();
        const rr = 12;
        ctx.moveTo(rr, 0);
        ctx.arcTo(size, 0, size, size, rr);
        ctx.arcTo(size, size, 0, size, rr);
        ctx.arcTo(0, size, 0, 0, rr);
        ctx.arcTo(0, 0, size, 0, rr);
        ctx.fill();
      });
    img.src = baseSrc;
  });
}

/**
 * Reflects the unread-notification count on the browser tab: a `(N)` prefix on the
 * title plus a numbered badge on the favicon. Driven by the shared notifications
 * query (no extra SignalR connection — the topbar feed keeps that cache fresh).
 * Mount once in the dashboard shell.
 */
export function useTabBadge() {
  const cafeId = useAuthStore((s) => s.user?.cafeId);
  const tabBadgeEnabled = useNotifPrefs((s) => s.tabBadgeEnabled);

  // Same query key as useNotificationsFeed → shares the cache, no duplicate fetch.
  const { data } = useQuery({
    queryKey: ["notifications", cafeId, false],
    queryFn: () => fetchNotifications(cafeId!, false, 50),
    enabled: !!cafeId,
    refetchInterval: 60_000,
  });

  const unread = data?.unreadCount ?? 0;
  const count = tabBadgeEnabled ? unread : 0;

  // --- Title prefix (survives Next.js route-driven <title> changes via observer) ---
  useEffect(() => {
    if (typeof document === "undefined") return;
    const titleEl = document.querySelector("title");

    const apply = () => {
      const base = stripCount(document.title);
      const next = count > 0 ? `(${count > 9 ? "9+" : count}) ${base}` : base;
      if (document.title !== next) document.title = next;
    };

    apply();

    // Re-apply when something else (router) rewrites the title.
    let observer: MutationObserver | undefined;
    if (titleEl) {
      observer = new MutationObserver(() => apply());
      observer.observe(titleEl, { childList: true });
    }

    return () => {
      observer?.disconnect();
      document.title = stripCount(document.title);
    };
  }, [count]);

  // --- Favicon badge ---
  useEffect(() => {
    if (typeof document === "undefined") return;
    const link = ensureFaviconLink();
    if (!link) return;

    // Remember the original href once so we can restore it.
    const originalHref = link.dataset.originalHref ?? link.href ?? "/favicon.ico";
    if (!link.dataset.originalHref) link.dataset.originalHref = originalHref;

    let cancelled = false;
    if (count > 0) {
      void buildBadgedFavicon(originalHref || "/icons/icon-32.png", count)
        .then((url) => {
          if (!cancelled) link.href = url;
        })
        .catch(() => {
          // leave the favicon as-is on failure
        });
    } else {
      link.href = originalHref;
    }

    return () => {
      cancelled = true;
      // Restore the plain favicon when the count changes or the shell unmounts.
      link.href = originalHref;
    };
  }, [count]);
}
