// home.jsx — Portfolio hub

const THEMES = {
  dark: {
    bg:    '#000000',
    fg:    '#FFFFFF',
    muted: 'rgba(255,255,255,0.48)',
    dim:   'rgba(255,255,255,0.24)',
    rule:  'rgba(255,255,255,0.10)',
    toggleBg:   'rgba(255,255,255,0.12)',
    toggleFg:   '#FFFFFF',
    toggleHover:'rgba(255,255,255,0.20)',
    hoverBg:    'rgba(255,255,255,0.04)',
  },
  light: {
    bg:    '#F0EEE9',
    fg:    '#0A0A0A',
    muted: 'rgba(0,0,0,0.48)',
    dim:   'rgba(0,0,0,0.28)',
    rule:  'rgba(0,0,0,0.10)',
    toggleBg:   '#1A1A1A',
    toggleFg:   '#FFFFFF',
    toggleHover:'#333333',
    hoverBg:    'rgba(0,0,0,0.04)',
  },
};

const HOME_SANS = "'Inter Tight', system-ui, sans-serif";
const HOME_MONO = "'Space Mono', ui-monospace, monospace";

// ── i18n ──────────────────────────────────────────────────────────────────────

const I18N_CACHE = {};

function useHubStrings(lang) {
  const [strings, setStrings] = React.useState(I18N_CACHE[lang] || null);

  React.useEffect(() => {
    if (I18N_CACHE[lang]) { setStrings(I18N_CACHE[lang]); return; }
    fetch(`/home/i18n/${lang}.json`)
      .then(r => r.json())
      .then(d => { I18N_CACHE[lang] = d; setStrings(d); })
      .catch(() => {
        fetch('/home/i18n/en.json').then(r => r.json()).then(d => setStrings(d));
      });
  }, [lang]);

  return strings;
}

const ThemeCtx   = React.createContext({ theme: THEMES.dark, mode: 'dark', toggle: () => {} });
const StringsCtx = React.createContext(null);

function useThemePref() {
  const stored = localStorage.getItem('hub-theme');
  const [mode, setMode] = React.useState(
    stored === 'light' || stored === 'dark' ? stored : 'dark'
  );
  const toggle = () => {
    const next = mode === 'dark' ? 'light' : 'dark';
    localStorage.setItem('hub-theme', next);
    setMode(next);
  };
  return { mode, theme: THEMES[mode], toggle };
}

const LOCALES = [
  { code: 'en', label: 'EN' },
  { code: 'pt', label: 'PT' },
  { code: 'es', label: 'ES' },
];

function useLangPref() {
  const fromUrl = new URLSearchParams(window.location.search).get('lang');
  const [lang, setLangState] = React.useState(
    fromUrl || localStorage.getItem('hub-lang') || 'en'
  );
  const setLang = (l) => {
    localStorage.setItem('hub-lang', l);
    const url = new URL(window.location.href);
    url.searchParams.set('lang', l);
    window.history.replaceState({}, '', url.toString());
    setLangState(l);
  };
  return [lang, setLang];
}

const CASES = [
  {
    id: 'picpay',
    company: 'PicPay',
    projectName: 'Impact System',
    role: 'Head of Design Foundation',
    year: '2023–2024',
    status: 'live',
    thumb: '/assets/img/picpay-featured.png',
    video: '/assets/video/picpay-wallet.mp4',
  },
  {
    id: 'btg',
    company: 'BTG Pactual',
    projectName: 'Product Design',
    role: 'Senior Product Designer',
    year: '2022–2023',
    status: 'coming-soon',
    thumb: null,
  },
  {
    id: 'nubank',
    company: 'Nubank',
    projectName: 'Design System',
    role: 'Product Designer',
    year: '2021–2022',
    status: 'coming-soon',
    thumb: null,
  },
];

function useInView(ref) {
  const [visible, setVisible] = React.useState(false);
  React.useEffect(() => {
    if (!ref.current) return;
    const obs = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { setVisible(true); obs.disconnect(); }
    }, { threshold: 0.12 });
    obs.observe(ref.current);
    return () => obs.disconnect();
  }, []);
  return visible;
}

// ── Icons ─────────────────────────────────────────────────────────────────────

