// Lumiscan — shared UI: nav, footer, icons, brand glyphs

const X_URL = "https://x.com/Lumiscansol";
const DISCORD_URL = "#";

// Tiny inline icon factory
const Icon = ({ name, size = 16, stroke = 1.6 }) => {
  const props = { width: size, height: size, viewBox: "0 0 24 24", fill: "none",
                  stroke: "currentColor", strokeWidth: stroke, strokeLinecap: "round", strokeLinejoin: "round" };
  switch (name) {
    case "x": return (
      <svg width={size} height={size} viewBox="0 0 24 24" fill="currentColor">
        <path d="M18.244 2H21l-6.52 7.451L22 22h-6.81l-4.77-6.247L4.8 22H2l7.06-8.07L2 2h6.92l4.31 5.7L18.244 2Zm-1.193 18.4h1.65L7.04 3.503H5.27L17.05 20.4Z"/>
      </svg>
    );
    case "discord": return (
      <svg width={size} height={size} viewBox="0 0 24 24" fill="currentColor">
        <path d="M20.317 4.37a19.79 19.79 0 0 0-4.885-1.515.07.07 0 0 0-.074.035c-.21.375-.444.864-.608 1.249a18.27 18.27 0 0 0-5.487 0 12.51 12.51 0 0 0-.617-1.25.077.077 0 0 0-.073-.034 19.74 19.74 0 0 0-4.885 1.515.07.07 0 0 0-.032.027C.533 9.046-.319 13.58.1 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.1 13.1 0 0 1-1.872-.892.077.077 0 0 1-.008-.128c.126-.094.252-.192.372-.291a.074.074 0 0 1 .078-.01c3.927 1.793 8.18 1.793 12.061 0a.074.074 0 0 1 .078.01c.12.099.246.198.373.292a.077.077 0 0 1-.006.127 12.3 12.3 0 0 1-1.873.892.077.077 0 0 0-.04.106c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.84 19.84 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.548-13.66a.061.061 0 0 0-.031-.028ZM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.42 0-1.333.956-2.418 2.157-2.418 1.21 0 2.176 1.094 2.157 2.418 0 1.335-.956 2.42-2.157 2.42Zm7.974 0c-1.183 0-2.157-1.085-2.157-2.42 0-1.333.955-2.418 2.157-2.418 1.21 0 2.176 1.094 2.157 2.418 0 1.335-.946 2.42-2.157 2.42Z"/>
      </svg>
    );
    case "arrow": return <svg {...props}><path d="M5 12h14M13 5l7 7-7 7"/></svg>;
    case "play": return <svg {...props}><polygon points="5 3 19 12 5 21 5 3" fill="currentColor"/></svg>;
    case "shield": return <svg {...props}><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10Z"/></svg>;
    case "scan": return <svg {...props}><path d="M3 7V5a2 2 0 0 1 2-2h2M17 3h2a2 2 0 0 1 2 2v2M21 17v2a2 2 0 0 1-2 2h-2M7 21H5a2 2 0 0 1-2-2v-2M7 12h10"/></svg>;
    case "db": return <svg {...props}><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5v6c0 1.66 4 3 9 3s9-1.34 9-3V5M3 11v6c0 1.66 4 3 9 3s9-1.34 9-3v-6"/></svg>;
    case "hub": return <svg {...props}><circle cx="12" cy="12" r="3"/><circle cx="12" cy="3" r="2"/><circle cx="12" cy="21" r="2"/><circle cx="3" cy="12" r="2"/><circle cx="21" cy="12" r="2"/><path d="M12 5v4M12 15v4M5 12h4M15 12h4"/></svg>;
    case "doc": return <svg {...props}><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6M8 13h8M8 17h5"/></svg>;
    case "code": return <svg {...props}><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>;
    case "check": return <svg {...props}><polyline points="20 6 9 17 4 12"/></svg>;
    case "alert": return <svg {...props}><circle cx="12" cy="12" r="10"/><path d="M12 8v4M12 16h.01"/></svg>;
    case "zap": return <svg {...props}><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" fill="currentColor" stroke="none"/></svg>;
    case "globe": return <svg {...props}><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15.3 15.3 0 0 1 0 20M12 2a15.3 15.3 0 0 0 0 20"/></svg>;
    case "search": return <svg {...props}><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></svg>;
    case "menu": return <svg {...props}><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>;
    default: return null;
  }
};

// Brand glyph — italic serif letter in a coloured tile
const BrandIco = ({ letters, color = "green", size = "sm" }) => (
  <span className={`brand-ico ${color} ${size === "lg" ? "lg" : ""}`}>{letters}</span>
);

// Solana wordmark style logo (italic serif)
const Logo = ({ size = 24 }) => (
  <span className="nav-logo" style={{ fontSize: size + "px" }}>
    lumiscan<span className="dot">.</span>
  </span>
);

const NAV_ITEMS = [
  { label: "Docs",       href: "docs.html",      letters: "Dc" },
  { label: "AgentScan",  href: "index.html#agentscan", letters: "As", color: "green" },
  { label: "RepoScan",   href: "index.html#reposcan",  letters: "Rs", color: "green" },
  { label: "Registry",   href: "index.html#registry",  letters: "Rg", color: "purple" },
  { label: "ProviderHub",href: "index.html#providerhub", letters: "Ph", color: "purple" },
];

