/* ============================================================
   frame.jsx — icons, phone shell, bottom nav, shared atoms
   ============================================================ */

/* ---------- Icons (stroke, currentColor) ---------- */
const PATHS = {
  target: '<circle cx="12" cy="12" r="8"/><circle cx="12" cy="12" r="4"/><circle cx="12" cy="12" r="1" fill="currentColor"/>',
  spark: '<path d="M12 3v4M12 17v4M3 12h4M17 12h4M5.6 5.6l2.8 2.8M15.6 15.6l2.8 2.8M18.4 5.6l-2.8 2.8M8.4 15.6l-2.8 2.8"/>',
  cap: '<path d="M3 9l9-4 9 4-9 4-9-4z"/><path d="M7 11v4c0 1 2.2 2.5 5 2.5s5-1.5 5-2.5v-4"/>',
  briefcase: '<rect x="3" y="7" width="18" height="13" rx="2"/><path d="M8 7V5a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M3 12h18"/>',
  clock: '<circle cx="12" cy="12" r="8"/><path d="M12 8v4l3 2"/>',
  pin: '<path d="M12 21s7-5.2 7-11a7 7 0 1 0-14 0c0 5.8 7 11 7 11z"/><circle cx="12" cy="10" r="2.5"/>',
  chevron: '<path d="M9 6l6 6-6 6"/>',
  chevDown: '<path d="M6 9l6 6 6-6"/>',
  check: '<path d="M5 12.5l4.5 4.5L19 7"/>',
  arrow: '<path d="M5 12h14M13 6l6 6-6 6"/>',
  plus: '<path d="M12 5v14M5 12h14"/>',
  mic: '<rect x="9" y="3" width="6" height="11" rx="3"/><path d="M5 11a7 7 0 0 0 14 0M12 18v3"/>',
  clip: '<path d="M21 11.5l-8.5 8.5a5 5 0 0 1-7-7l8.5-8.5a3.5 3.5 0 0 1 5 5l-8.6 8.5a2 2 0 0 1-3-3l8-8"/>',
  send: '<path d="M4 12l16-7-7 16-2.5-6.5L4 12z"/>',
  sun: '<circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M2 12h2M20 12h2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M19.1 4.9l-1.4 1.4M6.3 17.7l-1.4 1.4"/>',
  moon: '<path d="M20 14a8 8 0 1 1-9.5-9.8A6.5 6.5 0 0 0 20 14z"/>',
  globe: '<circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3c2.5 2.7 2.5 15.3 0 18M12 3c-2.5 2.7-2.5 15.3 0 18"/>',
  lock: '<rect x="5" y="11" width="14" height="9" rx="2"/><path d="M8 11V8a4 4 0 0 1 8 0v3"/>',
  fire: '<path d="M12 3c1 3-2 4-2 7a2 2 0 0 0 4 0c2 1.5 3 3.5 3 5.5a5 5 0 0 1-10 0C7 12 12 10 12 3z"/>',
  eye: '<path d="M2 12s4-7 10-7 10 7 10 7-4 7-10 7-10-7-10-7z"/><circle cx="12" cy="12" r="3"/>',
  trend: '<path d="M3 17l6-6 4 4 7-7M14 8h6v6"/>',
  // nav
  n_stories: '<rect x="4" y="3" width="16" height="18" rx="3"/><path d="M9 7h6M9 11h6M9 15h3"/>',
  n_jobs: '<rect x="3" y="7" width="18" height="13" rx="2"/><path d="M8 7V5a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>',
  n_advisor: '<path d="M21 12a8 8 0 0 1-8 8H4l1.8-3.4A8 8 0 1 1 21 12z"/><circle cx="9" cy="12" r="1" fill="currentColor"/><circle cx="13" cy="12" r="1" fill="currentColor"/><circle cx="17" cy="12" r="1" fill="currentColor"/>',
  n_growth: '<path d="M4 19V5M4 19h16M8 16V11M12 16V7M16 16v-3"/>',
  n_profile: '<circle cx="12" cy="8" r="4"/><path d="M5 20a7 7 0 0 1 14 0"/>',
  voice: '<path d="M4 12v0M8 8v8M12 5v14M16 8v8M20 12v0"/>',
};
function Icon({ name, size = 22, stroke = 2, fill, style, className }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
      stroke={fill ? 'none' : 'currentColor'} strokeWidth={stroke}
      strokeLinecap="round" strokeLinejoin="round"
      className={className} style={style}
      dangerouslySetInnerHTML={{ __html: PATHS[name] || '' }} />
  );
}