function IconMoon({ color = 'currentColor', size = 18 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
      xmlns="http://www.w3.org/2000/svg" style={{ display: 'block' }}>
      <path
        d="M21 12.79A9 9 0 1 1 11.21 3a7 7 0 0 0 9.79 9.79Z"
        stroke={color} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"
      />
    </svg>
  );
}

function IconSun({ color = 'currentColor', size = 18 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
      xmlns="http://www.w3.org/2000/svg" style={{ display: 'block' }}>
      <circle cx="12" cy="12" r="4" stroke={color} strokeWidth="1.5"/>
      <path d="M12 2v2M12 20v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M2 12h2M20 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"
        stroke={color} strokeWidth="1.5" strokeLinecap="round"/>
    </svg>
  );
}

// ── ThemeToggle ───────────────────────────────────────────────────────────────

function ThemeToggle() {
  const { mode, theme, toggle } = React.useContext(ThemeCtx);
  const [hovered, setHovered] = React.useState(false);
  const isDark = mode === 'dark';

  return (
    <button
      onClick={toggle}
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}
      aria-label={isDark ? 'Switch to light mode' : 'Switch to dark mode'}
      style={{
        width: 44, height: 44, borderRadius: '50%',
        border: 'none',
        background: hovered ? theme.toggleHover : theme.toggleBg,
        cursor: 'pointer',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        transition: 'background 200ms ease, transform 200ms ease',
        transform: hovered ? 'scale(1.08)' : 'scale(1)',
        flexShrink: 0,
      }}
    >
      <span style={{
        display: 'block',
        opacity: 1,
        transition: 'opacity 180ms ease, transform 180ms ease',
        transform: 'rotate(0deg)',
      }}>
        {isDark
          ? <IconMoon color={theme.toggleFg} size={18} />
          : <IconSun color={theme.toggleFg} size={18} />
        }
      </span>
    </button>
  );
}

// ── ViewCaseBtn ───────────────────────────────────────────────────────────────

const CASE_BTN_W = 148; // fixed px — both states same width

function ViewCaseBtn({ hovered, disabled }) {
  const { theme } = React.useContext(ThemeCtx);
  const strings   = React.useContext(StringsCtx);
  const label     = strings?.view_case ?? 'View case';
  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 10,
      width: CASE_BTN_W,
      fontFamily: HOME_MONO, fontSize: 11,
      letterSpacing: '0.18em', textTransform: 'uppercase',
      color: disabled ? theme.dim : (hovered ? theme.bg : theme.fg),
      border: `1px solid ${disabled ? theme.rule : theme.fg}`,
      borderRadius: 4,
      padding: '11px 0',
      background: (!disabled && hovered) ? theme.fg : 'transparent',
      transition: 'background 180ms ease, color 180ms ease',
      whiteSpace: 'nowrap',
      boxSizing: 'border-box',
    }}>
      <span>{label}</span>
      <span style={{
        display: 'inline-block',
        opacity: disabled ? 0 : 1,
        animation: (!disabled && hovered) ? 'hub-bounce 0.55s cubic-bezier(.36,.07,.19,.97) infinite' : 'none',
        fontSize: 13,
        width: 13,
      }}>↗</span>
    </div>
  );
}

// ── CaseCard ──────────────────────────────────────────────────────────────────

