// Theme helpers, tokens, Tweaks panel, global state

const { useState, useEffect, useRef, useMemo, useCallback, createContext, useContext } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "bgTone": "warm-dark",
  "accent": "orange",
  "density": "roomy",
  "heroVariant": "banner",
  "typography": "editorial"
}/*EDITMODE-END*/;

const ACCENT_MAP = {
  orange: { hue: 32,  label: "Warm orange" },
  amber:  { hue: 55,  label: "Amber" },
  green:  { hue: 145, label: "Phosphor green" },
  cool:   { hue: 220, label: "Cool blue" },
};

const BG_MAP = {
  "pure-black": {
    bg: "#000000",
    panel: "#0a0a0a",
    panel2: "#141414",
    border: "rgba(255,255,255,0.08)",
    borderStrong: "rgba(255,255,255,0.16)",
    text: "#f4f1ec",
    textDim: "rgba(244,241,236,0.62)",
    textMute: "rgba(244,241,236,0.38)",
    grid: "rgba(255,255,255,0.035)",
    scheme: "dark",
  },
  "warm-dark": {
    bg: "#12100e",
    panel: "#1a1713",
    panel2: "#211d17",
    border: "rgba(244,216,180,0.10)",
    borderStrong: "rgba(244,216,180,0.22)",
    text: "#f4ede1",
    textDim: "rgba(244,237,225,0.64)",
    textMute: "rgba(244,237,225,0.40)",
    grid: "rgba(244,216,180,0.04)",
    scheme: "dark",
  },
  "off-white": {
    bg: "#f4efe6",
    panel: "#ede6d8",
    panel2: "#e2dac8",
    border: "rgba(40,32,20,0.14)",
    borderStrong: "rgba(40,32,20,0.26)",
    text: "#1a1510",
    textDim: "rgba(26,21,16,0.66)",
    textMute: "rgba(26,21,16,0.42)",
    grid: "rgba(40,32,20,0.05)",
    scheme: "light",
  },
};

const DENSITY_MAP = {
  packed: { section: 64, gap: 16, pad: 20, hero: 72 },
  roomy:  { section: 112, gap: 24, pad: 28, hero: 120 },
};

const TypeContext = createContext(null);
const ThemeContext = createContext(null);

function buildTheme(state) {
  const bg = BG_MAP[state.bgTone] || BG_MAP["warm-dark"];
  const ac = ACCENT_MAP[state.accent] || ACCENT_MAP.orange;
  const accent      = `oklch(0.74 0.16 ${ac.hue})`;
  const accentSoft  = `oklch(0.74 0.16 ${ac.hue} / 0.18)`;
  const accentHair  = `oklch(0.74 0.16 ${ac.hue} / 0.35)`;
  const accentDeep  = `oklch(0.52 0.14 ${ac.hue})`;
  const accentGlow  = `oklch(0.78 0.18 ${ac.hue} / 0.55)`;
  const density = DENSITY_MAP[state.density] || DENSITY_MAP.roomy;
  return { ...bg, accent, accentSoft, accentHair, accentDeep, accentGlow, hue: ac.hue, density, typography: state.typography, heroVariant: state.heroVariant };
}

function useTweakState() {
  const [state, setState] = useState(() => {
    try {
      const saved = localStorage.getItem("evalyn-tweaks");
      if (saved) return { ...TWEAK_DEFAULTS, ...JSON.parse(saved) };
    } catch {}
    return TWEAK_DEFAULTS;
  });
  useEffect(() => {
    try { localStorage.setItem("evalyn-tweaks", JSON.stringify(state)); } catch {}
  }, [state]);
  const update = useCallback((patch) => {
    setState(prev => {
      const next = { ...prev, ...patch };
      try {
        window.parent.postMessage({ type: '__edit_mode_set_keys', edits: patch }, '*');
      } catch {}
      return next;
    });
  }, []);
  return [state, update];
}

function useEditModeHost(onActivate, onDeactivate) {
  useEffect(() => {
    const handler = (e) => {
      if (!e.data || typeof e.data !== 'object') return;
      if (e.data.type === '__activate_edit_mode') onActivate();
      if (e.data.type === '__deactivate_edit_mode') onDeactivate();
    };
    window.addEventListener('message', handler);
    try { window.parent.postMessage({ type: '__edit_mode_available' }, '*'); } catch {}
    return () => window.removeEventListener('message', handler);
  }, [onActivate, onDeactivate]);
}

// Intersection observer hook for scroll reveals
function useReveal(options = {}) {
  const ref = useRef(null);
  const [visible, setVisible] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { setVisible(true); io.disconnect(); }
    }, { threshold: 0.15, ...options });
    io.observe(ref.current);
    return () => io.disconnect();
  }, []);
  return [ref, visible];
}

// Tiny icons rendered as characters/svg
const Icon = {
  arrow: (p = {}) => (
    <svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" strokeWidth="1.5" {...p}>
      <path d="M3 8h10M9 4l4 4-4 4" strokeLinecap="square"/>
    </svg>
  ),
  dot: (p = {}) => <svg viewBox="0 0 8 8" width="8" height="8" {...p}><circle cx="4" cy="4" r="3" fill="currentColor"/></svg>,
  check: (p = {}) => (
    <svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" strokeWidth="2" {...p}>
      <path d="M3 8l3.5 3.5L13 5" strokeLinecap="square" strokeLinejoin="miter"/>
    </svg>
  ),
  x: (p = {}) => (
    <svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" strokeWidth="1.5" {...p}>
      <path d="M4 4l8 8M12 4l-8 8" strokeLinecap="square"/>
    </svg>
  ),
  github: (p = {}) => (
    <svg viewBox="0 0 16 16" width="14" height="14" fill="currentColor" {...p}>
      <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2 .37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0016 8c0-4.42-3.58-8-8-8z"/>
    </svg>
  ),
};

// Copy-to-clipboard helper
function useCopy() {
  const [copied, setCopied] = useState(false);
  const copy = useCallback((text) => {
    try {
      navigator.clipboard.writeText(text);
      setCopied(true);
      setTimeout(() => setCopied(false), 1400);
    } catch {}
  }, []);
  return [copied, copy];
}

Object.assign(window, {
  TWEAK_DEFAULTS, ACCENT_MAP, BG_MAP, DENSITY_MAP,
  TypeContext, ThemeContext,
  buildTheme, useTweakState, useEditModeHost, useReveal, useCopy,
  Icon,
});
