/**
 * Error Context Bridge
 *
 * Links user actions to errors for debugging:
 * - Ring buffer storing last 10 user actions
 * - PostHog session ID retrieval
 * - Constructs PostHog replay URLs
 *
 * Used by Sentry to attach user context to errors
 */

import { posthog } from "posthog-js";

// ============================================================================
// Types
// ============================================================================

export interface UserAction {
  timestamp: string;
  action: string;
  component?: string;
  location?: string;
  page?: string;
  data?: Record<string, unknown>;
}

export interface ErrorContext {
  sessionId: string | null;
  sessionUrl: string | null;
  distinctId: string | null;
  recentActions: string[];
  actionDetails: UserAction[];
}

// ============================================================================
// Ring Buffer for User Actions
// ============================================================================

// Store last 20 actions to capture more context for debugging
// ~2KB memory footprint
const MAX_ACTIONS = 20;
const actionBuffer: UserAction[] = [];

/**
 * Records a user action to the ring buffer
 * @param action - Action description (e.g., "click:signup_cta")
 * @param options - Additional context
 */
export function recordAction(
  action: string,
  options?: {
    component?: string;
    location?: string;
    data?: Record<string, unknown>;
  },
): void {
  if (typeof window === "undefined") return;

  const userAction: UserAction = {
    timestamp: new Date().toISOString(),
    action,
    component: options?.component,
    location: options?.location,
    page: window.location.pathname,
    data: options?.data,
  };

  // Add to ring buffer, removing oldest if at capacity
  if (actionBuffer.length >= MAX_ACTIONS) {
    actionBuffer.shift();
  }
  actionBuffer.push(userAction);
}

/**
 * Formats a user action for display in Sentry
 */
function formatAction(action: UserAction): string {
  const parts = [action.timestamp, action.action];
  if (action.location) {
    parts[1] = `${action.action}@${action.location}`;
  }
  return parts.join(": ");
}

/**
 * Gets the PostHog session ID
 */
function getPostHogSessionId(): string | null {
  if (typeof window === "undefined") return null;

  try {
    // PostHog stores session ID in the session recording
    const sessionId = posthog.get_session_id?.();
    return sessionId || null;
  } catch {
    return null;
  }
}

/**
 * Gets the PostHog distinct ID (user identifier)
 */
function getPostHogDistinctId(): string | null {
  if (typeof window === "undefined") return null;

  try {
    const distinctId = posthog.get_distinct_id?.();
    return distinctId || null;
  } catch {
    return null;
  }
}

/**
 * Constructs a PostHog session replay URL
 */
function getPostHogSessionUrl(sessionId: string | null): string | null {
  if (!sessionId) return null;

  const apiHost =
    process.env.NEXT_PUBLIC_POSTHOG_HOST || "https://app.posthog.com";
  // Remove /ingest if present in the host
  const baseHost = apiHost.replace("/ingest", "");

  return `${baseHost}/replay/${sessionId}`;
}

/**
 * Gets complete error context for Sentry
 * Call this when an error occurs to attach user action history
 */
export function getErrorContext(): ErrorContext {
  const sessionId = getPostHogSessionId();

  return {
    sessionId,
    sessionUrl: getPostHogSessionUrl(sessionId),
    distinctId: getPostHogDistinctId(),
    recentActions: actionBuffer.map(formatAction),
    actionDetails: [...actionBuffer], // Return a copy
  };
}

/**
 * Clears the action buffer (useful for testing)
 */
export function clearActions(): void {
  actionBuffer.length = 0;
}

/**
 * Gets the current action count (useful for testing)
 */
export function getActionCount(): number {
  return actionBuffer.length;
}
