/**
 * Detects whether the meSEO snippet (t.js) is installed on a customer website.
 * Returns detection result with confidence level and any diagnostics.
 *
 * Does NOT throw on fetch failures — returns { detected: false, reason } instead.
 *
 * The meSEO snippet is an inline IIFE (not a bare <script src>), so detection
 * targets the config object and script URL it injects:
 *   w.meSEOConfig={siteId:"ms_...",appUrl:"..."}
 *   j.src="https://app.meseoapp.com/t.js?v=2"
 */

export interface SnippetDetectionResult {
  detected: boolean;
  installationMethod: "direct" | "gtm" | "none";
  reason?: string;
  fetchedUrl: string;
  httpStatus?: number;
  httpDuration?: number;
}

const FETCH_TIMEOUT_MS = 10_000;
const USER_AGENT = "meSEO-SnippetDetector/1.0 (+https://meseoapp.com/bot)";

const DIRECT_PATTERNS = [
  /meSEOConfig\s*=\s*\{/,            // config object set in the snippet IIFE
  /meseoapp\.com\/t\.js/,             // script src URL injected by the IIFE
  /<!--\s*meSEO\s*Site\s*Tag\s*-->/, // HTML comment wrapper around the snippet
];

const GTM_INDICATORS = [
  /<script[^>]*src=["']https?:\/\/www\.googletagmanager\.com\/gtm\.js/i,
  /GTM-[A-Z0-9]+/,
];

export async function detectSnippet(domain: string): Promise<SnippetDetectionResult> {
  let url: string;
  try {
    const normalized = domain.startsWith("http") ? domain : `https://${domain}`;
    url = new URL(normalized).toString();
  } catch {
    return {
      detected: false,
      installationMethod: "none",
      reason: "Invalid domain",
      fetchedUrl: domain,
    };
  }

  const startedAt = Date.now();
  let httpStatus: number | undefined;
  let html: string;

  try {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);

    const response = await fetch(url, {
      method: "GET",
      headers: { "User-Agent": USER_AGENT, "Accept": "text/html" },
      signal: controller.signal,
      redirect: "follow",
    });
    clearTimeout(timeoutId);

    httpStatus = response.status;

    if (!response.ok) {
      return {
        detected: false,
        installationMethod: "none",
        reason: `HTTP ${response.status}`,
        fetchedUrl: url,
        httpStatus,
        httpDuration: Date.now() - startedAt,
      };
    }

    html = await response.text();
  } catch (err) {
    const reason =
      err instanceof Error && err.name === "AbortError"
        ? "Timeout (10s)"
        : err instanceof Error
          ? err.message
          : "Fetch failed";
    return {
      detected: false,
      installationMethod: "none",
      reason,
      fetchedUrl: url,
      httpStatus,
      httpDuration: Date.now() - startedAt,
    };
  }

  for (const pattern of DIRECT_PATTERNS) {
    if (pattern.test(html)) {
      return {
        detected: true,
        installationMethod: "direct",
        fetchedUrl: url,
        httpStatus,
        httpDuration: Date.now() - startedAt,
      };
    }
  }

  const hasGtm = GTM_INDICATORS.some((pattern) => pattern.test(html));
  if (hasGtm) {
    return {
      detected: false,
      installationMethod: "gtm",
      reason: "GTM container detected — meSEO tag may be inside GTM (not visible from HTML)",
      fetchedUrl: url,
      httpStatus,
      httpDuration: Date.now() - startedAt,
    };
  }

  return {
    detected: false,
    installationMethod: "none",
    reason: "No meSEO snippet or GTM container found in HTML",
    fetchedUrl: url,
    httpStatus,
    httpDuration: Date.now() - startedAt,
  };
}
