"use client";

import Script from "next/script";
import { useEffect, useState } from "react";

const STORE_PATH = "/store/analytics-scripts";

type ScriptPiece =
  | { kind: "src"; id: string; src: string }
  | { kind: "inline"; id: string; code: string };

type ScriptEntry = {
  id?: string;
  src?: string;
  innerHTML?: string;
  inline?: string;
  content?: string;
  body?: string;
};

function isLikelyTrackingId(value: string): boolean {
  const v = value.trim();
  if (!v) return false;
  return /^(G|UA|AW|GT)-[A-Za-z0-9_-]+$/.test(v);
}

function pickStringField(obj: unknown, keys: string[]): string | null {
  if (!obj || typeof obj !== "object") return null;
  const o = obj as Record<string, unknown>;
  for (const k of keys) {
    const v = o[k];
    if (typeof v === "string" && v.trim()) return v.trim();
  }
  return null;
}

function extractScriptsArray(json: unknown): ScriptEntry[] {
  if (!json || typeof json !== "object") return [];
  const o = json as Record<string, unknown>;
  const nested = o.data;
  const fromData =
    nested && typeof nested === "object"
      ? (nested as Record<string, unknown>).scripts
      : undefined;
  const candidates = [o.scripts, o.analytics_scripts, o.analyticsScripts, fromData];
  for (const c of candidates) {
    if (Array.isArray(c) && c.length) return c as ScriptEntry[];
  }
  if (Array.isArray(json)) return json as ScriptEntry[];
  return [];
}

function extractTrackingId(obj: unknown, depth = 0): string | null {
  if (depth > 5 || obj == null) return null;
  if (typeof obj === "string" && isLikelyTrackingId(obj)) return obj.trim();
  if (typeof obj !== "object") return null;
  const o = obj as Record<string, unknown>;
  const directKeys = [
    "measurement_id",
    "measurementId",
    "ga_measurement_id",
    "google_analytics_id",
    "gtag_id",
    "trackingId",
    "tracking_id",
  ];
  for (const k of directKeys) {
    const v = o[k];
    if (typeof v === "string" && isLikelyTrackingId(v)) return v.trim();
  }
  for (const v of Object.values(o)) {
    const found = extractTrackingId(v, depth + 1);
    if (found) return found;
  }
  return null;
}

function entriesToPieces(scripts: ScriptEntry[]): ScriptPiece[] {
  const pieces: ScriptPiece[] = [];
  scripts.forEach((s, i) => {
    const baseId =
      typeof s.id === "string" && s.id.trim() ? s.id.trim() : `analytics-api-${i}`;
    if (typeof s.src === "string" && s.src.trim()) {
      pieces.push({ kind: "src", id: `${baseId}-ext`, src: s.src.trim() });
    }
    const code =
      typeof s.innerHTML === "string"
        ? s.innerHTML
        : typeof s.inline === "string"
          ? s.inline
          : typeof s.content === "string"
            ? s.content
            : typeof s.body === "string"
              ? s.body
              : "";
    if (code.trim()) {
      pieces.push({ kind: "inline", id: `${baseId}-inline`, code: code.trim() });
    }
  });
  return pieces;
}

function gaPieces(measurementId: string): ScriptPiece[] {
  const safe = measurementId.trim().replace(/[^A-Za-z0-9_-]/g, "");
  if (!safe) return [];
  const q = encodeURIComponent(safe);
  return [
    {
      kind: "src",
      id: `ga-gtag-js-${safe}`,
      src: `https://www.googletagmanager.com/gtag/js?id=${q}`,
    },
    {
      kind: "inline",
      id: `ga-gtag-config-${safe}`,
      code: `window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag('js',new Date());gtag('config','${safe}',{send_page_view:true});`,
    },
  ];
}

function injectHtmlFragment(html: string, target: "head" | "body-start" | "body-end") {
  if (typeof document === "undefined") return;
  const tpl = document.createElement("template");
  tpl.innerHTML = html.trim();

  const nodes: Node[] = [];
  while (tpl.content.firstChild) {
    const node = tpl.content.firstChild;
    tpl.content.removeChild(node);
    if (node.nodeType === Node.ELEMENT_NODE && node.nodeName === "SCRIPT") {
      const old = node as HTMLScriptElement;
      const s = document.createElement("script");
      for (const attr of Array.from(old.attributes)) {
        s.setAttribute(attr.name, attr.value);
      }
      if (old.src) s.src = old.src;
      if (old.textContent) s.textContent = old.textContent;
      nodes.push(s);
    } else {
      nodes.push(node);
    }
  }

  if (target === "head") {
    nodes.forEach((n) => document.head.appendChild(n));
    return;
  }
  if (!document.body) return;
  if (target === "body-end") {
    nodes.forEach((n) => document.body.appendChild(n));
    return;
  }
  const anchor = document.body.firstChild;
  if (!anchor) {
    nodes.forEach((n) => document.body.appendChild(n));
    return;
  }
  nodes.forEach((n) => document.body.insertBefore(n, anchor));
}

export default function AnalyticsScriptsLoader() {
  const [pieces, setPieces] = useState<ScriptPiece[]>([]);

  useEffect(() => {
    let cancelled = false;
    const ac = new AbortController();

    const run = async () => {
      const base = process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL?.replace(/\/$/, "");
      const key = process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_API_KEY?.trim();
      if (!base || !key) return;

      try {
        const res = await fetch(`${base}${STORE_PATH}`, {
          method: "GET",
          headers: { "x-publishable-api-key": key },
          cache: "no-store",
          signal: ac.signal,
        });
        if (!res.ok || cancelled) return;

        const ct = (res.headers.get("content-type") || "").toLowerCase();
        const text = await res.text();
        if (cancelled) return;

        if (ct.includes("application/json")) {
          let json: unknown;
          try {
            json = JSON.parse(text);
          } catch {
            return;
          }

          if (json && typeof json === "object") {
            const o = json as Record<string, unknown>;
            const header =
              typeof o.header_scripts === "string" ? o.header_scripts.trim() : "";
            const body =
              typeof o.body_scripts === "string" ? o.body_scripts.trim() : "";
            const footer =
              typeof o.footer_scripts === "string" ? o.footer_scripts.trim() : "";
            if (header || body || footer) {
              if (header) injectHtmlFragment(header, "head");
              if (body) injectHtmlFragment(body, "body-start");
              if (footer) injectHtmlFragment(footer, "body-end");
              return;
            }
          }

          const htmlSnippet = pickStringField(json, [
            "html",
            "head_html",
            "head_snippet",
            "snippet",
            "scripts_html",
          ]);
          if (htmlSnippet && htmlSnippet.includes("<script")) {
            injectHtmlFragment(htmlSnippet, "head");
            return;
          }

          const list = extractScriptsArray(json);
          if (list.length) {
            setPieces(entriesToPieces(list));
            return;
          }

          const gaId = extractTrackingId(json);
          if (gaId) {
            setPieces(gaPieces(gaId));
          }
          return;
        }

        if (text.includes("<script")) {
          injectHtmlFragment(text, "head");
        }
      } catch {
      }
    };

    void run();
    return () => {
      cancelled = true;
      ac.abort();
    };
  }, []);

  if (!pieces.length) return null;

  return (
    <>
      {pieces.map((p) =>
        p.kind === "src" ? (
          <Script key={p.id} id={p.id} src={p.src} strategy="afterInteractive" />
        ) : (
          <Script key={p.id} id={p.id} strategy="afterInteractive">
            {p.code}
          </Script>
        ),
      )}
    </>
  );
}