/* ---------- Animated number (count-up) ---------- */
function useCountUp(target, dur = 900, run = true) {
  const [v, setV] = useState(run ? 0 : target);
  useEffect(() => {
    if (!run) { setV(target); return; }
    let raf, t0;
    const step = (t) => {
      if (!t0) t0 = t;
      const p = Math.min(1, (t - t0) / dur);
      const e = 1 - Math.pow(1 - p, 3);
      setV(Math.round(target * e));
      if (p < 1) raf = requestAnimationFrame(step);
    };
    raf = requestAnimationFrame(step);
    // failsafe: if rAF is throttled/paused (page not visible), still land on target
    const safety = setTimeout(() => setV(target), dur + 250);
    return () => { cancelAnimationFrame(raf); clearTimeout(safety); };
  }, [target, run]);
  return v;
}
function fmtSum(n) { return n.toLocaleString('ru-RU').replace(/,/g, ' '); }

/* ---------- Progress ring ---------- */
function Ring({ value, size = 56, stroke = 6, color = 'var(--amber)', track = 'var(--surface-3)', children, run = true }) {
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const v = useCountUp(value, 1000, run);
  return (
    <div style={{ position: 'relative', width: size, height: size, flexShrink: 0 }}>
      <svg width={size} height={size} style={{ transform: 'rotate(-90deg)' }}>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={track} strokeWidth={stroke} />
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={color} strokeWidth={stroke}
          strokeLinecap="round" strokeDasharray={c}
          strokeDashoffset={c - (c * v) / 100}
          style={{ transition: 'stroke-dashoffset .25s linear' }} />
      </svg>
      <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', fontWeight: 700, fontSize: size * 0.26, color: 'var(--text)' }}>
        {children ?? `${v}%`}
      </div>
    </div>
  );
}

/* ---------- Avatar ---------- */
function Avatar({ size = 44, lang }) {
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%', flexShrink: 0,
      background: 'linear-gradient(140deg, var(--indigo-500), var(--indigo-700))',
      color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontWeight: 700, fontSize: size * 0.38, letterSpacing: '.5px',
      boxShadow: 'inset 0 0 0 1.5px rgba(255,255,255,.12)',
    }}>{lang === 'uz' ? PERSONA.initialsUz : PERSONA.initials}</div>
  );
}

/* ---------- Status bar ---------- */
function StatusBar() {
  return (
    <div style={{
      height: 38, display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      padding: '0 22px', color: 'var(--statusbar-ink)', flexShrink: 0, position: 'relative', zIndex: 5,
    }}>
      <span style={{ fontSize: 14, fontWeight: 600, letterSpacing: '.3px' }}>9:41</span>
      <div style={{
        position: 'absolute', left: '50%', top: 9, transform: 'translateX(-50%)',
        width: 11, height: 11, borderRadius: 99, background: '#05060c',
        boxShadow: 'inset 0 0 0 1.5px rgba(255,255,255,.08)',
      }} />
      <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
        <Icon name="voice" size={15} stroke={2.4} />
        <svg width="17" height="13" viewBox="0 0 17 13" fill="currentColor"><rect x="0" y="8" width="3" height="5" rx="1"/><rect x="4.5" y="5" width="3" height="8" rx="1"/><rect x="9" y="2.5" width="3" height="10.5" rx="1"/><rect x="13.5" y="0" width="3" height="13" rx="1" opacity=".35"/></svg>
        <svg width="24" height="13" viewBox="0 0 24 13" fill="none"><rect x="1" y="1.5" width="19" height="10" rx="2.5" stroke="currentColor" strokeWidth="1.3" opacity=".5"/><rect x="3" y="3.5" width="13" height="6" rx="1" fill="currentColor"/><rect x="21" y="4.5" width="1.6" height="4" rx="1" fill="currentColor" opacity=".5"/></svg>
      </div>
    </div>
  );
}