const Nav = ({ active }) => (
  <nav className="nav">
    <div className="wrap nav-inner">
      <a href="index.html" style={{display:"flex",alignItems:"center"}}><Logo /></a>
      <div className="nav-links">
        {NAV_ITEMS.map(item => (
          <a key={item.label} href={item.href} className="nav-link"
             style={active === item.label ? { color: "var(--text)" } : {}}>
            <span className="ico" style={{
              color: item.color === "purple" ? "#c79bff" : item.color === "green" ? "var(--green)" : "var(--text-dim)"
            }}>{item.letters}</span>
            {item.label}
          </a>
        ))}
      </div>
      <div className="nav-right">
        <a className="icon-btn" href={X_URL} target="_blank" rel="noreferrer" aria-label="X"><Icon name="x" size={15}/></a>
        <a className="icon-btn" href={DISCORD_URL} aria-label="Discord"><Icon name="discord" size={17}/></a>
        <a className="btn btn-ghost btn-sm" href="app.html" style={{marginLeft:6}}>
          <Icon name="zap" size={13}/> Launch App
        </a>
      </div>
    </div>
  </nav>
);

const Footer = () => (
  <footer className="footer">
    <div className="wrap">
      <div className="footer-grid">
        <div>
          <Logo size={22} />
          <p className="muted" style={{marginTop:14, maxWidth:340}}>
            The trust layer for the Solana agent economy. Audit code,
            verify identity, monitor endpoints — before agents transact.
          </p>
          <div style={{display:"flex",gap:8,marginTop:18}}>
            <a className="icon-btn" href={X_URL} target="_blank" rel="noreferrer" aria-label="X"><Icon name="x" size={14}/></a>
            <a className="icon-btn" href={DISCORD_URL} aria-label="Discord"><Icon name="discord" size={16}/></a>
          </div>
        </div>
        <div className="footer-col">
          <div className="footer-col-h">Products</div>
          <a href="index.html#agentscan">AgentScan</a>
          <a href="index.html#reposcan">RepoScan</a>
          <a href="index.html#registry">Registry</a>
          <a href="index.html#providerhub">ProviderHub</a>
          <a href="app.html">Launch App</a>
        </div>
        <div className="footer-col">
          <div className="footer-col-h">Developers</div>
          <a href="docs.html">Documentation</a>
          <a href="sdk.html">SDK Reference</a>
          <a href="docs.html#api">API</a>
          <a href="docs.html#cli">CLI</a>
          <a href="sdk.html#examples">Examples</a>
        </div>
        <div className="footer-col">
          <div className="footer-col-h">Company</div>
          <a href={X_URL} target="_blank" rel="noreferrer">Twitter / X</a>
          <a href={DISCORD_URL}>Discord</a>
          <a href="#">Press</a>
          <a href="#">Brand kit</a>
          <a href="#">Contact</a>
        </div>
      </div>
      <div className="footer-bottom">
        <span>© 2026 Lumiscan Labs. All rights reserved.</span>
        <span className="mono">v0.42.0 · mainnet-beta · <span className="live-dot" style={{marginLeft:6,marginRight:6,verticalAlign:"middle"}}></span> all systems nominal</span>
      </div>
    </div>
  </footer>
);

// Reveal-on-scroll wrapper
const Reveal = ({ children, delay = 0, as: As = "div", className = "", ...rest }) => {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current; if (!el) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          setTimeout(() => el.classList.add("in"), delay);
          io.unobserve(el);
        }
      });
    }, { threshold: 0.15 });
    io.observe(el);
    return () => io.disconnect();
  }, [delay]);
  return <As ref={ref} className={`reveal ${className}`} {...rest}>{children}</As>;
};

// Animated counter
const Counter = ({ to, prefix = "", suffix = "", duration = 1800, className = "" }) => {
  const [v, setV] = React.useState(0);
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current; if (!el) return;
    const io = new IntersectionObserver((entries) => {
      if (!entries[0].isIntersecting) return;
      io.disconnect();
      const start = performance.now();
      const step = (t) => {
        const p = Math.min(1, (t - start) / duration);
        const eased = 1 - Math.pow(1 - p, 3);
        setV(Math.floor(to * eased));
        if (p < 1) requestAnimationFrame(step);
      };
      requestAnimationFrame(step);
    }, { threshold: 0.4 });
    io.observe(el);
    return () => io.disconnect();
  }, [to, duration]);
  const fmt = (n) => n.toLocaleString("en-US").replace(/,/g, ".");
  return <span ref={ref} className={className}>{prefix}{fmt(v)}{suffix}</span>;
};

// Particle field
const Particles = ({ count = 40 }) => {
  const items = React.useMemo(() =>
    Array.from({length: count}, () => ({
      left: Math.random() * 100,
      top: Math.random() * 100,
      dx: (Math.random() - 0.5) * 80,
      dy: -Math.random() * 200 - 50,
      delay: Math.random() * 12,
      duration: 8 + Math.random() * 14,
      size: Math.random() * 2 + 1,
      opacity: Math.random() * 0.5 + 0.2,
    })), [count]);
  return (
    <div className="particles" aria-hidden="true">
      {items.map((p, i) => (
        <span key={i} className="particle" style={{
          left: p.left + "%", top: p.top + "%",
          width: p.size + "px", height: p.size + "px",
          opacity: p.opacity,
          "--dx": p.dx + "px", "--dy": p.dy + "px",
          animationDelay: p.delay + "s",
          animationDuration: p.duration + "s",
        }}/>
      ))}
    </div>
  );
};

Object.assign(window, { Icon, BrandIco, Logo, Nav, Footer, Reveal, Counter, Particles, X_URL, DISCORD_URL });
