// components.jsx — shared UI primitives + Header + Footer
const { useState, useEffect, useRef, useMemo, useCallback } = React;

/* ------------------------------------------------------------------
   Icons (minimal stroke set)
------------------------------------------------------------------ */
const Icon = ({ name, size = 18, stroke = 1.5 }) => {
  const s = { width: size, height: size, fill: 'none', stroke: 'currentColor',
              strokeWidth: stroke, strokeLinecap: 'round', strokeLinejoin: 'round' };
  const paths = {
    search:   <><circle cx="11" cy="11" r="7"/><path d="M20 20l-3.5-3.5"/></>,
    user:     <><circle cx="12" cy="8" r="4"/><path d="M4 21c1.5-4 5-6 8-6s6.5 2 8 6"/></>,
    bookmark: <path d="M6 4h12v17l-6-3-6 3V4z"/>,
    bookmarkFilled: <path d="M6 4h12v17l-6-3-6 3V4z" fill="currentColor"/>,
    share:    <><circle cx="6" cy="12" r="2"/><circle cx="18" cy="6" r="2"/><circle cx="18" cy="18" r="2"/><path d="M8 11l8-4M8 13l8 4"/></>,
    print:    <><path d="M7 8V3h10v5M7 18H4v-7h16v7h-3M7 14h10v7H7z"/></>,
    star:     <path d="M12 3l2.8 5.7 6.3.9-4.5 4.4 1 6.3L12 17.6l-5.6 2.7 1-6.3L2.9 9.6l6.3-.9z" fill="currentColor" stroke="none"/>,
    starOutline: <path d="M12 3l2.8 5.7 6.3.9-4.5 4.4 1 6.3L12 17.6l-5.6 2.7 1-6.3L2.9 9.6l6.3-.9z"/>,
    clock:    <><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></>,
    minus:    <path d="M5 12h14"/>,
    plus:     <path d="M12 5v14M5 12h14"/>,
    check:    <path d="M4 12l5 5 11-12"/>,
    arrowR:   <path d="M5 12h14M13 6l6 6-6 6"/>,
    arrowL:   <path d="M19 12H5M11 6l-6 6 6 6"/>,
    arrowUp:  <path d="M12 19V5M6 11l6-6 6 6"/>,
    chevronR: <path d="M9 6l6 6-6 6"/>,
    chevronD: <path d="M6 9l6 6 6-6"/>,
    close:    <path d="M6 6l12 12M18 6L6 18"/>,
    timer:    <><circle cx="12" cy="13" r="8"/><path d="M9 2h6M12 5v3M12 13l3-2"/></>,
    play:     <path d="M7 5l12 7-12 7z" fill="currentColor" stroke="none"/>,
    pause:    <><path d="M8 5v14M16 5v14"/></>,
    sun:      <><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M2 12h2M20 12h2M5 5l1.5 1.5M17.5 17.5L19 19M5 19l1.5-1.5M17.5 6.5L19 5"/></>,
    moon:     <path d="M20 14a8 8 0 11-10-10 6 6 0 0010 10z"/>,
    flame:    <path d="M12 3c0 4-5 5-5 10a5 5 0 0010 0c0-2-1-3-2-4 0 2-1 3-2 3 0-4 1-6-1-9z"/>,
    sparkle:  <path d="M12 3v6m0 6v6M3 12h6m6 0h6M6 6l3 3m6 6l3 3M6 18l3-3m6-6l3-3"/>,
    leaf:     <path d="M5 19c8 0 14-6 14-14C11 5 5 11 5 19zM5 19l5-5"/>,
    globe:    <><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3c3 3 4.5 6 4.5 9S15 21 12 21s-4.5-3-4.5-9S9 3 12 3z"/></>,
    fire:     <path d="M12 3c0 4-5 5-5 10a5 5 0 0010 0c0-3-2-3-2-6 0 2-1 2-1 2 0-3 0-4-2-6z"/>,
    knife:    <path d="M4 20l8-8M13 11l7-7-1-1c-3 0-5 2-7 4l-2 2"/>,
    list:     <><path d="M4 6h16M4 12h16M4 18h10"/></>,
    grid:     <><path d="M4 4h7v7H4zM13 4h7v7h-7zM4 13h7v7H4zM13 13h7v7h-7z"/></>,
    filter:   <path d="M4 5h16l-6 8v6l-4-2v-4z"/>,
    mic:      <><rect x="9" y="3" width="6" height="11" rx="3"/><path d="M5 11a7 7 0 0014 0M12 18v3M9 21h6"/></>,
    enter:    <path d="M20 6v6a3 3 0 01-3 3H6l4 4m-4-4l4-4"/>,
  };
  return <svg viewBox="0 0 24 24" style={s} aria-hidden>{paths[name] || null}</svg>;
};

