// Shared design tokens and primitives for the Daniel Urdaneta site
// Paper aesthetic — warm parchment, ink, ochre

const tokens = {
  bg: '#F4F1EA',
  bgAlt: '#EDE9DF',
  ink: '#0E0E0C',
  inkSoft: 'rgba(14,14,12,0.7)',
  inkMute: 'rgba(14,14,12,0.5)',
  inkLine: 'rgba(14,14,12,0.12)',
  inkLineSoft: 'rgba(14,14,12,0.06)',
  ochre: '#C9A24A',
  green: '#5A7A3E',
  red: '#A04A3E',
  paper: '#FBFAF6',
};

const fontDisplay = '"Inter Tight", "Inter", system-ui, sans-serif';
const fontBody = '"Inter", system-ui, sans-serif';
const fontMono = '"JetBrains Mono", monospace';

// ── Roles ─────────────────────────────────────────────────────────────────────
// owner      — the real account, full powers.
// demo_live  — shareable demo: edits the private shelves + For Me like the owner,
//              can run AI research. For Me tickers are its own copy (user-scoped).
// demo_view  — shareable demo: sees everything, can add/edit, but cannot run AI
//              research and cannot delete anything (also enforced server-side).
// guest      — any other signed-in user: public pages only.
const getRole = (user) => {
  const e = user && user.email ? user.email.toLowerCase() : '';
  if (!e) return 'guest';
  if (window.SITE_OWNER_EMAIL && e === window.SITE_OWNER_EMAIL.toLowerCase()) return 'owner';
  if (window.SITE_DEMO_LIVE_EMAIL && e === window.SITE_DEMO_LIVE_EMAIL.toLowerCase()) return 'demo_live';
  if (window.SITE_DEMO_VIEW_EMAIL && e === window.SITE_DEMO_VIEW_EMAIL.toLowerCase()) return 'demo_view';
  return 'guest';
};
window.getRole = getRole;

// ── Dynamic access (site_access table, managed from the Admin page) ───────────
// The owner controls — per authorized email — which private pages are visible
// and whether they're full-access or read-only. Built-in owner/demo accounts
// keep their existing behavior; any other email is resolved from its
// `site_access` row. The private *generic* pages (home/about/…) stay public to
// any signed-in user; site_access governs the private shelves + For Me.
const PRIVATE_PAGES = ['objects', 'ideas', 'places', 'forme'];

const resolveAccess = (user, row) => {
  const role = getRole(user);
  let priv = [], level = 'read';
  if (role === 'owner')          { priv = PRIVATE_PAGES.slice(); level = 'full'; }
  else if (role === 'demo_live') { priv = PRIVATE_PAGES.slice(); level = 'full'; }
  else if (role === 'demo_view') { priv = PRIVATE_PAGES.slice(); level = 'read'; }
  else if (row && row.active)    { priv = Array.isArray(row.pages) ? row.pages : []; level = row.access_level === 'full' ? 'full' : 'read'; }
  return { role, isOwner: role === 'owner', priv: new Set(priv), level, ready: true };
};
window.resolveAccess = resolveAccess;

// Fetch + resolve the current user's access (queries site_access only for
// non-built-in accounts). Returns the resolved access object.
const loadSiteAccess = async (user) => {
  const role = getRole(user);
  let row = null;
  if (role === 'guest' && user && user.email && window._supabaseClient) {
    try {
      const { data } = await window._supabaseClient
        .from('site_access')
        .select('pages, access_level, active')
        .eq('email', user.email.toLowerCase())
        .maybeSingle();
      row = data || null;
    } catch { row = null; }
  }
  return resolveAccess(user, row);
};
window.loadSiteAccess = loadSiteAccess;

// Publish the resolved access to window so deep components can guard cheaply.
const applySiteAccess = (access) => {
  window.SITE_ACCESS_RESOLVED = access;
  window.SITE_ACCESS_LEVEL = access.level;     // 'full' | 'read'
  window.siteCanSee   = (p) => access.isOwner || access.priv.has(p);
  window.siteCanWrite = (p) => access.isOwner || (access.priv.has(p) && access.level === 'full');
};
window.applySiteAccess = applySiteAccess;

