import {
  useCallback,
  useEffect,
  useMemo,
  useState,
  type ReactNode,
} from "react";
import { Link } from "react-router-dom";
import {
  hasAnalyticsConfiguration,
  privacyConfig,
} from "./privacy-config";
import {
  AnalyticsConsentContext,
  type AnalyticsConsentValue,
  type ConsentChoice,
} from "./analytics-consent-context";

const CONSENT_KEY = "plimi.analytics-consent.v1";
const LEGACY_DISABLED_KEY = "umami.disabled";
const SCRIPT_ID = "plimi-umami-script";

function storedChoice(): ConsentChoice {
  try {
    const value = window.localStorage.getItem(CONSENT_KEY);
    if (value === "granted" || value === "denied") return value;

    if (window.localStorage.getItem(LEGACY_DISABLED_KEY) === "1") {
      return "denied";
    }
  } catch {
    // Treat unavailable storage as no consent.
  }

  return "pending";
}

function removeAnalyticsScript() {
  document.getElementById(SCRIPT_ID)?.remove();
}

function loadAnalyticsScript() {
  if (!hasAnalyticsConfiguration || document.getElementById(SCRIPT_ID)) return;

  const script = document.createElement("script");
  script.id = SCRIPT_ID;
  script.defer = true;
  script.src = privacyConfig.analyticsScriptUrl;
  script.dataset.websiteId = privacyConfig.analyticsWebsiteId;
  script.dataset.hostUrl = privacyConfig.analyticsHostUrl;
  script.dataset.domains = new URL(privacyConfig.siteUrl).hostname;
  script.dataset.doNotTrack = "true";
  script.dataset.excludeSearch = "true";
  script.dataset.excludeHash = "true";
  document.head.appendChild(script);
}

function ConsentPanel({
  settings,
  onAccept,
  onReject,
  onClose,
}: {
  settings: boolean;
  onAccept: () => void;
  onReject: () => void;
  onClose?: () => void;
}) {
  return (
    <div
      className={`fixed inset-x-3 z-[80] mx-auto max-w-[680px] rounded-[18px] border border-[var(--p-border)] bg-[var(--p-surface)] p-5 md:inset-x-6 md:p-6 ${
        settings ? "top-1/2 -translate-y-1/2" : "bottom-3 md:bottom-6"
      }`}
      style={{ boxShadow: "0 24px 70px -28px var(--p-shadow-soft)" }}
      role={settings ? "dialog" : "region"}
      aria-modal={settings ? true : undefined}
      aria-label="Analytics preferences"
    >
      <div className="flex items-start justify-between gap-4">
        <div>
          <div className="font-mono text-[10px] uppercase tracking-[0.12em] text-[var(--p-muted)]">
            privacy choice
          </div>
          <h2 className="mb-0 mt-2 font-sans text-xl font-semibold tracking-tight text-[var(--p-text)]">
            Optional, cookieless analytics
          </h2>
        </div>
        {settings && onClose && (
          <button
            onClick={onClose}
            aria-label="Close analytics preferences"
            className="rounded-lg bg-[var(--p-chip)] px-3 py-2 text-sm text-[var(--p-muted)]"
          >
            Close
          </button>
        )}
      </div>

      <p className="mb-0 mt-3 text-sm leading-relaxed text-[var(--p-muted)]">
        With your permission, Plimi loads {privacyConfig.analyticsProvider} from{" "}
        {privacyConfig.analyticsHost} to measure page visits and device/browser
        categories. Tool inputs, files, and outputs are never included.
      </p>

      <div className="mt-5 flex flex-col-reverse gap-2 sm:flex-row sm:items-center">
        <Link
          to="/privacy"
          onClick={onClose}
          className="mr-auto px-1 py-2 text-center text-sm text-[var(--p-muted)] underline decoration-[var(--p-border)] underline-offset-4"
        >
          Read the privacy notice
        </Link>
        <button
          onClick={onReject}
          className="rounded-[10px] border border-[var(--p-border)] bg-[var(--p-chip)] px-4 py-2.5 font-sans text-sm font-semibold text-[var(--p-text)]"
        >
          Reject analytics
        </button>
        <button
          onClick={onAccept}
          className="rounded-[10px] bg-[var(--p-accent)] px-4 py-2.5 font-sans text-sm font-semibold text-[var(--p-accent-ink)]"
        >
          Accept analytics
        </button>
      </div>
    </div>
  );
}

export function AnalyticsConsentProvider({
  children,
}: {
  children: ReactNode;
}) {
  const [choice, setChoice] = useState<ConsentChoice>(storedChoice);
  const [isSettingsOpen, setSettingsOpen] = useState(false);

  useEffect(() => {
    if (choice === "granted") {
      loadAnalyticsScript();
    } else {
      removeAnalyticsScript();
    }
  }, [choice]);

  const saveChoice = useCallback(
    (nextChoice: Exclude<ConsentChoice, "pending">) => {
      const wasGranted = choice === "granted";

      try {
        window.localStorage.setItem(CONSENT_KEY, nextChoice);
        if (nextChoice === "denied") {
          window.localStorage.setItem(LEGACY_DISABLED_KEY, "1");
        } else {
          window.localStorage.removeItem(LEGACY_DISABLED_KEY);
        }
      } catch {
        // The in-memory choice still applies for the current page.
      }

      setChoice(nextChoice);
      setSettingsOpen(false);

      if (wasGranted && nextChoice === "denied") {
        window.location.reload();
      }
    },
    [choice]
  );

  const value = useMemo<AnalyticsConsentValue>(
    () => ({
      choice,
      isSettingsOpen,
      accept: () => saveChoice("granted"),
      reject: () => saveChoice("denied"),
      openSettings: () => setSettingsOpen(true),
      closeSettings: () => setSettingsOpen(false),
    }),
    [choice, isSettingsOpen, saveChoice]
  );

  return (
    <AnalyticsConsentContext.Provider value={value}>
      {children}
      {choice === "pending" && (
        <ConsentPanel
          settings={false}
          onAccept={value.accept}
          onReject={value.reject}
        />
      )}
      {isSettingsOpen && (
        <>
          <button
            aria-label="Close analytics preferences"
            onClick={value.closeSettings}
            className="fixed inset-0 z-[70] bg-[color-mix(in_oklab,var(--p-bg)_70%,transparent)] backdrop-blur-sm"
          />
          <ConsentPanel
            settings
            onAccept={value.accept}
            onReject={value.reject}
            onClose={value.closeSettings}
          />
        </>
      )}
    </AnalyticsConsentContext.Provider>
  );
}
