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

const THEMES = {
  architektur: {
    key: 'architektur', name: 'Architektur', isDark: false,
    heading: "'Cormorant Garamond', Georgia, serif",
    body: "'Plus Jakarta Sans', system-ui, sans-serif",
    bg: '#FAFAF7', bgAlt: '#F0EDE6', bgInverse: '#26241F',
    text: '#1A1A18', textInverse: '#F0EBE0', textMuted: '#84817A',
    accent: '#C49A6C', accentHover: '#A8804F',
    secondary: '#84817A', border: '#E0DCD4',
    radius: '2px',
    cardBg: '#FFFFFF',
    shadow: '0 1px 3px rgba(0,0,0,0.04)',
    shadowLg: '0 12px 40px rgba(0,0,0,0.07)',
    heroOverlay: 'linear-gradient(to bottom, rgba(26,26,24,0.05) 0%, rgba(26,26,24,0.55) 100%)',
    heroBg: 'linear-gradient(160deg, #C5C0B6 0%, #AEA89E 50%, #989288 100%)',
  },
  prestige: {
    key: 'prestige', name: 'Prestige', isDark: true,
    heading: "'Cormorant Garamond', Georgia, serif",
    body: "'Plus Jakarta Sans', system-ui, sans-serif",
    bg: '#0E140F', bgAlt: '#161E17', bgInverse: '#0A0F0B',
    text: '#EDE8DC', textInverse: '#1A1A18', textMuted: '#8A877A',
    accent: '#C4A265', accentHover: '#D4B275',
    secondary: '#6B7E60', border: '#263028',
    radius: '2px',
    cardBg: '#161E17',
    shadow: '0 1px 4px rgba(0,0,0,0.25)',
    shadowLg: '0 12px 40px rgba(0,0,0,0.4)',
    heroOverlay: 'linear-gradient(to bottom, rgba(10,14,10,0.15) 0%, rgba(10,14,10,0.65) 100%)',
    heroBg: 'linear-gradient(160deg, #2A3628 0%, #1A2618 50%, #0F1A14 100%)',
  },
  natur: {
    key: 'natur', name: 'Natur', isDark: false,
    heading: "'Cormorant Garamond', Georgia, serif",
    body: "'Plus Jakarta Sans', system-ui, sans-serif",
    bg: '#F5F1EA', bgAlt: '#EAE4D9', bgInverse: '#342C24',
    text: '#2D2520', textInverse: '#F0EBE0', textMuted: '#887E74',
    accent: '#B8704A', accentHover: '#9C5D3C',
    secondary: '#7D8E6F', border: '#DDD5C8',
    radius: '8px',
    cardBg: '#FFFFFF',
    shadow: '0 2px 8px rgba(0,0,0,0.05)',
    shadowLg: '0 12px 40px rgba(0,0,0,0.09)',
    heroOverlay: 'linear-gradient(to bottom, rgba(45,37,32,0.05) 0%, rgba(45,37,32,0.5) 100%)',
    heroBg: 'linear-gradient(160deg, #D4C8B8 0%, #BFB0A0 50%, #A89888 100%)',
  }
};

const ThemeContext = createContext(THEMES.prestige);
function useTheme() { return useContext(ThemeContext); }

function useInView(opts = {}) {
  const ref = useRef(null);
  const [vis, setVis] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    const ob = new IntersectionObserver(
      ([e]) => { if (e.isIntersecting) { setVis(true); ob.disconnect(); } },
      { threshold: opts.threshold || 0.12, rootMargin: opts.rootMargin || '0px' }
    );
    ob.observe(ref.current);
    return () => ob.disconnect();
  }, []);
  return [ref, vis];
}

function useScrollY() {
  const [y, setY] = useState(0);
  useEffect(() => {
    let rafId = null;
    const h = () => {
      if (rafId) return;
      rafId = requestAnimationFrame(() => {
        setY(window.scrollY);
        rafId = null;
      });
    };
    window.addEventListener('scroll', h, { passive: true });
    h();
    return () => {
      window.removeEventListener('scroll', h);
      if (rafId) cancelAnimationFrame(rafId);
    };
  }, []);
  return y;
}

function useMobile(bp = 768) {
  const [m, setM] = useState(false);
  useEffect(() => {
    const mq = window.matchMedia(`(max-width: ${bp}px)`);
    setM(mq.matches);
    const h = e => setM(e.matches);
    mq.addEventListener('change', h);
    return () => mq.removeEventListener('change', h);
  }, [bp]);
  return m;
}

function hashGroup(h) {
  if (h.startsWith('projekt')) return 'projekt';
  if (h.startsWith('wohnung-')) return 'wohnung';
  return h || 'home';
}