/* ---------- responsive scale ----------
   Desktop: capped at 0.87 (≈13% smaller, proportional on all sides).
   Mobile / small viewports: scaled down further so the whole 396×844
   mockup fits both width and height, no overflow. */
const PHONE_W = 396, PHONE_H = 844;
const DESKTOP_SCALE = 0.87;
function useAppScale() {
  const [scale, setScale] = useState(DESKTOP_SCALE);
  useEffect(() => {
    const calc = () => {
      const vw = window.innerWidth, vh = window.innerHeight;
      const pad = vw < 480 ? 12 : 24;          // per-side gutter, matches #root padding
      const fitW = (vw - pad * 2) / PHONE_W;
      const fitH = (vh - pad * 2) / PHONE_H;
      setScale(Math.max(0.3, Math.min(DESKTOP_SCALE, fitW, fitH)));
    };
    calc();
    window.addEventListener('resize', calc);
    window.addEventListener('orientationchange', calc);
    return () => {
      window.removeEventListener('resize', calc);
      window.removeEventListener('orientationchange', calc);
    };
  }, []);
  return scale;
}

/* ---------- Phone shell ---------- */
function Phone({ children, theme, overlay }) {
  const scale = useAppScale();
  return (
    <div style={{ width: PHONE_W * scale, height: PHONE_H * scale, flexShrink: 0 }}>
      <div style={{
        width: PHONE_W, height: PHONE_H, borderRadius: 46, padding: 4,
        transform: `scale(${scale})`, transformOrigin: 'top left',
        background: 'linear-gradient(160deg,#2a2f44,#0c0e18)',
        boxShadow: '0 40px 90px rgba(0,0,0,.55), 0 6px 18px rgba(0,0,0,.4), inset 0 0 0 1px rgba(255,255,255,.06)',
      }}>
        <div data-theme={theme} style={{
          width: '100%', height: '100%', borderRadius: 42, overflow: 'hidden',
          background: 'radial-gradient(120% 80% at 50% 0%, var(--bg-grad-a), var(--bg-grad-b))',
          display: 'flex', flexDirection: 'column', position: 'relative',
          color: 'var(--text)',
        }}>
          <StatusBar />
          <div style={{ flex: 1, minHeight: 0, position: 'relative', display: 'flex', flexDirection: 'column' }}>
            {children}
          </div>
          {overlay}
        </div>
      </div>
    </div>
  );
}