/* ------------------------------------------------------------------
   Stars
------------------------------------------------------------------ */
const Stars = ({ value = 0, size = 14 }) => {
  const full = Math.floor(value);
  const half = value - full >= 0.5;
  return (
    <span style={{ display: 'inline-flex', gap: 1, color: 'var(--accent)' }} aria-label={`${value} out of 5`}>
      {[0,1,2,3,4].map(i => {
        if (i < full) return <Icon key={i} name="star" size={size} />;
        if (i === full && half) return (
          <span key={i} style={{ position: 'relative', display: 'inline-flex' }}>
            <Icon name="starOutline" size={size} />
            <span style={{ position: 'absolute', inset: 0, overflow: 'hidden', width: '50%' }}>
              <Icon name="star" size={size} />
            </span>
          </span>
        );
        return <span key={i} style={{ color: 'var(--ink-mute)' }}><Icon name="starOutline" size={size} /></span>;
      })}
    </span>
  );
};

/* ------------------------------------------------------------------
   Photo placeholder (uses CSS .photo class)
------------------------------------------------------------------ */
const Photo = ({ tone = 'butter', label, ratio = '4/3', radius = 'var(--r-4)', style = {}, children }) => (
  <div className="photo" data-tone={tone} style={{ aspectRatio: ratio, borderRadius: radius, ...style }}>
    {label && <span className="photo-label">{label}</span>}
    {children}
  </div>
);

/* ------------------------------------------------------------------
   Logo
------------------------------------------------------------------ */
const Logo = ({ size = 22 }) => (
  <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
    <span style={{
      width: size, height: size, borderRadius: 999,
      background: 'var(--accent)',
      display: 'inline-grid', placeItems: 'center',
      color: 'var(--accent-ink)', fontFamily: 'var(--font-display)',
      fontSize: size * 0.55, fontWeight: 600, letterSpacing: '-0.04em',
      boxShadow: 'inset 0 -2px 0 rgba(0,0,0,.1), 0 1px 2px rgba(0,0,0,.08)',
    }}>i</span>
    <span className="display" style={{ fontSize: 19, fontWeight: 600, color: 'var(--ink-strong)', letterSpacing: '-0.025em' }}>
      inspirecipe
    </span>
  </span>
);

/* ------------------------------------------------------------------
   Header
------------------------------------------------------------------ */
const Header = ({ locale, route, onNavigate, onOpenLocale }) => {
  const [scrolled, setScrolled] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 12);
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  // Chrome is always English. Routes do not include locale.
  const navItems = [
    { label: 'Recipes',       route: '/recipes' },
    { label: 'Collections',   route: '/collections' },
    { label: 'Cuisines',      route: '/cuisines' },
    { label: 'Quick & Easy',  route: '/quick' },
    { label: 'Methods',       route: '/methods' },
  ];

  return (
    <header style={{
      position: 'sticky', top: 0, zIndex: 40,
      background: scrolled ? 'color-mix(in oklab, var(--bg) 88%, transparent)' : 'transparent',
      backdropFilter: scrolled ? 'blur(18px) saturate(140%)' : 'none',
      WebkitBackdropFilter: scrolled ? 'blur(18px) saturate(140%)' : 'none',
      borderBottom: scrolled ? '1px solid var(--line)' : '1px solid transparent',
      transition: 'all .25s var(--ease)',
    }}>
      <div className="page" style={{
        display: 'flex', alignItems: 'center', gap: 'var(--s-6)',
        height: 68,
      }}>
        <a href="#/" onClick={(e)=>{e.preventDefault(); onNavigate('/');}}>
          <Logo />
        </a>

        <nav className="nav-main" style={{ display: 'flex', gap: 4, marginLeft: 'var(--s-4)' }}>
          {navItems.map(n => {
            const isActive = route === n.route || (n.route !== '/' && route.startsWith(n.route));
            return (
              <a key={n.label} href={`#${n.route}`}
                 onClick={(e)=>{e.preventDefault(); onNavigate(n.route);}}
                 style={{
                   padding: '8px 12px', fontSize: 14, fontWeight: 500,
                   color: isActive ? 'var(--ink-strong)' : 'var(--ink-soft)',
                   background: isActive ? 'var(--bg-sunken)' : 'transparent',
                   borderRadius: 'var(--r-2)',
                   transition: 'color .15s, background .15s',
                 }}
                 onMouseEnter={e=>{e.currentTarget.style.color='var(--ink-strong)'; e.currentTarget.style.background='var(--bg-sunken)';}}
                 onMouseLeave={e=>{ if(!isActive){ e.currentTarget.style.color='var(--ink-soft)'; e.currentTarget.style.background='transparent'; } }}
              >{n.label}</a>
            );
          })}
        </nav>

        <div style={{ flex: 1 }} />

        <button className="btn btn-ghost btn-sm" onClick={()=>onNavigate('/ask')}
                style={{ gap: 6 }}>
          <Icon name="sparkle" size={14} />
          <span>AI Sous-Chef</span>
        </button>

        <button className="btn btn-ghost btn-sm" onClick={onOpenLocale} aria-label="Language">
          <Icon name="globe" size={14} />
          <span style={{ fontVariant: 'all-small-caps', letterSpacing: '.05em' }}>{locale.toUpperCase()}</span>
        </button>

        <button className="btn btn-sm" aria-label="Search"
                style={{ background: 'var(--bg-sunken)', color: 'var(--ink)' }}
                onClick={()=>document.getElementById('global-search')?.focus()}>
          <Icon name="search" size={14} />
        </button>
      </div>

      <style>{`
        @media (max-width: 880px){
          .nav-main { display: none !important; }
        }
      `}</style>
    </header>
  );
};

