"use client";

import { useEffect, useRef, useState, useSyncExternalStore } from 'react';
import { usePathname } from 'next/navigation';
import Link from './site-link';
import { campaignFromUrl, ga4EventParameters, linkDestination, safeLabel, safePath, trackingHash, type TrackingEvent } from '../lib/tracking-policy';
import type { AnalyticsConfig } from '../lib/analytics-config';

type Consent = 'granted' | 'denied' | null;
type Attribution = { landing_path: string; referrer_host: string; [key: string]: string };
type Clarity = ((...args: unknown[]) => void) & { q?: unknown[][] };
declare global {
  interface Window {
    portalConversionEvents?: TrackingEvent[];
    dataLayer?: unknown[];
    gtag?: (...args: unknown[]) => void;
    clarity?: Clarity;
  }
}
const CONSENT_KEY = 'portal.analytics-consent.v1';
const ATTRIBUTION_KEY = 'portal.attribution.v1';
const EMPTY: TrackingEvent[] = [];
function subscribe(listener: () => void) {
  window.addEventListener('portal:conversion', listener);
  return () => window.removeEventListener('portal:conversion', listener);
}
function snapshot() { return window.portalConversionEvents ?? EMPTY; }
function region(element: Element) {
  return element.closest('dialog') ? 'menu' : element.closest('header') ? 'header' : element.closest('footer') ? 'footer' : element.closest('main') ? 'content' : 'floating';
}
function elementKey(element: Element) {
  const parts: string[] = [];
  let node: Element | null = element;
  while (node && node.tagName !== 'BODY') {
    parts.push(`${node.tagName}:${node.parentElement ? Array.from(node.parentElement.children).indexOf(node) : 0}`);
    node = node.parentElement;
  }
  return trackingHash(parts.join('/'));
}
function loadScript(id: string, src: string) {
  if (document.getElementById(id)) return;
  const script = document.createElement('script');
  script.id = id; script.async = true; script.src = src;
  document.head.appendChild(script);
}

