import { Partytown } from "@qwik.dev/partytown/react";
import * as React from "react";
import { useLocation } from "react-router";
import { useRouteContext } from "../../contexts/RouteContext";

// type dataLayer
declare global {
  interface Window {
    dataLayer: {
      push(...args: any[]): void;
    };
  }
}

function resolveUrl(
  url: URL,
  location: Location,
  type: "script" | "style" | "iframe" | "fetch" | "image" | "xhr",
) {
  if (type !== "script") {
    return url;
  }
  const bypassDomains = [
    "www.google-analytics.com",
    "www.googletagmanager.com",
    "cdn.mxpnl.com",
    "unpkg.com",
    "cdnjs.cloudflare.com",
    "esm.sh",
    "cors-proxy.devize.com",
  ];
  if (bypassDomains.includes(url.hostname)) {
    return url;
  }
  const proxyUrl = new URL("https://cors-proxy.devize.com/");
  proxyUrl.searchParams.append("url", url.toString());
  return proxyUrl;
}

export const AnalyticsHead = () => {
  const {
    settings: { analytics: settings },
  } = useRouteContext();
  const hasGTM = settings?.gtm?.enabled;
  const hasGA = settings?.ga?.enabled;
  const hasMP = settings?.mp?.enabled;
  const hasPH = settings?.ph?.enabled;
  const partyTownEnabled = hasGTM || hasGA || hasMP;
  const forward: string[] = [];
  if (hasGTM || hasGA) {
    forward.push("dataLayer.push");
  }
  if (hasMP) {
    forward.push(
      "mixpanel.identify",
      "mixpanel.people.set",
      "mixpanel.track",
      "mixpanel.reset",
      "mixpanel.alias",
    );
  }

  return (
    <>
      {partyTownEnabled ? (
        <Partytown forward={forward} resolveUrl={resolveUrl} />
      ) : null}
      {hasGTM ? <GoogleTagManager containerId={settings.gtm.cId} /> : null}
      {hasGA ? <GoogleAnalytics measurementId={settings.ga.mId} /> : null}
      {hasMP ? <Mixpanel token={settings.mp.token} /> : null}
      {hasPH ? (
        <PostHog apikey={settings.ph.key} host={settings.ph.host} />
      ) : null}
    </>
  );
};

export const AnalyticsBody = () => {
  const {
    settings: { analytics: settings },
  } = useRouteContext();
  const mId = settings?.ga?.mId;
  const location = useLocation();
  React.useEffect(() => {
    window.dataLayer?.push(["config", mId, { page_path: location.pathname }]);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [location]);
  const hasGTM = settings?.gtm?.enabled;
  return hasGTM ? (
    <GoogleTagManagerNoScript containerId={settings.gtm.cId} />
  ) : null;
};

const GoogleTagManager = ({ containerId }) => {
  return containerId ? (
    <script
      type="text/partytown"
      dangerouslySetInnerHTML={{
        __html: `
          (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
          new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
          j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
          'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
          })(window,document,'script','dataLayer','${containerId}');
      `,
      }}
    />
  ) : null;
};

const GoogleTagManagerNoScript = ({ containerId }) => {
  return containerId ? (
    <noscript>
      <iframe
        src={`https://www.googletagmanager.com/ns.html?id=${containerId}`}
        height="0"
        width="0"
        style={{ display: "none", visibility: "hidden" }}
      />
    </noscript>
  ) : null;
};

const GoogleAnalytics = ({ measurementId }) => {
  return measurementId ? (
    <>
      <script
        async
        src={`https://www.googletagmanager.com/gtag/js?id=${measurementId}`}
        type="text/partytown"
      />
      <script
        dangerouslySetInnerHTML={{
          __html: `
            window.dataLayer = window.dataLayer || [];
            function gtag(){dataLayer.push(arguments);}
            gtag('js', new Date());
            gtag('config', '${measurementId}', {});
          `,
        }}
      ></script>
    </>
  ) : null;
};

const Mixpanel = ({ token }) => {
  return token ? (
    <script
      type="text/partytown"
      dangerouslySetInnerHTML={{
        __html: `
          (function(f,b){if(!b.__SV){var e,g,i,h;window.mixpanel=b;b._i=[];b.init=function(e,f,c){function g(a,d){var b=d.split(".");2==b.length&&(a=a[b[0]],d=b[1]);a[d]=function(){a.push([d].concat(Array.prototype.slice.call(arguments,0)))}}var a=b;"undefined"!==typeof c?a=b[c]=[]:c="mixpanel";a.people=a.people||[];a.toString=function(a){var d="mixpanel";"mixpanel"!==c&&(d+="."+c);a||(d+=" (stub)");return d};a.people.toString=function(){return a.toString(1)+".people (stub)"};i="disable time_event track track_pageview track_links track_forms track_with_groups add_group set_group remove_group register register_once alias unregister identify name_tag set_config reset opt_in_tracking opt_out_tracking has_opted_in_tracking has_opted_out_tracking clear_opt_in_out_tracking start_batch_senders people.set people.set_once people.unset people.increment people.append people.union people.track_charge people.clear_charges people.delete_user people.remove".split(" ");
          for(h=0;h<i.length;h++)g(a,i[h]);var j="set set_once union unset remove delete".split(" ");a.get_group=function(){function b(c){d[c]=function(){call2_args=arguments;call2=[c].concat(Array.prototype.slice.call(call2_args,0));a.push([e,call2])}}for(var d={},e=["get_group"].concat(Array.prototype.slice.call(arguments,0)),c=0;c<j.length;c++)b(j[c]);return d};b._i.push([e,f,c])};b.__SV=1.2;e=f.createElement("script");e.type="text/javascript";e.async=!0;e.src="undefined"!==typeof MIXPANEL_CUSTOM_LIB_URL?
          MIXPANEL_CUSTOM_LIB_URL:"file:"===f.location.protocol&&"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js".match(/^\\/\\//)?"https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js":"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js";g=f.getElementsByTagName("script")[0];g.parentNode.insertBefore(e,g)}})(document,window.mixpanel||[]);
          mixpanel.init('${token}', { batch_requests: true });
      `,
      }}
    />
  ) : null;
};

const PostHog = ({
  apikey,
  host = "https://us.i.posthog.com",
}: {
  apikey: string;
  host: string;
}) => {
  return apikey ? (
    <script
      type="text/javascript"
      dangerouslySetInnerHTML={{
        __html: `
          !function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="init capture register register_once register_for_session unregister unregister_for_session getFeatureFlag getFeatureFlagPayload isFeatureEnabled reloadFeatureFlags updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures on onFeatureFlags onSessionId getSurveys getActiveMatchingSurveys renderSurvey canRenderSurvey getNextSurveyStep identify setPersonProperties group resetGroups setPersonPropertiesForFlags resetPersonPropertiesForFlags setGroupPropertiesForFlags resetGroupPropertiesForFlags reset get_distinct_id getGroups get_session_id get_session_replay_url alias set_config startSessionRecording stopSessionRecording sessionRecordingStarted captureException loadToolbar get_property getSessionProperty createPersonProfile opt_in_capturing opt_out_capturing has_opted_in_capturing has_opted_out_capturing clear_opt_in_out_capturing debug".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
          posthog.init('${apikey}', {api_host: '${host}', person_profiles: 'identified_only'});
        `,
      }}
    />
  ) : null;
};