// Convenience guards read by deep components. Honor BOTH the demo_view role and
// a resolved read-only access level (invited read-only emails).
const roleCanResearch = () => window.SITE_ROLE !== 'demo_view' && window.SITE_ACCESS_LEVEL !== 'read';
const roleCanDelete = () => window.SITE_ROLE !== 'demo_view' && window.SITE_ACCESS_LEVEL !== 'read';
// For Me ticker management (add / edit / remove tickers) — full-access only.
const roleCanManageTickers = () => window.SITE_ROLE !== 'demo_view' && window.SITE_ACCESS_LEVEL !== 'read';
const DEMO_BLOCK_MSG = 'This action is disabled on a read-only login. (AI research, edits, and deletions need full access.)';

// Top navigation — sticky, minimal
const Nav = ({ route, setRoute, isOwner, access }) => {
  const isMobile = useIsMobile();
  const role = window.SITE_ROLE || (isOwner ? 'owner' : 'guest');
  const acc = access || window.SITE_ACCESS_RESOLVED || resolveAccess({ email: role === 'owner' ? window.SITE_OWNER_EMAIL : '' }, null);
  const isDemo = role === 'demo_live' || role === 'demo_view';
  const generic = [
    { id: 'home', label: 'Home' },
    { id: 'about', label: 'About Me' },
    { id: 'investments', label: 'Investments' },
    { id: 'thesis', label: 'Innovation Activism' },
  ];
  const privAll = [
    { id: 'objects', label: 'Objects' },
    { id: 'ideas', label: 'Ideas' },
    { id: 'places', label: 'Places' },
    { id: 'forme', label: 'For Me' },
  ];
  const priv = privAll.filter((p) => acc.priv.has(p.id));
  // Private-only visitors (demo accounts + invited emails granted only private
  // shelves) see ONLY their granted shelves; owner sees everything + Admin; a
  // plain signed-in guest sees the generic pages.
  const privateOnly = isDemo || (role === 'guest' && priv.length > 0);
  const items = role === 'owner'
    ? [...generic, ...priv, { id: 'admin', label: 'Admin' }]
    : privateOnly ? priv : generic;
  const homeRoute = privateOnly ? (priv[0] ? priv[0].id : 'home') : 'home';

  const brand = (
    <a onClick={() => setRoute(homeRoute)} style={{ cursor: 'pointer', fontWeight: 500, letterSpacing: '-0.02em', fontSize: '15px', display: 'flex', alignItems: 'center', gap: '10px', flexShrink: 0 }}>
      <span style={{ width: '18px', height: '18px', border: `1px solid ${tokens.ink}`, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', fontFamily: fontMono, fontSize: '9px' }}>DU</span>
      Daniel Urdaneta
    </a>
  );
  const contact = (
    <a onClick={() => setRoute('contact')} style={{ cursor: 'pointer', fontFamily: fontMono, fontSize: '11px', color: tokens.inkMute, letterSpacing: '0.06em', flexShrink: 0, whiteSpace: 'nowrap' }}>
      CONTACT →
    </a>
  );
  const links = (
    <div style={{
      display: 'flex', gap: isMobile ? '20px' : 'clamp(14px, 2.2vw, 32px)',
      color: tokens.inkSoft, letterSpacing: '0.005em',
      flexWrap: isMobile ? 'nowrap' : 'wrap',
      justifyContent: isMobile ? 'flex-start' : 'center',
      overflowX: isMobile ? 'auto' : 'visible',
      WebkitOverflowScrolling: 'touch',
      msOverflowStyle: 'none', scrollbarWidth: 'none',
      padding: isMobile ? '2px 0' : 0,
    }}>
      {items.map(it => (
        <a key={it.id} onClick={() => setRoute(it.id)} style={{
          cursor: 'pointer',
          color: route === it.id || (route.startsWith && route.startsWith(it.id)) ? tokens.ink : tokens.inkSoft,
          fontWeight: route === it.id ? 500 : 400,
          whiteSpace: 'nowrap',
        }}>{it.label}</a>
      ))}
    </div>
  );

  const navBase = {
    position: 'sticky', top: 0, zIndex: 50,
    background: 'rgba(244,241,234,0.85)',
    backdropFilter: 'blur(12px)', WebkitBackdropFilter: 'blur(12px)',
    borderBottom: `1px solid ${tokens.inkLine}`,
    fontFamily: fontDisplay, fontSize: '13px',
  };

  if (isMobile) {
    return (
      <nav style={{ ...navBase, display: 'flex', flexDirection: 'column', gap: '10px', padding: '12px 16px' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          {brand}
          {contact}
        </div>
        {links}
      </nav>
    );
  }

  return (
    <nav style={{ ...navBase, display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: 'clamp(16px, 1.6vw, 20px) clamp(24px, 4vw, 56px)', gap: '16px' }}>
      {brand}
      {links}
      <div style={{ marginLeft: '8px' }}>{contact}</div>
    </nav>
  );
};

const Footer = ({ setRoute, signOut, user }) => (
  <footer style={{
    borderTop: `1px solid ${tokens.inkLine}`,
    padding: '56px 56px 40px',
    background: tokens.bgAlt,
    fontFamily: fontDisplay,
  }}>
    <div style={{ display: 'grid', gridTemplateColumns: '2fr 1fr 1fr 1fr', gap: '48px', marginBottom: '64px' }}>
      <div>
        <div style={{ fontSize: '24px', letterSpacing: '-0.03em', maxWidth: '420px', lineHeight: 1.25 }}>
          {(getRole(user) === 'demo_live' || getRole(user) === 'demo_view')
            ? 'A private collection — objects, ideas & places.'
            : 'A technology investor practicing innovation activism.'}
        </div>
        <div style={{ marginTop: '24px', fontFamily: fontMono, fontSize: '11px', color: tokens.inkMute, letterSpacing: '0.06em', lineHeight: 1.7 }}>
          PRIVATE EQUITY · PUBLIC MARKETS · VENTURE<br/>
          LAST UPDATED APR 2026
        </div>
      </div>
      <div>
        <div style={{ fontFamily: fontMono, fontSize: '10px', letterSpacing: '0.18em', color: tokens.inkMute, marginBottom: '12px' }}>SITE</div>
        {(() => {
          const r = getRole(user);
          const isDemo = r === 'demo_live' || r === 'demo_view';
          const generic = [['About Me','about'], ['Innovation Activism','thesis'], ['Investments','investments']];
          const priv = [['Objects','objects'], ['Ideas','ideas'], ['Places','places']];
          // Demos see only the private shelves; owner sees both; guest sees generic.
          return isDemo ? priv : (r === 'owner' ? [...generic, ...priv] : generic);
        })().map(([label, id]) => (
          <div key={id} style={{ fontSize: '13px', padding: '4px 0', cursor: 'pointer' }} onClick={() => setRoute(id)}>{label}</div>
        ))}
      </div>
      <div>
        <div style={{ fontFamily: fontMono, fontSize: '10px', letterSpacing: '0.18em', color: tokens.inkMute, marginBottom: '12px' }}>ELSEWHERE</div>
        <a href="https://www.linkedin.com/in/daniel-urdaneta-992a2510/" target="_blank" rel="noopener noreferrer" style={{ display: 'block', fontSize: '13px', padding: '4px 0', textDecoration: 'none', color: tokens.ink }}>LinkedIn ↗</a>
        <a href="https://twitter.com/DUrdaneta" target="_blank" rel="noopener noreferrer" style={{ display: 'block', fontSize: '13px', padding: '4px 0', textDecoration: 'none', color: tokens.ink }}>Twitter / X ↗</a>
        <a href="https://vimeo.com/1187373736" target="_blank" rel="noopener noreferrer" style={{ display: 'block', fontSize: '13px', padding: '4px 0', textDecoration: 'none', color: tokens.ink }}>Vimeo ↗</a>
      </div>
      <div>
        <div style={{ fontFamily: fontMono, fontSize: '10px', letterSpacing: '0.18em', color: tokens.inkMute, marginBottom: '12px' }}>CONTACT</div>
        <div style={{ fontSize: '13px', padding: '4px 0' }}>daniel@urdaneta.io</div>
        <div style={{ fontSize: '13px', padding: '4px 0', color: tokens.inkMute }}>For inbound ideas, press, or speaking.</div>
      </div>
    </div>
    <div style={{ borderTop: `1px solid ${tokens.inkLine}`, paddingTop: '24px', display: 'flex', justifyContent: 'space-between', fontFamily: fontMono, fontSize: '10px', letterSpacing: '0.08em', color: tokens.inkMute }}>
      <span>© 2026 DANIEL URDANETA. ALL VIEWS PERSONAL — NOT INVESTMENT ADVICE.</span>
      <span style={{ display: 'flex', gap: '20px', alignItems: 'center' }}>
        {user && user.email && <span>SIGNED IN · {user.email.toUpperCase()}</span>}
        {signOut && <span style={{ cursor: 'pointer', borderBottom: `1px solid ${tokens.inkLine}`, paddingBottom: '2px' }} onClick={signOut}>SIGN OUT</span>}
        <span>v.2026.04</span>
      </span>
    </div>
  </footer>
);

// Viewport hook — drives responsive layout switches in inline-styled components
const useIsMobile = (bp = 760) => {
  const query = `(max-width: ${bp}px)`;
  const [isMobile, setIsMobile] = React.useState(
    () => (typeof window !== 'undefined' && window.matchMedia ? window.matchMedia(query).matches : false)
  );
  React.useEffect(() => {
    if (!window.matchMedia) return;
    const mq = window.matchMedia(query);
    const handler = (e) => setIsMobile(e.matches);
    setIsMobile(mq.matches);
    mq.addEventListener ? mq.addEventListener('change', handler) : mq.addListener(handler);
    return () => { mq.removeEventListener ? mq.removeEventListener('change', handler) : mq.removeListener(handler); };
  }, [query]);
  return isMobile;
};

// Standardized section container
const Section = ({ children, label, title, sub, style }) => {
  const isMobile = useIsMobile();
  return (
    <section style={{ padding: isMobile ? '56px 18px' : '120px 56px', borderBottom: `1px solid ${tokens.inkLine}`, ...style }}>
      {(label || title) && (
        <div style={{ marginBottom: isMobile ? '36px' : '64px' }}>
          {label && <div style={{ fontFamily: fontMono, fontSize: '11px', letterSpacing: '0.18em', color: tokens.inkMute, marginBottom: isMobile ? '14px' : '20px', textTransform: 'uppercase' }}>{label}</div>}
          {title && <h2 style={{ fontSize: isMobile ? '32px' : '52px', lineHeight: 1.05, letterSpacing: '-0.04em', fontWeight: 400, margin: 0, maxWidth: '900px' }}>{title}</h2>}
          {sub && <p style={{ fontSize: isMobile ? '15px' : '17px', color: tokens.inkSoft, lineHeight: 1.5, marginTop: isMobile ? '16px' : '24px', maxWidth: '640px', letterSpacing: '-0.005em' }}>{sub}</p>}
        </div>
      )}
      {children}
    </section>
  );
};

// Striped placeholder — for media we don't have real assets for
const Placeholder = ({ label, height = 240, ratio }) => (
  <div style={{
    height: ratio ? undefined : height,
    aspectRatio: ratio,
    width: '100%',
    background: `repeating-linear-gradient(45deg, ${tokens.bgAlt} 0 1px, transparent 1px 12px), ${tokens.paper}`,
    border: `1px solid ${tokens.inkLine}`,
    display: 'flex', alignItems: 'center', justifyContent: 'center',
    fontFamily: fontMono, fontSize: '11px', letterSpacing: '0.16em',
    color: tokens.inkMute, textTransform: 'uppercase',
  }}>
    {label}
  </div>
);

window.useIsMobile = useIsMobile;
window.tokens = tokens;
window.fontDisplay = fontDisplay;
window.fontBody = fontBody;
window.fontMono = fontMono;
window.Nav = Nav;
window.Footer = Footer;
window.Section = Section;
window.Placeholder = Placeholder;