export function ConversionTracking({ config }: { config: AnalyticsConfig }) {
  const pathname = usePathname();
  const events = useSyncExternalStore(subscribe, snapshot, () => EMPTY);
  const [consent, setConsent] = useState<Consent>(null);
  const [preferencesOpen, setPreferencesOpen] = useState(false);
  const [available, setAvailable] = useState(false);
  const attribution = useRef<Attribution | null>(null);
  const send = useRef<(event: TrackingEvent) => void>(() => {});
  const lastDiagnosticPage = useRef('');
  const lastExternalPage = useRef('');

  useEffect(() => {
    const local = /^(localhost|127\.|\[::1\])/.test(location.hostname);
    const active = config.enabled && (!local || config.allowLocal) && (/^G-[A-Z0-9]+$/.test(config.ga4Id) || /^[a-z0-9]+$/i.test(config.clarityId));
    let saved: Consent = null;
    try { const value = localStorage.getItem(CONSENT_KEY); if (value === 'granted' || value === 'denied') saved = value; } catch { /* Browser storage or referrer may be unavailable. */ }
    const timer = window.setTimeout(() => { setAvailable(active); setConsent(saved); }, 0);
    return () => window.clearTimeout(timer);
  }, [config]);

  useEffect(() => {
    if (!available || consent !== 'granted') return;
    if (/^G-[A-Z0-9]+$/.test(config.ga4Id) && !document.getElementById('portal-ga4')) {
      window.dataLayer ??= [];
      // gtag's documented queue uses Arguments objects, not event objects.
      // eslint-disable-next-line prefer-rest-params
      window.gtag ??= function () { window.dataLayer!.push(arguments); };
      window.gtag('consent', 'default', { analytics_storage: 'granted', ad_storage: 'denied', ad_user_data: 'denied', ad_personalization: 'denied' });
      window.gtag('js', new Date());
      window.gtag('config', config.ga4Id, { send_page_view: false, allow_google_signals: false, allow_ad_personalization_signals: false, page_location: location.origin + safePath(location.pathname), page_referrer: '' });
      loadScript('portal-ga4', `https://www.googletagmanager.com/gtag/js?id=${config.ga4Id}`);
    }
    // Full native navigation ensures these exclusions apply before the recorder loads.
    if (/^[a-z0-9]+$/i.test(config.clarityId) && pathname !== '/orcamento' && !location.search) {
      if (!window.clarity) {
        const clarity: Clarity = (...args) => { (clarity.q ??= []).push(args); };
        window.clarity = clarity;
      }
      window.clarity('consentv2', { analytics_Storage: 'granted', ad_Storage: 'denied' });
      loadScript('portal-clarity', `https://www.clarity.ms/tag/${config.clarityId}`);
    }
  }, [available, consent, config, pathname]);

  useEffect(() => {
    if (!attribution.current) {
      let host = '';
      try { host = document.referrer ? new URL(document.referrer).hostname : ''; } catch { /* Browser storage or referrer may be unavailable. */ }
      attribution.current = { landing_path: safePath(location.pathname), referrer_host: host, ...campaignFromUrl(location.href) };
    }
    if (available && consent === 'granted') {
      try {
        const saved = JSON.parse(sessionStorage.getItem(ATTRIBUTION_KEY) || 'null');
        if (saved && typeof saved.landing_path === 'string') {
          const restored: Attribution = { landing_path: safePath(saved.landing_path), referrer_host: typeof saved.referrer_host === 'string' && /^[a-z0-9.-]+$/i.test(saved.referrer_host) ? saved.referrer_host : '' };
          for (const key of ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_id']) if (safeLabel(saved[key])) restored[key] = saved[key];
          attribution.current = restored;
        }
        sessionStorage.setItem(ATTRIBUTION_KEY, JSON.stringify(attribution.current));
      } catch { /* Browser storage or referrer may be unavailable. */ }
    }
    function record(event: TrackingEvent) {
      const payload = { ...attribution.current, ...event, event_id: crypto.randomUUID(), event_time: Date.now() } as TrackingEvent;
      if (event.event !== 'page_view' || lastDiagnosticPage.current !== pathname) {
        if (event.event === 'page_view') lastDiagnosticPage.current = pathname;
        window.portalConversionEvents = [...(window.portalConversionEvents ?? []), payload].slice(-200);
        window.dispatchEvent(new CustomEvent('portal:conversion', { detail: payload }));
      }
      if (!available || consent !== 'granted') return;
      if (event.event === 'page_view') {
        if (lastExternalPage.current === pathname) return;
        lastExternalPage.current = pathname;
      }
      const name = payload.event;
      const params = ga4EventParameters(payload);
      if (/^G-[A-Z0-9]+$/.test(config.ga4Id)) window.gtag?.('event', name, { ...params, campaign_source: payload.utm_source, campaign_medium: payload.utm_medium, campaign_name: payload.utm_campaign, campaign_content: payload.utm_content, campaign_id: payload.utm_id, send_to: config.ga4Id, page_location: location.origin + safePath(location.pathname), page_referrer: payload.referrer_host ? `https://${payload.referrer_host}/` : '', transport_type: 'beacon', ...(config.debug ? { debug_mode: true } : {}) });
      if (name === 'whatsapp_click') {
        window.clarity?.('set', 'cta_id', String(payload.cta_position));
        window.clarity?.('event', 'whatsapp_click');
      }
    }
    send.current = record;
    record({ event: 'page_view', page_path: safePath(pathname) });
    function restored(event: PageTransitionEvent) {
      if (!event.persisted) return;
      lastDiagnosticPage.current = ''; lastExternalPage.current = '';
      record({ event: 'page_view', page_path: safePath(pathname) });
    }
    window.addEventListener('pageshow', restored);
    return () => { send.current = () => {}; window.removeEventListener('pageshow', restored); };
  }, [pathname, available, consent, config]);

  useEffect(() => {
    function track(event: MouseEvent) {
      if (event.type === 'auxclick' && event.button !== 1) return;
      const target = event.target instanceof Element ? event.target : null;
      if (!target || target.closest('[data-tracking-ignore]')) return;
      const element = target.closest<HTMLElement>('a,button,summary,[role="button"],input[type="submit"]') ?? target;
      if (element.matches(':disabled,[aria-disabled="true"]')) return;
      const link = element.closest<HTMLAnchorElement>('a');
      const destination = link ? linkDestination(link.href, location.origin) : '';
      const cta = safeLabel((element as HTMLElement).dataset.cta);
      const key = elementKey(element);
      const productCode = element.closest<HTMLElement>('[data-product-code]')?.dataset.productCode;
      const payload: TrackingEvent = {
        event: destination === 'whatsapp' ? 'whatsapp_click' : link ? 'link_click' : 'ui_click',
        page_path: safePath(location.pathname),
        element_id: safeLabel((element as HTMLElement).dataset.trackId) || cta || `${region(element)}_${key}`,
        element_instance: key, element_type: element.tagName.toLowerCase(), section: region(element),
        interaction: event.detail === 0 ? 'keyboard' : event.button === 1 ? 'middle_click' : 'pointer',
      };
      if (destination) payload.link_destination = destination;
      if (destination === 'whatsapp') payload.cta_position = cta || `${region(element)}_whatsapp_${key}`;
      if (productCode && /^\d{1,8}$/.test(productCode)) payload.product_id = productCode;
      if (event.detail > 0) {
        payload.click_x_percent = Math.round(event.pageX / Math.max(document.documentElement.scrollWidth, 1) * 100);
        payload.click_y_percent = Math.round(event.pageY / Math.max(document.documentElement.scrollHeight, 1) * 100);
        payload.viewport_width = window.innerWidth;
      }
      send.current(payload);
    }
    const thresholds = new Set<number>();
    let scheduled = false;
    function scroll() {
      if (scheduled) return;
      scheduled = true;
      requestAnimationFrame(() => {
        scheduled = false;
        const height = document.documentElement.scrollHeight;
        const percent = (window.scrollY + window.innerHeight) / height * 100;
        for (const threshold of [25, 50, 75, 90]) if (height > innerHeight && percent >= threshold && !thresholds.has(threshold)) {
          thresholds.add(threshold);
          send.current({ event: 'scroll_depth', page_path: safePath(location.pathname), percent_scrolled: threshold });
        }
      });
    }
    document.addEventListener('click', track, true);
    document.addEventListener('auxclick', track, true);
    window.addEventListener('scroll', scroll, { passive: true });
    return () => { document.removeEventListener('click', track, true); document.removeEventListener('auxclick', track, true); window.removeEventListener('scroll', scroll); };
  }, [pathname]);

  function choose(value: Exclude<Consent, null>) {
    try { localStorage.setItem(CONSENT_KEY, value); } catch { /* Browser storage or referrer may be unavailable. */ }
    if (value === 'denied') {
      window.gtag?.('consent', 'update', { analytics_storage: 'denied', ad_storage: 'denied', ad_user_data: 'denied', ad_personalization: 'denied' });
      window.clarity?.('consentv2', { analytics_Storage: 'denied', ad_Storage: 'denied' });
      try { sessionStorage.removeItem(ATTRIBUTION_KEY); } catch { /* Browser storage or referrer may be unavailable. */ }
      if (consent === 'granted') { location.reload(); return; }
    }
    setConsent(value); setPreferencesOpen(false);
  }
  return <>
    <output id="portal-conversion-diagnostics" hidden data-clarity-mask="true">{JSON.stringify(events)}</output>
    {available && <div className="analytics-preferences" data-tracking-ignore>
      {(consent === null || preferencesOpen) ? <section className="analytics-consent" aria-label="Preferências de privacidade"><h2>Podemos entender como você usa o site?</h2><p>Com sua permissão, usamos estatísticas de navegação e mapas de cliques para melhorar o atendimento. A lista e as mensagens de orçamento ficam fora das gravações.</p><Link href="/privacidade">Como usamos os dados</Link><div><button className="button button--primary" onClick={() => choose('granted')}>Permitir análise</button><button className="button button--outline" onClick={() => choose('denied')}>Continuar sem análise</button></div></section> : <button className="analytics-manage" onClick={() => setPreferencesOpen(true)}>Preferências de privacidade</button>}
    </div>}
  </>;
}