function CaseCard({ id, company, year, status, thumb, video, lang }) {
  const { theme }   = React.useContext(ThemeCtx);
  const strings     = React.useContext(StringsCtx);
  const caseStrings = strings?.cases?.[id];
  const projectName = caseStrings?.projectName ?? id;
  const role        = caseStrings?.role ?? '';
  const ref      = React.useRef(null);
  const videoRef = React.useRef(null);
  const visible  = useInView(ref);
  const [hovered, setHovered] = React.useState(false);
  const isLive = status === 'live';

  React.useEffect(() => {
    const v = videoRef.current;
    if (!v) return;
    if (hovered) { v.currentTime = 0; v.play().catch(() => {}); }
    else { v.pause(); v.currentTime = 0; }
  }, [hovered]);
  const href = `/${id}/?lang=${lang}`;

  return (
    <a
      ref={ref}
      href={isLive ? href : undefined}
      onMouseEnter={() => { if (isLive) setHovered(true); }}
      onMouseLeave={() => setHovered(false)}
      style={{
        display: 'block',
        textDecoration: 'none',
        color: theme.fg,
        opacity: visible ? 1 : 0,
        transform: visible
          ? (hovered ? 'translateX(6px)' : 'translateX(0)')
          : 'translateY(32px)',
        transition: 'opacity 700ms cubic-bezier(.22,.61,.36,1), transform 320ms cubic-bezier(.4,0,.2,1)',
        cursor: isLive ? 'pointer' : 'default',
        pointerEvents: isLive ? 'auto' : 'none',
      }}
    >
      <div style={{
        borderTop: `1px solid ${hovered ? (theme.rule.replace(/[\d.]+\)$/, '0.45)')) : theme.rule}`,
        paddingTop: 32,
        paddingBottom: 32,
        display: 'grid',
        gridTemplateColumns: '1fr auto auto',
        gap: 40,
        alignItems: 'center',
        background: hovered ? theme.hoverBg : 'transparent',
        marginLeft: -24, marginRight: -24, paddingLeft: 24, paddingRight: 24,
        transition: 'border-color 320ms cubic-bezier(.4,0,.2,1), background 320ms cubic-bezier(.4,0,.2,1)',
      }}>
        {/* Text */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          <div style={{
            fontSize: 'clamp(20px, 2.6vw, 38px)', fontWeight: 500,
            letterSpacing: '-0.04em', lineHeight: 0.95,
            color: isLive ? theme.fg : theme.muted,
            fontFamily: HOME_SANS,
          }}>
            {company}
          </div>
          <div style={{
            fontSize: 'clamp(11px, 1.1vw, 16px)', fontWeight: 400, fontStyle: 'italic',
            letterSpacing: '-0.01em',
            color: isLive ? theme.muted : theme.dim,
            fontFamily: HOME_SANS,
          }}>
            {projectName}
          </div>
          <div style={{ display: 'flex', gap: 16, marginTop: 4 }}>
            <div style={{
              fontFamily: HOME_MONO, fontSize: 11,
              color: isLive ? theme.muted : theme.dim, letterSpacing: '0.06em',
            }}>{role}</div>
            <div style={{
              fontFamily: HOME_MONO, fontSize: 11,
              color: theme.dim, letterSpacing: '0.10em',
            }}>{year}</div>
          </div>
        </div>

        {/* Thumbnail */}
        <div style={{
          width: 'clamp(180px, 18vw, 280px)',
          aspectRatio: '16/9',
          overflow: 'hidden',
          borderRadius: 8,
          flexShrink: 0,
          background: theme.rule,
          position: 'relative',
          opacity: isLive ? (hovered ? 1 : 0.75) : 0.28,
          transition: 'opacity 320ms cubic-bezier(.4,0,.2,1)',
        }}>
          {thumb && (
            <img
              src={thumb}
              alt={company}
              style={{
                position: 'absolute', inset: 0,
                width: '100%', height: '100%',
                objectFit: 'cover', objectPosition: 'center 30%',
                display: 'block',
                transition: 'opacity 400ms ease',
                opacity: (hovered && video) ? 0 : 1,
              }}
            />
          )}
          {video && (
            <video
              ref={videoRef}
              src={video}
              muted loop playsInline
              style={{
                position: 'absolute', inset: 0,
                width: '100%', height: '100%',
                objectFit: 'cover', objectPosition: '50% 15%',
                display: 'block',
                opacity: hovered ? 1 : 0,
                transition: 'opacity 400ms ease',
              }}
            />
          )}
        </div>

        {/* Action */}
        <div style={{ display: 'flex', alignItems: 'center' }}>
          {isLive ? (
            <ViewCaseBtn hovered={hovered} disabled={false} />
          ) : (
            <span style={{
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
              width: CASE_BTN_W,
              fontFamily: HOME_MONO, fontSize: 9,
              letterSpacing: '0.22em', textTransform: 'uppercase',
              color: theme.dim,
              border: `1px solid ${theme.rule}`,
              borderRadius: 4,
              padding: '11px 0',
              boxSizing: 'border-box',
            }}>
              {strings?.coming_soon ?? 'Soon'}
            </span>
          )}
        </div>
      </div>
    </a>
  );
}

// ── LangSwitcher ──────────────────────────────────────────────────────────────

const LANG_BTN_W = 28; // px, fixed width per button
const LANG_SEP_W = 12; // px, separator width (gap + char)

function LangSwitcher({ lang, setLang }) {
  const { theme } = React.useContext(ThemeCtx);
  const [hoverCode, setHoverCode] = React.useState(null);

  const activeIdx  = LOCALES.findIndex(l => l.code === lang);
  const hoverIdx   = hoverCode ? LOCALES.findIndex(l => l.code === hoverCode) : -1;
  const underlineIdx = hoverIdx >= 0 ? hoverIdx : activeIdx;
  const underlineX   = underlineIdx * (LANG_BTN_W + LANG_SEP_W);

  return (
    <div style={{ position: 'relative', display: 'flex', alignItems: 'center' }}>
      {LOCALES.map((l, i) => (
        <React.Fragment key={l.code}>
          <button
            onClick={() => setLang(l.code)}
            onMouseEnter={() => setHoverCode(l.code)}
            onMouseLeave={() => setHoverCode(null)}
            style={{
              appearance: 'none', border: 'none', background: 'transparent',
              fontFamily: HOME_MONO, fontSize: 11,
              letterSpacing: '0.16em', textTransform: 'uppercase',
              color: l.code === lang ? theme.fg : theme.dim,
              cursor: 'pointer',
              width: LANG_BTN_W, padding: '4px 0',
              textAlign: 'center',
              transition: 'color 150ms ease',
            }}
          >
            {l.label}
          </button>
          {i < LOCALES.length - 1 && (
            <span style={{
              color: theme.dim, fontSize: 10,
              width: LANG_SEP_W, textAlign: 'center',
              pointerEvents: 'none', userSelect: 'none',
            }}>/</span>
          )}
        </React.Fragment>
      ))}
      {/* sliding underline */}
      <div style={{
        position: 'absolute',
        bottom: 0,
        left: underlineX,
        width: LANG_BTN_W,
        height: 1,
        background: theme.fg,
        transition: 'left 200ms cubic-bezier(.4,0,.2,1), background 300ms ease',
      }} />
    </div>
  );
}

// ── RoleRoulette ──────────────────────────────────────────────────────────────

const ROULETTE_ROLES_DEFAULT = [
  'Staff Product Designer – LATAM',
  'Head of Design Foundation',
  'Design Systems Architect',
  'Design × Engineering Lead',
];

function RoleRoulette() {
  const { theme } = React.useContext(ThemeCtx);
  const strings   = React.useContext(StringsCtx);
  const roles     = strings?.roles ?? ROULETTE_ROLES_DEFAULT;
  const [idx, setIdx] = React.useState(0);
  const [key, setKey] = React.useState(0);

  React.useEffect(() => {
    setIdx(0);
    setKey(k => k + 1);
  }, [roles]);

  React.useEffect(() => {
    const iv = setInterval(() => {
      setIdx(i => (i + 1) % roles.length);
      setKey(k => k + 1);
    }, 2600);
    return () => clearInterval(iv);
  }, [roles]);

  return (
    <div style={{ overflow: 'hidden', height: '42px', marginTop: 18 }}>
      <div key={key} style={{
        fontFamily: HOME_SANS, fontWeight: 300,
        fontSize: 'clamp(15px, 1.8vw, 24px)', lineHeight: '42px',
        letterSpacing: '-0.02em',
        color: theme.muted,
        animation: 'hub-roulette 480ms cubic-bezier(.22,.61,.36,1) both',
      }}>
        {roles[idx]}
      </div>
    </div>
  );
}

// ── HomeHeader ────────────────────────────────────────────────────────────────

function HomeHeader({ lang, setLang }) {
  const { theme } = React.useContext(ThemeCtx);
  const strings   = React.useContext(StringsCtx);
  const [ready, setReady] = React.useState(false);
  React.useEffect(() => {
    const t = setTimeout(() => setReady(true), 60);
    return () => clearTimeout(t);
  }, []);

  const anim = (delay, duration = 600) => ready ? {
    animation: `pp-fade-up ${duration}ms cubic-bezier(.22,.61,.36,1) ${delay}ms both`,
  } : { opacity: 0 };

  return (
    <header style={{ paddingTop: 96, paddingBottom: 72 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
        <div>
          <div style={{
            fontFamily: HOME_MONO, fontSize: 11,
            letterSpacing: '0.22em', textTransform: 'uppercase',
            color: theme.muted, marginBottom: 20,
            display: 'flex', alignItems: 'center', gap: 14,
            ...anim(0, 500),
          }}>
            <span style={{ width: 32, height: 1, background: 'currentColor', display: 'inline-block', opacity: 0.6 }} />
            <span>{strings?.eyebrow ?? 'Design deck cases • Hub'}</span>
          </div>

          <div style={{ overflow: 'hidden', lineHeight: 1 }}>
            <h1 style={{
              margin: 0,
              fontFamily: HOME_SANS, fontWeight: 500,
              fontSize: 'clamp(48px, 6.5vw, 88px)', letterSpacing: '-0.05em', lineHeight: 0.88,
              color: theme.fg,
              ...(ready ? {
                animation: 'hub-sunrise 900ms cubic-bezier(.16,1,.3,1) 80ms both',
              } : { transform: 'translateY(110%)' }),
            }}>
              Julio Ferracini
            </h1>
          </div>

          {ready && <RoleRoulette />}
        </div>

        <div style={{ display: 'flex', alignItems: 'center', gap: 20, paddingTop: 8, ...anim(200, 500) }}>
          <LangSwitcher lang={lang} setLang={setLang} />
          <ThemeToggle />
        </div>
      </div>
    </header>
  );
}

// ── HomeFooter ────────────────────────────────────────────────────────────────

function HomeFooter() {
  const { theme } = React.useContext(ThemeCtx);
  const strings   = React.useContext(StringsCtx);
  return (
    <footer style={{
      borderTop: `1px solid ${theme.rule}`,
      paddingTop: 36, paddingBottom: 56,
      display: 'flex', justifyContent: 'space-between', alignItems: 'center',
    }}>
      <div style={{ fontFamily: HOME_MONO, fontSize: 12, color: theme.dim, letterSpacing: '0.12em' }}>
        {strings?.footer_label ?? 'Julio Ferracini · Portfolio'}
      </div>
      <div style={{ display: 'flex', gap: 36 }}>
        {[
          { label: 'julioferracini.com', href: 'https://julioferracini.com' },
          { label: 'LinkedIn',           href: 'https://www.linkedin.com/in/julioferracini' },
          { label: 'Email',              href: 'mailto:jferracini@gmail.com' },
        ].map((l) => (
          <a key={l.label} href={l.href}
            target={l.href.startsWith('mailto:') ? undefined : '_blank'}
            rel={l.href.startsWith('mailto:') ? undefined : 'noreferrer'}
            style={{
              fontFamily: HOME_MONO, fontSize: 12, color: theme.muted,
              letterSpacing: '0.08em', textDecoration: 'none',
              transition: 'color 150ms',
            }}
            onMouseEnter={(e) => { e.target.style.color = theme.fg; }}
            onMouseLeave={(e) => { e.target.style.color = theme.muted; }}
          >
            {l.label}
          </a>
        ))}
      </div>
    </footer>
  );
}

// ── HomePage ──────────────────────────────────────────────────────────────────

function HomePage() {
  const [lang, setLang] = useLangPref();
  const themeCtx = useThemePref();
  const { theme } = themeCtx;
  const strings = useHubStrings(lang);

  return (
    <ThemeCtx.Provider value={themeCtx}>
    <StringsCtx.Provider value={strings}>
      <div style={{
        background: theme.bg,
        color: theme.fg,
        minHeight: '100vh',
        fontFamily: HOME_SANS,
        paddingLeft: 96, paddingRight: 96,
        transition: 'background 300ms ease, color 300ms ease',
      }}>
        <HomeHeader lang={lang} setLang={setLang} />
        <main>
          {CASES.map((c) => (
            <CaseCard key={c.id} {...c} lang={lang} />
          ))}
        </main>
        <HomeFooter />
      </div>
    </StringsCtx.Provider>
    </ThemeCtx.Provider>
  );
}

Object.assign(window, { HomePage });
