"use client";

import type { AttributionPayload } from "@/lib/attribution";

const STORAGE_KEY = "solar_attribution";
const SESSION_KEY = "solar_session_id";

function getCookieValue(name: string): string | null {
  if (typeof document === "undefined") return null;
  const match = document.cookie.match(new RegExp(`(?:^|; )${name}=([^;]*)`));
  if (!match) return null;

  try {
    return decodeURIComponent(match[1]);
  } catch {
    return match[1];
  }
}

function mergeAttribution(base: AttributionPayload, incoming: AttributionPayload) {
  return Object.fromEntries(
    Object.entries({
      ...base,
      ...Object.fromEntries(
        Object.entries(incoming).filter(([, value]) => value !== undefined && value !== null && value !== "")
      ),
    }).filter(([, value]) => value !== undefined)
  ) as AttributionPayload;
}

export function getTrackingSessionId(): string {
  if (typeof window === "undefined") return "";

  try {
    let sessionId = sessionStorage.getItem(SESSION_KEY);
    if (!sessionId) {
      sessionId = `solar_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
      sessionStorage.setItem(SESSION_KEY, sessionId);
    }
    return sessionId;
  } catch {
    return `solar_${Date.now()}_anon`;
  }
}

export function getAttribution(): AttributionPayload {
  if (typeof window === "undefined") return {};

  const params = new URLSearchParams(window.location.search);
  const current: AttributionPayload = {
    src: params.get("src") || params.get("source") || undefined,
    campaign: params.get("campaign") || undefined,
    creative: params.get("creative") || undefined,
    variant: params.get("variant") || undefined,
    click_id: params.get("click_id") || undefined,
    slug: params.get("slug") || undefined,
    exp: params.get("exp") || undefined,
    ad_type: params.get("ad_type") || undefined,
    utm_source: params.get("utm_source") || undefined,
    utm_medium: params.get("utm_medium") || undefined,
    utm_campaign: params.get("utm_campaign") || undefined,
    utm_content: params.get("utm_content") || undefined,
    utm_term: params.get("utm_term") || undefined,
    landing_path: window.location.pathname,
    full_path: `${window.location.pathname}${window.location.search}`,
  };

  try {
    const storedRaw = localStorage.getItem(STORAGE_KEY);
    const stored = storedRaw ? JSON.parse(storedRaw) as AttributionPayload : null;
    const cookieAttribution: AttributionPayload = {
      click_id: getCookieValue("solar_click_id") || undefined,
      src: getCookieValue("solar_click_src") || undefined,
      campaign: getCookieValue("solar_click_campaign") || undefined,
      creative: getCookieValue("solar_click_creative") || undefined,
      variant: getCookieValue("solar_click_variant") || undefined,
      slug: getCookieValue("solar_click_slug") || undefined,
      exp: getCookieValue("solar_click_exp") || undefined,
      ad_type: getCookieValue("solar_click_ad_type") || undefined,
    };

    const fallback = mergeAttribution(cookieAttribution, stored || {});
    const hasCurrentAttribution = Object.entries(current).some(([, value]) => value);

    if (hasCurrentAttribution) {
      const merged = mergeAttribution(fallback, current);
      localStorage.setItem(
        STORAGE_KEY,
        JSON.stringify({
          ...merged,
          referrer: stored?.referrer || document.referrer || "",
          first_seen_at: (stored as Record<string, string> | null)?.first_seen_at || new Date().toISOString(),
        })
      );
      return merged;
    }

    if (stored) {
      return stored;
    }

    return fallback;
  } catch {
    return current;
  }
}

export function persistAttribution(): AttributionPayload {
  const attribution = getAttribution();

  if (typeof window !== "undefined") {
    try {
      localStorage.setItem(
        STORAGE_KEY,
        JSON.stringify({
          ...attribution,
          referrer: attribution.referrer || document.referrer || "",
          first_seen_at: new Date().toISOString(),
        })
      );
    } catch {
      // Ignore storage failures.
    }
  }

  return attribution;
}

export function trackTrafficEvent(eventType: string, data?: Record<string, unknown>) {
  if (typeof window === "undefined") return;

  const attribution = persistAttribution();
  const payload = JSON.stringify({
    eventType,
    sessionId: getTrackingSessionId(),
    path: window.location.pathname,
    attribution: {
      ...attribution,
      referrer: attribution.referrer || document.referrer || "",
    },
    data: data || {},
  });

  try {
    if (navigator.sendBeacon) {
      navigator.sendBeacon("/api/traffic/track", new Blob([payload], { type: "application/json" }));
      return;
    }
  } catch {
    // Fall through to fetch.
  }

  fetch("/api/traffic/track", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: payload,
    keepalive: true,
  }).catch(() => {});
}
