{"version":3,"sources":["../../src/hooks/useTracking.ts"],"names":["useRef","useCallback","section","useEffect"],"mappings":"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","file":"index.cjs","sourcesContent":["'use client'\n\nimport { useEffect, useRef, useCallback } from 'react'\n\n/**\n * Section metadata for tracking\n */\nexport interface SectionMeta {\n  id: string\n  label: string\n  order: number\n  type?: string\n}\n\n/**\n * Tracking configuration\n */\nexport interface UseTrackingOptions {\n  /** Presentation ID for analytics */\n  presentationId: string\n  /** Access link ID (if using access control) */\n  accessLinkId?: string\n  /** Section metadata */\n  sections: SectionMeta[]\n  /** API endpoint for sending events */\n  apiEndpoint?: string\n  /** Whether tracking is enabled */\n  enabled?: boolean\n  /** Viewer email for identity tracking */\n  viewerEmail?: string\n}\n\n/**\n * Analytics event types\n */\ntype EventType =\n  | 'session_start'\n  | 'section_enter'\n  | 'section_exit'\n  | 'section_visible'\n  | 'session_end'\n  | 'engagement'\n\n/**\n * React hook for presentation tracking\n *\n * Initializes the Brixon tracking SDK and provides methods for\n * custom event tracking.\n *\n * @example\n * ```tsx\n * const { trackEngagement, sessionId } = useTracking({\n *   presentationId: 'acme-pitch',\n *   sections: [\n *     { id: 'hero', label: 'Introduction', order: 1 },\n *     { id: 'features', label: 'Features', order: 2 },\n *   ],\n * })\n *\n * // Track custom engagement\n * trackEngagement('cta_click', { buttonId: 'contact' })\n * ```\n */\nexport function useTracking(options: UseTrackingOptions) {\n  const {\n    presentationId,\n    accessLinkId,\n    sections,\n    apiEndpoint = '/api/analytics/track',\n    enabled = true,\n    viewerEmail,\n  } = options\n\n  const sessionIdRef = useRef<string>(\n    typeof crypto !== 'undefined' ? crypto.randomUUID() : `session-${Date.now()}`\n  )\n  const sessionStartRef = useRef<number>(Date.now())\n  const currentSectionRef = useRef<string | null>(null)\n  const sectionTimersRef = useRef<Map<string, number>>(new Map())\n  const eventQueueRef = useRef<Array<Record<string, unknown>>>([])\n  const observerRef = useRef<IntersectionObserver | null>(null)\n\n  // Send events to API\n  const flushEvents = useCallback(async () => {\n    if (eventQueueRef.current.length === 0) return\n\n    const events = [...eventQueueRef.current]\n    eventQueueRef.current = []\n\n    try {\n      await fetch(apiEndpoint, {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({ events }),\n        keepalive: true,\n      })\n    } catch {\n      // Re-queue on failure\n      eventQueueRef.current = [...events, ...eventQueueRef.current]\n    }\n  }, [apiEndpoint])\n\n  // Track event\n  const trackEvent = useCallback(\n    (type: EventType, data?: Record<string, unknown>) => {\n      const event = {\n        id: crypto.randomUUID(),\n        access_link_id: accessLinkId,\n        session_id: sessionIdRef.current,\n        event_type: type,\n        presentation_id: presentationId,\n        viewer_email: viewerEmail,\n        created_at: new Date().toISOString(),\n        time_on_page: Math.round((Date.now() - sessionStartRef.current) / 1000),\n        ...data,\n      }\n\n      eventQueueRef.current.push(event)\n\n      // Batch flush\n      if (eventQueueRef.current.length >= 10) {\n        flushEvents()\n      }\n    },\n    [accessLinkId, presentationId, viewerEmail, flushEvents]\n  )\n\n  // Section enter handler\n  const onSectionEnter = useCallback(\n    (sectionId: string) => {\n      if (currentSectionRef.current === sectionId) return\n\n      // Exit previous section\n      if (currentSectionRef.current) {\n        const enterTime = sectionTimersRef.current.get(currentSectionRef.current)\n        const duration = enterTime ? Math.round((Date.now() - enterTime) / 1000) : 0\n        const section = sections.find((s) => s.id === currentSectionRef.current)\n\n        trackEvent('section_exit', {\n          section_id: currentSectionRef.current,\n          section_label: section?.label,\n          section_order: section?.order,\n          duration_seconds: duration,\n        })\n\n        sectionTimersRef.current.delete(currentSectionRef.current)\n      }\n\n      // Enter new section\n      currentSectionRef.current = sectionId\n      sectionTimersRef.current.set(sectionId, Date.now())\n\n      const section = sections.find((s) => s.id === sectionId)\n      trackEvent('section_enter', {\n        section_id: sectionId,\n        section_label: section?.label,\n        section_order: section?.order,\n      })\n    },\n    [sections, trackEvent]\n  )\n\n  // Setup tracking\n  useEffect(() => {\n    if (!enabled || typeof window === 'undefined') return\n\n    // Track session start\n    trackEvent('session_start')\n\n    // Setup intersection observer\n    observerRef.current = new IntersectionObserver(\n      (entries) => {\n        entries.forEach((entry) => {\n          const sectionId = entry.target.getAttribute('data-section-id')\n          if (sectionId && entry.isIntersecting && entry.intersectionRatio > 0.5) {\n            onSectionEnter(sectionId)\n          }\n        })\n      },\n      { threshold: [0, 0.25, 0.5, 0.75, 1] }\n    )\n\n    // Observe sections\n    const sectionElements = document.querySelectorAll('[data-section-id]')\n    sectionElements.forEach((el) => observerRef.current?.observe(el))\n\n    // Batch flush interval\n    const flushInterval = setInterval(flushEvents, 2000)\n\n    // Session end handlers\n    const handleVisibilityChange = () => {\n      if (document.visibilityState === 'hidden') {\n        trackEvent('session_end', {\n          duration_seconds: Math.round((Date.now() - sessionStartRef.current) / 1000),\n        })\n        flushEvents()\n      }\n    }\n\n    const handleBeforeUnload = () => {\n      trackEvent('session_end', {\n        duration_seconds: Math.round((Date.now() - sessionStartRef.current) / 1000),\n      })\n      flushEvents()\n    }\n\n    document.addEventListener('visibilitychange', handleVisibilityChange)\n    window.addEventListener('beforeunload', handleBeforeUnload)\n\n    return () => {\n      clearInterval(flushInterval)\n      observerRef.current?.disconnect()\n      document.removeEventListener('visibilitychange', handleVisibilityChange)\n      window.removeEventListener('beforeunload', handleBeforeUnload)\n    }\n  }, [enabled, trackEvent, onSectionEnter, flushEvents])\n\n  // Manual engagement tracking\n  const trackEngagement = useCallback(\n    (interactionType: string, metadata?: Record<string, unknown>) => {\n      trackEvent('engagement', {\n        metadata: {\n          interaction_type: interactionType,\n          ...metadata,\n        },\n      })\n    },\n    [trackEvent]\n  )\n\n  return {\n    trackEngagement,\n    sessionId: sessionIdRef.current,\n  }\n}\n"]}