/* ---------- Gesture handle ---------- */
function GestureBar() {
  return (
    <div style={{ height: 22, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
      <div style={{ width: 128, height: 5, borderRadius: 3, background: 'var(--text)', opacity: .22 }} />
    </div>
  );
}

/* ---------- Bottom nav ---------- */
function BottomNav({ route, go, t }) {
  const items = [
    { key: 'stories', icon: 'n_stories', label: t.nav_stories },
    { key: 'jobs', icon: 'n_jobs', label: t.nav_jobs },
    { key: 'advisor', icon: 'n_advisor', label: t.nav_advisor, center: true },
    { key: 'growth', icon: 'n_growth', label: t.nav_growth },
    { key: 'profile', icon: 'n_profile', label: t.nav_profile },
  ];
  return (
    <div style={{
      flexShrink: 0,
      background: 'color-mix(in srgb, var(--surface) 86%, transparent)',
      backdropFilter: 'blur(18px)', WebkitBackdropFilter: 'blur(18px)',
      borderTop: '1px solid var(--border)',
    }}>
      <div style={{ display: 'flex', padding: '8px 8px 2px' }}>
        {items.map(it => {
          const active = route === it.key;
          if (it.center) {
            return (
              <button key={it.key} onClick={() => go(it.key)} style={{
                flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4, paddingTop: 2,
              }}>
                <div style={{
                  width: 52, height: 38, borderRadius: 16, marginTop: -14,
                  background: active ? 'linear-gradient(150deg,var(--amber-soft),var(--amber))' : 'linear-gradient(150deg,var(--indigo-500),var(--indigo-700))',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  color: active ? 'var(--indigo-900)' : '#fff',
                  boxShadow: active ? '0 8px 20px var(--amber-glow)' : '0 8px 18px rgba(20,29,58,.3)',
                  transition: 'all .3s var(--spring)',
                }}>
                  <Icon name={it.icon} size={22} stroke={2.2} />
                </div>
                <span style={{ fontSize: 10.5, fontWeight: 600, color: active ? 'var(--amber-deep)' : 'var(--text-3)' }}>{it.label}</span>
              </button>
            );
          }
          return (
            <button key={it.key} onClick={() => go(it.key)} style={{
              flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 5, padding: '6px 0',
              color: active ? 'var(--brand)' : 'var(--text-3)',
            }}>
              <Icon name={it.icon} size={23} stroke={active ? 2.4 : 1.9} fill={undefined} style={{ color: active ? 'var(--amber-deep)' : 'var(--text-3)', transform: active ? 'translateY(-1px)' : 'none', transition: 'all .25s var(--ease)' }} />
              <span style={{ fontSize: 10.5, fontWeight: active ? 700 : 500, color: active ? 'var(--text)' : 'var(--text-3)' }}>{it.label}</span>
            </button>
          );
        })}
      </div>
      <GestureBar />
    </div>
  );
}

/* ---------- Header (per screen) ---------- */
function Header({ title, sub, right, lang, setLang, theme, setTheme, t }) {
  return (
    <div style={{ padding: '6px 20px 12px', display: 'flex', alignItems: 'flex-start', gap: 12 }}>
      <div style={{ flex: 1, minWidth: 0 }}>
        {sub && <div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--amber-deep)', letterSpacing: '.2px', marginBottom: 3 }}>{sub}</div>}
        <h1 style={{ margin: 0, fontSize: 25, fontWeight: 800, letterSpacing: '-.5px', lineHeight: 1.1 }}>{title}</h1>
      </div>
      {right}
    </div>
  );
}

/* ---------- Lang/Theme quick toggles ---------- */
function QuickToggles({ lang, setLang, theme, setTheme }) {
  return (
    <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
      <button onClick={() => setLang(lang === 'ru' ? 'uz' : 'ru')} style={{
        height: 36, padding: '0 12px', borderRadius: 'var(--r-full)', display: 'flex', alignItems: 'center', gap: 6,
        background: 'var(--surface)', border: '1px solid var(--border)', color: 'var(--text-2)', fontWeight: 700, fontSize: 12.5,
        boxShadow: 'var(--shadow-1)',
      }}>
        <Icon name="globe" size={15} stroke={2} />
        {lang === 'ru' ? 'RU' : 'UZ'}
      </button>
      <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')} style={{
        width: 36, height: 36, borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center',
        background: 'var(--surface)', border: '1px solid var(--border)', color: 'var(--text-2)', boxShadow: 'var(--shadow-1)',
      }}>
        <Icon name={theme === 'light' ? 'moon' : 'sun'} size={17} stroke={2} />
      </button>
    </div>
  );
}

/* ---------- Skill bar ---------- */
function SkillBar({ skill, lang, delay = 0 }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
      <span style={{ fontSize: 13.5, fontWeight: 600, width: 96, flexShrink: 0 }}>{tr(skill, lang)}</span>
      <div style={{ flex: 1, height: 7, borderRadius: 99, background: 'var(--surface-3)', overflow: 'hidden' }}>
        <div style={{
          height: '100%', borderRadius: 99, transformOrigin: 'left',
          width: `${skill.lvl * 20}%`,
          background: 'linear-gradient(90deg,var(--indigo-500),var(--amber))',
          animation: `barGrow .8s var(--ease-out) ${delay}s both`,
        }} />
      </div>
    </div>
  );
}