function useHash() {
  const [hash, setHash] = useState(window.location.hash.replace('#', '') || 'home');
  useEffect(() => {
    let prev = window.location.hash.replace('#', '') || 'home';
    const h = () => {
      const next = window.location.hash.replace('#', '') || 'home';
      const sameGroup = hashGroup(prev) === hashGroup(next);
      setHash(next);
      if (!sameGroup) {
        window.scrollTo({ top: 0, behavior: 'instant' });
      }
      prev = next;
    };
    window.addEventListener('hashchange', h);
    return () => window.removeEventListener('hashchange', h);
  }, []);
  return hash;
}

function FadeIn({ children, delay = 0, direction = 'up', style = {} }) {
  const [ref, vis] = useInView();
  const tr = { up: 'translateY(32px)', down: 'translateY(-32px)', left: 'translateX(32px)', right: 'translateX(-32px)', none: 'none' };
  return (
    <div ref={ref} style={{
      ...style, opacity: vis ? 1 : 0,
      transform: vis ? 'translateY(0) translateX(0)' : tr[direction],
      transition: `opacity 0.85s cubic-bezier(0.16,1,0.3,1) ${delay}s, transform 0.85s cubic-bezier(0.16,1,0.3,1) ${delay}s`,
    }}>{children}</div>
  );
}

function RevealText({ children, delay = 0, dur = 1.1, style = {} }) {
  const [ref, vis] = useInView({ threshold: 0.2 });
  return (
    <div ref={ref} style={{ overflow: 'hidden', display: 'block', ...style }}>
      <div style={{
        transform: vis ? 'translate3d(0,0,0)' : 'translate3d(0, 110%, 0)',
        opacity: vis ? 1 : 0,
        transition: `transform ${dur}s cubic-bezier(0.16,1,0.3,1) ${delay}s, opacity ${dur}s ease ${delay}s`,
        willChange: 'transform, opacity',
      }}>
        {children}
      </div>
    </div>
  );
}

function useParallax(strength = 30) {
  const ref = useRef(null);
  const scrollY = useScrollY();
  let y = 0;
  if (typeof window !== 'undefined' && ref.current) {
    const rect = ref.current.getBoundingClientRect();
    const dist = (rect.top + rect.height / 2 - window.innerHeight / 2) / window.innerHeight;
    y = dist * -strength;
  }
  return [ref, y];
}

function AnimCounter({ value, suffix = '', dur = 1800 }) {
  const [ref, vis] = useInView();
  const [disp, setDisp] = useState(0);
  useEffect(() => {
    if (!vis) return;
    const s = performance.now(); const n = parseFloat(value);
    const tick = (now) => {
      const p = Math.min((now - s) / dur, 1);
      setDisp(n * (1 - Math.pow(1 - p, 3)));
      if (p < 1) requestAnimationFrame(tick);
    };
    requestAnimationFrame(tick);
  }, [vis]);
  const hasDot = String(value).includes('.');
  return <span ref={ref}>{hasDot ? disp.toFixed(1) : Math.round(disp)}{suffix}</span>;
}

function Placeholder({ label, ratio = '16/9', style = {} }) {
  const t = useTheme();
  return (
    <div style={{
      aspectRatio: ratio, position: 'relative',
      background: `repeating-linear-gradient(-55deg, ${t.border}30, ${t.border}30 1px, transparent 1px, transparent 16px)`,
      backgroundColor: t.bgAlt,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      borderRadius: t.radius, overflow: 'hidden', ...style,
    }}>
      <span style={{
        fontFamily: 'ui-monospace, monospace', fontSize: '0.65rem',
        letterSpacing: '0.14em', color: t.textMuted,
        textTransform: 'uppercase', padding: '5px 12px',
        background: `${t.bg}cc`, borderRadius: '2px',
      }}>{label}</span>
    </div>
  );
}

function Logo({ compact, light }) {
  const t = useTheme();
  const col = light ? '#fff' : t.text;
  const sc = compact ? 0.82 : 1;
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: `${3*sc}px`, cursor: 'pointer' }}>
      <span style={{
        fontFamily: t.heading, fontWeight: 500, fontSize: `${1.1*sc}rem`,
        letterSpacing: '0.04em', color: col, lineHeight: 1,
      }}>Eigenmatt</span>
      <span style={{
        fontFamily: t.body, fontWeight: 600, fontSize: `${0.6*sc}rem`,
        letterSpacing: '0.28em', color: t.accent, lineHeight: 1, textTransform: 'uppercase',
      }}>Kaisten</span>
    </div>
  );
}