/* ------------------------------------------------------------------
   Locale picker modal
------------------------------------------------------------------ */
const LocalePicker = ({ open, onClose, locale, onPick }) => {
  if (!open) return null;
  const grouped = LOCALES.reduce((acc, l) => {
    (acc[l.region] = acc[l.region] || []).push(l); return acc;
  }, {});
  return (
    <div role="dialog" aria-modal="true"
         onClick={onClose}
         style={{
           position: 'fixed', inset: 0, zIndex: 60,
           background: 'color-mix(in oklab, var(--bg) 40%, rgba(0,0,0,.45))',
           backdropFilter: 'blur(8px)',
           display: 'grid', placeItems: 'center',
           padding: 'var(--s-6)',
           animation: 'fadeUp .25s var(--ease)',
         }}>
      <div onClick={e=>e.stopPropagation()}
           style={{
             background: 'var(--bg-elevated)', borderRadius: 'var(--r-5)',
             border: '1px solid var(--line)', boxShadow: 'var(--shadow-lg)',
             padding: 'var(--s-8)',
             maxWidth: 560, width: '100%',
           }}>
        <div className="row between" style={{ marginBottom: 'var(--s-6)' }}>
          <div>
            <div className="eyebrow">Choose language</div>
            <h2 className="display" style={{ fontSize: 26, margin: '6px 0 0' }}>Recipes in your language</h2>
          </div>
          <button className="btn btn-ghost btn-sm" onClick={onClose} aria-label="Close">
            <Icon name="close" size={14} />
          </button>
        </div>
        {Object.entries(grouped).map(([region, list]) => (
          <div key={region} style={{ marginBottom: 'var(--s-5)' }}>
            <div className="eyebrow" style={{ marginBottom: 8 }}>{region}</div>
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(160px, 1fr))', gap: 8 }}>
              {list.map(l => (
                <button key={l.code} onClick={()=>onPick(l.code)}
                  style={{
                    display: 'flex', alignItems: 'center', gap: 12,
                    padding: '10px 12px', borderRadius: 'var(--r-3)',
                    background: l.code === locale ? 'var(--accent-tint)' : 'transparent',
                    border: l.code === locale ? '1px solid var(--accent)' : '1px solid var(--line)',
                    color: 'var(--ink)', fontFamily: 'inherit',
                    transition: 'all .15s var(--ease)', textAlign: 'left',
                  }}
                  onMouseEnter={e=>{ if(l.code!==locale) e.currentTarget.style.background='var(--bg-sunken)'; }}
                  onMouseLeave={e=>{ if(l.code!==locale) e.currentTarget.style.background='transparent'; }}
                >
                  <span style={{
                    display: 'inline-grid', placeItems: 'center',
                    width: 30, height: 22, borderRadius: 3,
                    background: 'var(--bg-sunken)', fontFamily: 'var(--font-mono)',
                    fontSize: 10, fontWeight: 600, letterSpacing: '.05em',
                    color: 'var(--ink-soft)',
                  }}>{l.flag}</span>
                  <span>
                    <div style={{ fontSize: 14, fontWeight: 500 }}>{l.name}</div>
                    <div style={{ fontSize: 11, color: 'var(--ink-mute)', fontFamily: 'var(--font-mono)' }}>
                      /{l.code}/
                    </div>
                  </span>
                </button>
              ))}
            </div>
          </div>
        ))}
      </div>
    </div>
  );
};

