import type { ChatMessage } from '../types';

import { createFaviconBadge, type FaviconBadgeOptions } from './faviconBadge';
import { createTitleRotator, type TitleRotatorOptions } from './titleRotator';
import type { ChatNotifier } from './types';

export interface BrowserNotifierOptions {
  /** Title rotation config. Pass `false` to disable title mutation. */
  title?: TitleRotatorOptions | false;
  /** Favicon badge config. Pass `false` to disable favicon mutation. */
  favicon?: FaviconBadgeOptions | false;
}

const NOOP: ChatNotifier = { setUnread() {}, clear() {} };

/**
 * Facebook-style unread notifier: alternates `document.title` between
 * the base title and an alert, plus paints a small badge over the
 * favicon. Both surfaces are optional and individually toggleable.
 *
 * Returns a no-op in SSR or non-DOM environments — safe to construct
 * unconditionally.
 *
 * The notifier itself is **stateless w.r.t. visibility** by design;
 * the hook layer (`useChatUnreadNotifier`) decides when to call
 * `setUnread` vs `clear` based on page focus. Keeping the policy in
 * the hook lets hosts swap in their own notifier (Wails dock badge,
 * cross-tab Zustand broadcaster) without duplicating the gating logic.
 */
export function createBrowserNotifier(opts: BrowserNotifierOptions = {}): ChatNotifier {
  if (typeof document === 'undefined') return NOOP;

  const title = opts.title === false ? null : createTitleRotator(opts.title);
  const favicon = opts.favicon === false ? null : createFaviconBadge(opts.favicon);

  let active = false;

  return {
    setUnread(count: number, latest?: ChatMessage | null) {
      if (count <= 0) {
        this.clear();
        return;
      }
      if (active) {
        title?.update(count, latest);
        favicon?.set(count);
      } else {
        active = true;
        title?.start(count, latest);
        favicon?.set(count);
      }
    },
    clear() {
      if (!active) return;
      active = false;
      title?.stop();
      favicon?.clear();
    },
  };
}

export function createNoopNotifier(): ChatNotifier {
  return NOOP;
}