function Btn({ children, variant = 'primary', style = {}, ...props }) {
  const t = useTheme();
  const [hov, setHov] = useState(false);
  const base = {
    fontFamily: t.body, fontWeight: 600, fontSize: '0.72rem',
    letterSpacing: '0.13em', textTransform: 'uppercase',
    padding: '14px 34px', border: 'none', cursor: 'pointer',
    borderRadius: t.radius, transition: 'all 0.3s ease',
    display: 'inline-flex', alignItems: 'center', gap: '8px',
  };
  const v = {
    primary: { ...base, background: hov ? t.accentHover : t.accent, color: '#fff' },
    outline: { ...base, background: 'transparent', color: hov ? t.accent : t.text, border: `1.5px solid ${hov ? t.accent : t.border}` },
    light: { ...base, background: hov ? 'rgba(255,255,255,0.2)' : 'transparent', color: '#fff', border: '1.5px solid rgba(255,255,255,0.35)' },
  };
  return (
    <button {...props} onMouseEnter={() => setHov(true)} onMouseLeave={() => setHov(false)}
      style={{ ...v[variant], ...style }}>{children}</button>
  );
}

const lbl = (t) => ({ fontFamily: t.body, fontWeight: 600, fontSize: '0.62rem', letterSpacing: '0.22em', textTransform: 'uppercase', color: t.accent, marginBottom: '14px' });
const hdg = (t, extra) => ({ fontFamily: t.heading, fontWeight: 400, fontSize: 'clamp(2rem, 3.5vw, 2.8rem)', color: t.text, lineHeight: 1.15, ...extra });
const bdy = (t) => ({ fontFamily: t.body, fontWeight: 300, fontSize: '0.95rem', color: t.textMuted, lineHeight: 1.8 });
const sec = (t, extra) => ({ padding: 'clamp(64px, 10vw, 120px) clamp(20px, 5vw, 48px)', background: t.bg, ...extra });
const subhdg = (t, extra) => ({ fontFamily: t.heading, fontWeight: 500, fontSize: 'clamp(1.3rem, 2vw, 1.65rem)', color: t.text, lineHeight: 1.3, marginBottom: '14px', marginTop: '36px', ...extra });
const para = (t, extra) => ({ fontFamily: t.body, fontWeight: 300, fontSize: '1rem', color: t.text, lineHeight: 1.85, marginBottom: '18px', ...extra });

function PageHero({ title, eyebrow, subtitle, compact }) {
  const t = useTheme();
  return (
    <section style={{
      paddingTop: compact ? 'clamp(110px, 13vh, 150px)' : 'clamp(140px, 18vh, 200px)',
      paddingBottom: compact ? 'clamp(20px, 3vw, 36px)' : 'clamp(40px, 6vw, 72px)',
      paddingLeft: 'clamp(20px, 5vw, 48px)', paddingRight: 'clamp(20px, 5vw, 48px)',
      background: t.bgAlt, borderBottom: `1px solid ${t.border}`,
    }}>
      <div style={{ maxWidth: '1160px', margin: '0 auto' }}>
        <FadeIn>
          {eyebrow && <div style={lbl(t)}>{eyebrow}</div>}
          <h1 style={{
            fontFamily: t.heading, fontWeight: 400,
            fontSize: 'clamp(2.4rem, 5vw, 3.8rem)',
            color: t.text, lineHeight: 1.1, marginBottom: subtitle ? '16px' : 0,
          }}>{title}</h1>
          {subtitle && (
            <p style={{
              fontFamily: t.heading, fontStyle: 'italic', fontWeight: 300,
              fontSize: 'clamp(1.1rem, 1.6vw, 1.4rem)',
              color: t.textMuted, lineHeight: 1.4, maxWidth: '680px',
            }}>{subtitle}</p>
          )}
        </FadeIn>
      </div>
    </section>
  );
}

function ContentSection({ children, narrow, alt, style = {} }) {
  const t = useTheme();
  return (
    <section style={{
      padding: 'clamp(60px, 8vw, 100px) clamp(20px, 5vw, 48px)',
      background: alt ? t.bgAlt : t.bg, ...style,
    }}>
      <div style={{ maxWidth: narrow ? '760px' : '1160px', margin: '0 auto' }}>
        {children}
      </div>
    </section>
  );
}

Object.assign(window, {
  THEMES, ThemeContext, useTheme, useInView, useScrollY, useMobile, useHash, useParallax,
  hashGroup,
  FadeIn, RevealText, AnimCounter, Placeholder, Logo, Btn, PageHero, ContentSection,
  lbl, hdg, bdy, sec, subhdg, para,
});