/* ------------------------------------------------------------------
   Footer
------------------------------------------------------------------ */
const FOOTER_COLS = [
  { title: 'Recipes', links: [
    { label: 'Trending',         route: '/trending' },
    { label: 'New this week',    route: '/new' },
    { label: 'Seasonal',         route: '/seasonal' },
    { label: '30-minute meals',  route: '/quick' },
    { label: 'Baking',           route: '/baking' },
    { label: 'One-pan',          route: '/one-pan' },
  ]},
  { title: 'Discover', links: [
    { label: 'Cuisines of the world', route: '/cuisines' },
    { label: 'By technique',          route: '/methods' },
    { label: 'By diet',               route: '/by-diet' },
    { label: 'By ingredient',         route: '/by-ingredient' },
    { label: 'Collections',           route: '/collections' },
    { label: 'AI Sous-Chef',          route: '/ask' },
  ]},
  { title: 'Inspirecipe', links: [
    { label: 'How we test',   route: '/how-we-test' },
    { label: 'Our editors',   route: '/editors' },
    { label: 'Careers',       route: '/careers' },
    { label: 'Press',         route: '/press' },
    { label: 'Accessibility', route: '/accessibility' },
    { label: 'Contact',       route: '/contact' },
  ]},
];

const Footer = ({ locale, onNavigate }) => (
  <footer style={{
    marginTop: 'var(--s-20)',
    borderTop: '1px solid var(--line)',
    padding: 'var(--s-16) 0 var(--s-10)',
    background: 'var(--bg-sunken)',
  }}>
    <div className="page footer-grid" style={{
      display: 'grid', gridTemplateColumns: '1.4fr 1fr 1fr 1fr', gap: 'var(--s-10)',
    }}>
      <div>
        <a href="#/" onClick={e=>{e.preventDefault(); onNavigate('/');}} style={{ textDecoration: 'none' }}>
          <Logo size={24} />
        </a>
        <p style={{ marginTop: 14, color: 'var(--ink-soft)', fontSize: 14, maxWidth: 300, lineHeight: 1.6 }}>
          Recipes that respect your time. Every recipe tested at least three times in a real home kitchen.
        </p>
        <div style={{ marginTop: 18 }}>
          <div className="eyebrow" style={{ marginBottom: 8 }}>Languages</div>
          <div className="row wrap" style={{ gap: 6 }}>
            {LOCALES.map(l => (
              <a key={l.code} href={`#/${l.code}/`}
                 onClick={e=>{e.preventDefault(); onNavigate(`/${l.code}/`);}}
                 style={{
                   fontFamily: 'var(--font-mono)', fontSize: 10, fontWeight: 600,
                   padding: '4px 8px', borderRadius: 4,
                   background: l.code === locale ? 'var(--ink-strong)' : 'var(--bg)',
                   color: l.code === locale ? 'var(--bg)' : 'var(--ink-mute)',
                   letterSpacing: '.06em', border: '1px solid var(--line)',
                   textDecoration: 'none',
                 }}>{l.flag}</a>
            ))}
          </div>
        </div>
      </div>
      {FOOTER_COLS.map(col => (
        <FooterCol key={col.title} title={col.title} links={col.links} onNavigate={onNavigate} />
      ))}
    </div>
    <div className="page row between" style={{
      marginTop: 'var(--s-12)', paddingTop: 'var(--s-6)',
      borderTop: '1px solid var(--line)',
      fontSize: 12, color: 'var(--ink-mute)', flexWrap: 'wrap', gap: 12,
    }}>
      <span>© 2026 Inspirecipe. Recipes that respect your time.</span>
      <span style={{ display: 'flex', gap: 16, flexWrap: 'wrap' }}>
        <a href="#/accessibility" onClick={e=>{e.preventDefault(); onNavigate('/accessibility');}} style={{ color: 'inherit' }}>Accessibility</a>
        <a href="#/privacy" onClick={e=>{e.preventDefault(); onNavigate('/privacy');}} style={{ color: 'inherit' }}>Privacy</a>
        <a href="#/terms" onClick={e=>{e.preventDefault(); onNavigate('/terms');}} style={{ color: 'inherit' }}>Terms</a>
      </span>
      <span style={{ fontFamily: 'var(--font-mono)' }}>v1.0 · {locale.toUpperCase()}</span>
    </div>
    <style>{`
      @media (max-width: 880px){
        .footer-grid { grid-template-columns: 1fr 1fr !important; }
        .footer-grid > div:first-child { grid-column: 1 / -1; }
      }
      @media (max-width: 520px){
        .footer-grid { grid-template-columns: 1fr !important; }
      }
    `}</style>
  </footer>
);

