import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { PostHogProvider } from "@posthog/react";
import posthog, { type CaptureResult } from "posthog-js";
import "./index.css";
import App from "./App.tsx";
import * as FullStory from "@fullstory/browser";
import { identifyPostHogUser, clearPostHogIdentity } from "./utils/posthog";

// Initialize FullStory
if (import.meta.env.VITE_MERGE_ENV == "PRODUCTION") {
  FullStory.init({ orgId: "YVN3B" });
}

const posthogToken = import.meta.env.VITE_PUBLIC_POSTHOG_PROJECT_TOKEN;
const posthogHost = import.meta.env.VITE_PUBLIC_POSTHOG_HOST;

const AUTOCAPTURE_ALLOWED_PATHS = new Set<string>(["/signup"]);

const PATH_NORMALIZATION_RULES: Array<{ pattern: RegExp; replacement: string }> = [
  { pattern: /\/connectors\/[^/?#]+/g, replacement: "/connectors/:connectorId" },
  {
    pattern: /\/registered-users\/details\/[^/?#]+/g,
    replacement: "/registered-users/details/:id",
  },
];

function normalizeUrl(raw: unknown): unknown {
  if (typeof raw !== "string" || !raw) return raw;
  try {
    const u = new URL(raw);
    u.search = "";
    let path = u.pathname;
    for (const { pattern, replacement } of PATH_NORMALIZATION_RULES) {
      path = path.replace(pattern, replacement);
    }
    u.pathname = path;
    return u.toString();
  } catch {
    return raw;
  }
}

const SECRET_PATTERNS = [
  /sk-[A-Za-z0-9_-]{16,}/,
  /sk_(test|live)_[A-Za-z0-9]{16,}/,
  /ghp_[A-Za-z0-9]{30,}/,
  /Bearer\s+[A-Za-z0-9._-]{20,}/i,
  /eyJ[A-Za-z0-9._-]+/,
];

function looksSensitive(v: unknown): boolean {
  return typeof v === "string" && SECRET_PATTERNS.some((rx) => rx.test(v));
}

const posthogOptions = {
  api_host: posthogHost,
  ui_host: "https://us.posthog.com",
  autocapture: true,
  capture_pageview: true,
  capture_pageleave: true,
  disable_session_recording: true,
  enable_heatmaps: true,
  person_profiles: "identified_only" as const,
  opt_out_capturing_by_default: false,
  defaults: "2026-01-30" as const,
  debug: import.meta.env.DEV,
  before_send: (event: CaptureResult | null): CaptureResult | null => {
    if (!event) return event;

    if (event.properties) {
      for (const key of [
        "$current_url",
        "$referrer",
        "$initial_current_url",
        "$initial_referrer",
      ] as const) {
        if (key in event.properties) {
          event.properties[key] = normalizeUrl(event.properties[key]);
        }
      }
      if (typeof event.properties.$pathname === "string") {
        let p = event.properties.$pathname;
        for (const { pattern, replacement } of PATH_NORMALIZATION_RULES) {
          p = p.replace(pattern, replacement);
        }
        event.properties.$pathname = p;
      }
    }

    if (event.event === "$autocapture" || event.event === "$heatmap") {
      const path = typeof window !== "undefined" ? window.location.pathname : "";
      if (!AUTOCAPTURE_ALLOWED_PATHS.has(path)) return null;
    }

    if (
      event.event === "$autocapture" &&
      event.properties &&
      typeof event.properties.$elements_chain === "string"
    ) {
      const firstSegment = event.properties.$elements_chain.split(";")[0];
      if (firstSegment) {
        const tagMatch = firstSegment.match(/^([a-zA-Z][a-zA-Z0-9-]*)/);
        if (tagMatch) event.properties.element_tag = tagMatch[1];
        const idMatch = firstSegment.match(/(^|[^_])attr_id="([^"]*)"/);
        const nameMatch = firstSegment.match(/attr__name="([^"]*)"/);
        if (idMatch && idMatch[2]) {
          event.properties.field_name = idMatch[2];
        } else if (nameMatch && nameMatch[1]) {
          event.properties.field_name = nameMatch[1];
        }
        const textMatch = firstSegment.match(/_text="([^"]*)"/);
        if (textMatch && textMatch[1]) {
          event.properties.element_text = textMatch[1];
        }
      }
    }

    if (event.properties) {
      for (const k of Object.keys(event.properties)) {
        if (looksSensitive(event.properties[k])) {
          event.properties[k] = "[redacted]";
        }
      }
    }
    return event;
  },
};

const root = createRoot(document.getElementById("root")!);
if (posthogToken) {
  root.render(
    <StrictMode>
      <PostHogProvider apiKey={posthogToken} options={posthogOptions}>
        <App />
      </PostHogProvider>
    </StrictMode>,
  );
} else {
  if (import.meta.env.DEV) {
    console.warn(
      "[PostHog] VITE_PUBLIC_POSTHOG_PROJECT_TOKEN is not set, rendering without PostHog.",
    );
  }
  root.render(
    <StrictMode>
      <App />
    </StrictMode>,
  );
}

if (import.meta.env.DEV) {
  const w = window as unknown as {
    posthog: typeof posthog;
    identifyPostHogUser: typeof identifyPostHogUser;
    clearPostHogIdentity: typeof clearPostHogIdentity;
  };
  w.posthog = posthog;
  w.identifyPostHogUser = identifyPostHogUser;
  w.clearPostHogIdentity = clearPostHogIdentity;
}
