type GtagFn = (...args: unknown[]) => void;

const TEXT_LIMIT = 80;

function gtag(): GtagFn | null {
  if (typeof window === 'undefined') return null;
  const fn = (window as unknown as { gtag?: GtagFn }).gtag;
  return typeof fn === 'function' ? fn : null;
}

export function trackPageView(path: string, title: string): void {
  const send = gtag();
  if (!send) return;
  send('event', 'page_view', {
    page_path: path,
    page_title: title,
    page_location: window.location.href
  });
}

function getLabel(el: HTMLElement): string {
  const aria = el.getAttribute('aria-label');
  if (aria) return aria.trim().slice(0, TEXT_LIMIT);
  const text = (el.textContent ?? '').replace(/\s+/g, ' ').trim();
  if (text) return text.slice(0, TEXT_LIMIT);
  const title = el.getAttribute('title');
  if (title) return title.trim().slice(0, TEXT_LIMIT);
  return '';
}

function getLocation(el: HTMLElement): string {
  const dataLoc = el.closest<HTMLElement>('[data-track-location]');
  if (dataLoc?.dataset.trackLocation) {
    return dataLoc.dataset.trackLocation.slice(0, TEXT_LIMIT);
  }
  const section = el.closest<HTMLElement>('section[id]');
  if (section?.id) return section.id;
  if (el.closest('header')) return 'header';
  if (el.closest('footer')) return 'footer';
  if (el.closest('nav')) return 'nav';
  return 'body';
}

export function initClickTracking(): () => void {
  if (typeof window === 'undefined') return () => {};

  const handler = (event: MouseEvent) => {
    const send = gtag();
    if (!send) return;
    const target = event.target;
    if (!(target instanceof Element)) return;
    const interactive = target.closest<HTMLElement>('a, button, [role="button"]');
    if (!interactive) return;

    const isLink = interactive.tagName === 'A';
    const label = getLabel(interactive);
    const location = getLocation(interactive);

    const params: Record<string, unknown> = {
      element: isLink ? 'link' : 'button',
      label,
      location,
      page_path: window.location.pathname
    };

    if (isLink) {
      const href = (interactive as HTMLAnchorElement).href;
      if (href) {
        params.link_url = href;
        try {
          const url = new URL(href, window.location.href);
          params.outbound = url.hostname !== window.location.hostname;
        } catch {
          params.outbound = false;
        }
      }
    } else {
      const btn = interactive as HTMLButtonElement;
      if (btn.type) params.button_type = btn.type;
      if (btn.name) params.button_name = btn.name;
    }

    send('event', isLink ? 'link_click' : 'button_click', params);
  };

  document.addEventListener('click', handler, { capture: true });
  return () => document.removeEventListener('click', handler, { capture: true });
}