const FooterCol = ({ title, links, onNavigate }) => (
  <div>
    <div className="eyebrow" style={{ marginBottom: 12 }}>{title}</div>
    <ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 8 }}>
      {links.map(l => (
        <li key={l.label}>
          <a href={`#${l.route}`}
             onClick={e=>{e.preventDefault(); onNavigate(l.route);}}
             style={{
               color: 'var(--ink-soft)', fontSize: 14, transition: 'color .15s',
               textDecoration: 'none', display: 'inline-block',
             }}
             onMouseEnter={e=>{e.currentTarget.style.color='var(--ink-strong)';}}
             onMouseLeave={e=>{e.currentTarget.style.color='var(--ink-soft)';}}>{l.label}</a>
        </li>
      ))}
    </ul>
  </div>
);

/* ------------------------------------------------------------------
   Recipe card (used by grids)
------------------------------------------------------------------ */
const RecipeCard = ({ recipe, locale, onClick, large = false }) => {
  const [saved, setSaved] = useState(false);
  return (
    <article className="card fade-in" onClick={onClick}
      style={{ overflow: 'hidden', cursor: 'pointer',
               display: 'flex', flexDirection: 'column' }}>
      <Photo tone={recipe.tone} label={`food photo · ${recipe.title.toLowerCase().slice(0, 28)}`}
             ratio={large ? '5/4' : '4/3'} radius="0" />
      <div style={{ padding: large ? 'var(--s-5)' : 'var(--s-4)', display: 'flex', flexDirection: 'column', gap: 10, flex: 1 }}>
        {recipe.tag && (
          <div className="row between">
            <span className="chip chip-outline" style={{ fontSize: 11 }}>{recipe.tag}</span>
            <button aria-label="Save"
                    onClick={(e)=>{e.stopPropagation(); setSaved(s => !s);}}
                    style={{ background: 'transparent', border: 0, color: saved ? 'var(--accent)' : 'var(--ink-mute)', padding: 0 }}>
              <Icon name={saved ? 'bookmarkFilled' : 'bookmark'} size={18} />
            </button>
          </div>
        )}
        <h3 className="display" style={{
          fontSize: large ? 22 : 17, fontWeight: 500, margin: 0, color: 'var(--ink-strong)',
          letterSpacing: '-0.015em',
        }}>{recipe.title}</h3>
        <div className="row between meta" style={{ marginTop: 'auto', paddingTop: 6 }}>
          <span className="row" style={{ gap: 6 }}>
            <Stars value={recipe.rating} size={12} />
            <span className="num" style={{ fontSize: 12, color: 'var(--ink-mute)' }}>{recipe.rating}</span>
          </span>
          <span className="row" style={{ gap: 4, color: 'var(--ink-mute)', fontSize: 12 }}>
            <Icon name="clock" size={12} />
            <span className="num">{recipe.time} {t(locale, 'minutes')}</span>
          </span>
        </div>
        {recipe.author && (
          <div className="row meta" style={{ gap: 6, fontSize: 12, color: 'var(--ink-mute)' }}>
            <span style={{
              width: 18, height: 18, borderRadius: 999,
              background: 'var(--accent-soft)', color: 'var(--accent)',
              display: 'grid', placeItems: 'center', fontSize: 9, fontWeight: 700,
            }}>{recipe.author.split(' ').map(s=>s[0]).join('').slice(0,2)}</span>
            <span>{recipe.author}</span>
          </div>
        )}
      </div>
    </article>
  );
};

Object.assign(window, { Icon, Stars, Photo, Logo, Header, Footer, LocalePicker, RecipeCard });