/* ---------- Pill / chip ---------- */
function Chip({ children, active, onClick, accent, icon }) {
  return (
    <button onClick={onClick} style={{
      display: 'inline-flex', alignItems: 'center', gap: 6, height: 34, padding: '0 14px',
      borderRadius: 'var(--r-full)', fontSize: 13, fontWeight: 600, whiteSpace: 'nowrap',
      background: active ? (accent ? 'var(--amber)' : 'var(--brand)') : 'var(--surface)',
      color: active ? (accent ? 'var(--indigo-900)' : '#fff') : 'var(--text-2)',
      border: active ? '1px solid transparent' : '1px solid var(--border)',
      boxShadow: active ? 'var(--shadow-1)' : 'none', transition: 'all .2s var(--ease)',
    }}>
      {icon && <Icon name={icon} size={15} stroke={2.2} />}
      {children}
    </button>
  );
}

/* ---------- employer logo tile (monogram, brand colour) ---------- */
function Logo({ brand, size = 48, radius }) {
  const b = BRANDS[brand] || { short: '?', bg: 'var(--brand)' };
  const r = radius ?? Math.round(size * 0.28);
  const [err, setErr] = useState(false);
  // real logo file present → render image on a clean white tile, fall back
  // to the colour monogram if the asset fails to load.
  if (b.logo && !err) {
    return (
      <div style={{
        width: size, height: size, borderRadius: r, flexShrink: 0, overflow: 'hidden',
        background: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center',
        boxShadow: 'inset 0 0 0 1px rgba(20,29,58,.08), 0 2px 6px rgba(20,29,58,.12)',
      }}>
        <img src={`logos/${brand}.png`} alt={b.name} loading="lazy"
          onError={() => setErr(true)}
          style={{ width: '76%', height: '76%', objectFit: 'contain', display: 'block' }} />
      </div>
    );
  }
  return (
    <div style={{
      width: size, height: size, borderRadius: r, flexShrink: 0,
      background: b.bg, color: b.fg || '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontWeight: 800, fontSize: Math.round(size * 0.46), letterSpacing: '-.5px',
      boxShadow: 'inset 0 0 0 1.5px rgba(255,255,255,.14), 0 2px 6px rgba(20,29,58,.12)',
    }}>{b.short}</div>
  );
}
function brandName(brand) { return (BRANDS[brand] || {}).name || brand; }

/* ---------- app brand mark (rising path / growth) ---------- */
function BrandMark({ size = 72, animate = false, plain = false }) {
  const mark = (
    <svg width={plain ? size : size * 0.62} height={plain ? size : size * 0.62} viewBox="0 0 48 48" fill="none">
      <path d="M9 35 L20 24 L27 30 L39 14" stroke={plain ? 'var(--amber)' : '#fff'} strokeWidth="4.2" strokeLinecap="round" strokeLinejoin="round" />
      <circle cx="39" cy="14" r="4.6" fill="var(--amber)" />
      <circle cx="9" cy="35" r="3.4" fill={plain ? 'var(--indigo-400)' : 'rgba(255,255,255,.55)'} />
    </svg>
  );
  if (plain) return mark;
  return (
    <div style={{
      width: size, height: size, borderRadius: Math.round(size * 0.27), flexShrink: 0,
      background: 'linear-gradient(150deg, var(--indigo-500), var(--indigo-800))',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      boxShadow: '0 10px 26px rgba(20,29,58,.4), inset 0 0 0 1.5px rgba(255,255,255,.1)',
    }}>{mark}</div>
  );
}

Object.assign(window, { Icon, useCountUp, fmtSum, Ring, Avatar, StatusBar, Phone, GestureBar, BottomNav, Header, QuickToggles, SkillBar, Chip, Logo, brandName, BrandMark });
