const { useState, useEffect, useRef } = React;

// ============ CURSOR ============
function Cursor() {
  const dotRef = useRef(null);
  const ringRef = useRef(null);
  const pos = useRef({ x: 0, y: 0 });
  const target = useRef({ x: 0, y: 0 });

  useEffect(() => {
    const onMove = (e) => {
      target.current = { x: e.clientX, y: e.clientY };
      if (dotRef.current) {
        dotRef.current.style.transform = `translate(${e.clientX}px, ${e.clientY}px) translate(-50%,-50%)`;
      }
    };
    let raf;
    const tick = () => {
      pos.current.x += (target.current.x - pos.current.x) * 0.18;
      pos.current.y += (target.current.y - pos.current.y) * 0.18;
      if (ringRef.current) {
        ringRef.current.style.transform = `translate(${pos.current.x}px, ${pos.current.y}px) translate(-50%,-50%)`;
      }
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);

    const setHover = (on) => {
      if (dotRef.current) dotRef.current.classList.toggle('hover', on);
      if (ringRef.current) ringRef.current.classList.toggle('hover', on);
    };
    const onOver = (e) => {
      if (e.target.closest('a, button, .role, .brand-logo, .nav-link, .process-step')) setHover(true);
    };
    const onOut = (e) => {
      if (e.target.closest && e.target.closest('a, button, .role, .brand-logo, .nav-link, .process-step')) {
        if (!e.relatedTarget || !e.relatedTarget.closest || !e.relatedTarget.closest('a, button, .role, .brand-logo, .nav-link, .process-step')) {
          setHover(false);
        }
      }
    };
    window.addEventListener('mousemove', onMove);
    document.addEventListener('mouseover', onOver);
    document.addEventListener('mouseout', onOut);
    return () => {
      window.removeEventListener('mousemove', onMove);
      document.removeEventListener('mouseover', onOver);
      document.removeEventListener('mouseout', onOut);
      cancelAnimationFrame(raf);
    };
  }, []);

  return (
    <React.Fragment>
      <div ref={ringRef} className="cursor-ring"></div>
      <div ref={dotRef} className="cursor-dot"></div>
    </React.Fragment>
  );
}

// ============ REVEAL ON SCROLL ============
function useReveal() {
  useEffect(() => {
    const els = document.querySelectorAll('.reveal');
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          e.target.classList.add('in');
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.12 });
    els.forEach((el) => io.observe(el));
    return () => io.disconnect();
  }, []);
}

// ============ NAV ============
function Nav() {
  const [t, setT] = useState('');
  useEffect(() => {
    const update = () => {
      const d = new Date();
      // Dubai: UTC+4
      const utc = d.getTime() + d.getTimezoneOffset() * 60000;
      const dxb = new Date(utc + 4 * 3600 * 1000);
      const hh = String(dxb.getHours()).padStart(2, '0');
      const mm = String(dxb.getMinutes()).padStart(2, '0');
      const ss = String(dxb.getSeconds()).padStart(2, '0');
      setT(`${hh}:${mm}:${ss}`);
    };
    update();
    const i = setInterval(update, 1000);
    return () => clearInterval(i);
  }, []);

  return (
    <nav className="nav">
      <div className="nav-logo">
        <span className="nav-logo-mark"></span>
        <span>SCALEDBOX</span>
      </div>
      <div className="nav-links">
        <a href="#process" className="nav-link">Method</a>
        <a href="#roles" className="nav-link">Roles</a>
        <a href="#apply" className="nav-link">Apply</a>
      </div>
      <div className="nav-logo">
        <span className="status-dot"></span>
        <span className="dim">DXB</span>
        <span style={{ minWidth: '70px' }}>{t}</span>
      </div>
    </nav>
  );
}

// ============ HERO ============
function Hero() {
  return (
    <section className="hero">
      <div className="shell" style={{ width: '100%' }}>
        <div className="hero-meta">
          <div className="hero-meta-item">
            <span className="dim">[01]</span> Status
            <span><span className="status-dot" style={{ marginRight: 8 }}></span>Operational</span>
          </div>
          <div className="hero-meta-item">
            <span className="dim">[02]</span> Index
            <span>2025 — Year 03</span>
          </div>
          <div className="hero-meta-item">
            <span className="dim">[03]</span> Coordinates
            <span>25.20°N / 55.27°E</span>
          </div>
          <div className="hero-meta-item">
            <span className="dim">[04]</span> Discipline
            <span>Consumer brands · AI</span>
          </div>
        </div>

        <h1 className="display hero-headline" aria-label="We build consumer brands and scale them with machines that don't sleep.">
          <span className="line"><span>we build</span></span>
          <span className="line"><span><span className="hero-italic">brands.</span></span></span>
          <span className="line"><span>scaled by <span className="accent">/</span> machines.</span></span>
        </h1>

        <div className="hero-bottom">
          <p className="hero-manifesto reveal">
            <strong>Scaledbox</strong> is a private studio that conceives, launches and scales
            consumer brands with a small team and a deep stack of AI. Small inputs.
            Large outputs. We design the system, then let it run.
          </p>
          <div className="hero-cta reveal">
            <span className="dim">[ &mdash; ] Currently</span>
            <div className="hero-cta-num">hiring <em>one.</em></div>
            <span className="dim">video editor</span>
          </div>
        </div>
      </div>
    </section>
  );
}

// ============ TICKER ============
function Ticker() {
  const items = [
    'Now hiring — video editor',
    'Copywriter — closed',
    'Brand manager — closed',
    'Remote · global',
    'Based in Dubai',
    'Consumer brands · scaled with AI',
    'Apply by email',
  ];
  const row = (
    <span>
      {items.map((it, i) => (
        <React.Fragment key={i}>
          {it}
          <span className="dot"></span>
        </React.Fragment>
      ))}
    </span>
  );
  return (
    <div className="ticker">
      <div className="ticker-track">
        {row}{row}{row}
      </div>
    </div>
  );
}

// ============ PROCESS ============
function Process() {
  const steps = [
    { n: '01', label: 'Origination', title: 'Spot the gap', desc: 'Cultural pattern-matching. Margins, timing, and a category that doesn&rsquo;t know it&rsquo;s about to move.' },
    { n: '02', label: 'Construction', title: 'Build the body', desc: 'Brand world, product, supply, site, story. Engineered as one object, not assembled from parts.' },
    { n: '03', label: 'Ignition', title: 'Light it up', desc: 'AI-stitched creative pipelines. Hundreds of variants daily. We test, we cut, we recompound.' },
    { n: '04', label: 'Compounding', title: 'Make it loud', desc: 'Scale the winners. Kill the rest. Move the budget where the system tells us to move it.' },
  ];
  return (
    <section id="process" className="section">
      <div className="shell">
        <div className="section-label reveal">
          <span><span className="num">[02]</span> &nbsp;&nbsp; Method</span>
          <span className="title">// the four moves</span>
          <span>scaledbox.ops</span>
        </div>
        <h2 className="display section-h reveal">
          A studio that runs <br/>like an <em className="hero-italic accent">algorithm.</em>
        </h2>
      </div>
      <div className="shell">
        <div className="process">
          {steps.map((s, i) => (
            <div key={i} className="process-step reveal">
              <div className="process-step-num">{s.n} / {s.label}</div>
              <div className="process-num">{s.n}</div>
              <div className="process-title">{s.title}</div>
              <div className="process-desc" dangerouslySetInnerHTML={{ __html: s.desc }}></div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ============ MARQUEE BIG ============
function MarqueeBig() {
  const phrase = (
    <React.Fragment>
      <span>Quiet engines.</span>
      <span className="dot"></span>
      <span className="stroke">Loud results.</span>
      <span className="dot"></span>
      <span>Quiet engines.</span>
      <span className="dot"></span>
      <span className="stroke">Loud results.</span>
      <span className="dot"></span>
    </React.Fragment>
  );
  return (
    <div className="marquee-big">
      <div className="marquee-big-track">
        {phrase}{phrase}
      </div>
    </div>
  );
}

// ============ ROLES ============
const ROLES = [
  {
    n: '01',
    title: 'Copywriter',
    type: 'Full-time',
    location: 'Remote · Global',
    closed: true,
    blurb: 'Words that move money. Hooks, scripts, landers, emails. Volume and taste.',
    requirements: [
      'You write fast and rewrite faster',
      'Portfolio of DTC ads, scripts, or landing pages',
      'Comfort with AI tools as a force multiplier, not a crutch',
      'Native-level English. Other languages a plus.',
    ],
    you: [
      'Ship 30+ hooks a week without losing edge',
      'Translate a brand brief into a 60s spot in an hour',
      'Hold strong opinions about voice and punctuation',
      'Read more than you scroll',
    ],
  },
  {
    n: '02',
    title: 'Video Editor',
    type: 'Full-time',
    location: 'Remote · Global',
    blurb: 'Cuts that hold attention through second three. UGC, statics, motion, VSLs. All of it.',
    requirements: [
      'Premiere or CapCut. Doesn&rsquo;t matter, but you&rsquo;re fast in it',
      '2+ years cutting paid social creative',
      'Experience editing VSLs &mdash; pacing, retention, payoff',
      'Sound design instincts. Subtitle game tight.',
      'You understand a hook, a turn, a payoff',
    ],
    you: [
      'Output 20+ variants per concept per week',
      'Cut VSLs that convert past minute three',
      'Use AI for b-roll, voiceover, and rapid iteration',
      'Know which frame to start on without thinking',
      'Have opinions about cutting on the beat',
    ],
  },
  {
    n: '03',
    title: 'Brand Manager',
    type: 'Full-time',
    location: 'Remote · Global',
    closed: true,
    blurb: 'Own a brand end-to-end. Creative, ops, performance, story. CEO of the box.',
    requirements: [
      'You&rsquo;ve scaled a DTC brand past $1M before',
      'Comfort reading P&L, MER, CAC, and a creative brief in the same hour',
      'Manage editors, writers, designers without micromanaging',
      'Sharp taste. You know what good looks like, and you defend it.',
    ],
    you: [
      'Run a brand like it&rsquo;s yours',
      'Move between strategy and execution without ceremony',
      'Hold the line on quality when speed wants to win',
      'Build systems instead of doing the same thing twice',
    ],
  },
];

function Role({ role, i, open, onToggle }) {
  const isClosed = !!role.closed;
  return (
    <React.Fragment>
      <div
        className={`role ${isClosed ? 'closed' : ''}`}
        onClick={isClosed ? undefined : () => onToggle(i)}
        aria-disabled={isClosed || undefined}
      >
        <div className="role-num">[ {role.n} ]</div>
        <div className="role-title display">{role.title}</div>
        <div className="role-meta">
          <strong>{role.type}</strong>
          {isClosed ? 'Position closed' : role.location}
        </div>
        <div className="role-meta">
          <strong>{role.blurb.split('.')[0]}.</strong>
          {isClosed ? 'No longer accepting applications' : 'Tap to read brief'}
        </div>
        <div className="role-arrow">{isClosed ? '×' : (open ? '−' : '+')}</div>
      </div>
      {!isClosed && (
        <div className={`role-detail ${open ? 'open' : ''}`}>
          <div>
            <h4>// requirements</h4>
            <ul>
              {role.requirements.map((r, k) => (
                <li key={k} dangerouslySetInnerHTML={{ __html: r }}></li>
              ))}
            </ul>
          </div>
          <div>
            <h4>// you, in motion</h4>
            <ul>
              {role.you.map((r, k) => (
                <li key={k} dangerouslySetInnerHTML={{ __html: r }}></li>
              ))}
            </ul>
          </div>
        </div>
      )}
    </React.Fragment>
  );
}

function Roles() {
  const firstOpenIndex = ROLES.findIndex((r) => !r.closed);
  const [open, setOpen] = useState(firstOpenIndex);
  const toggle = (i) => setOpen(open === i ? -1 : i);
  return (
    <section id="roles" className="section">
      <div className="shell">
        <div className="section-label reveal">
          <span><span className="num">[03]</span> &nbsp;&nbsp; Open Positions</span>
          <span className="title">// 01 role · all remote</span>
          <span>now hiring</span>
        </div>
        <h2 className="display section-h reveal">
          We&rsquo;re looking <br/>for <em className="hero-italic accent">one</em> person.
        </h2>
        <div className="roles">
          {ROLES.map((r, i) => (
            <Role key={i} role={r} i={i} open={open === i} onToggle={toggle} />
          ))}
        </div>
      </div>
    </section>
  );
}

// ============ APPLY ============
function Apply() {
  return (
    <section id="apply" className="apply">
      <div className="shell">
        <div className="section-label reveal">
          <span><span className="num">[04]</span> &nbsp;&nbsp; Apply</span>
          <span className="title">// no forms, just a DM</span>
          <span>DM @william_labussiere on IG or @Willbuki on X</span>
        </div>
        <h1 className="apply-h reveal">
          send the <br/><span className="stroke">best thing</span> <br/>you&rsquo;ve made.
        </h1>
        <div className="apply-grid">
          <p className="apply-text reveal">
            No CV templates. No cover letters. Send one DM with three things:
            <br/><br/>
            <span className="accent">01</span> &nbsp; the role you want.<br/>
            <span className="accent">02</span> &nbsp; the single piece of work you&rsquo;re proudest of.<br/>
            <span className="accent">03</span> &nbsp; one sentence on why you.<br/><br/>
            We read every one. We reply to the ones that hit.
          </p>
          <div className="reveal" style={{ display: 'flex', justifyContent: 'flex-end', flexDirection: 'column', gap: '12px', alignItems: 'flex-end' }}>
            <a href="https://instagram.com/william_labussiere" target="_blank" rel="noopener noreferrer" className="apply-btn">
              <span>@william_labussiere on Instagram</span>
              <span className="arrow">→</span>
            </a>
            <a href="https://x.com/Willbuki" target="_blank" rel="noopener noreferrer" className="apply-btn">
              <span>@Willbuki on X</span>
              <span className="arrow">→</span>
            </a>
          </div>
        </div>
      </div>
    </section>
  );
}

// ============ FOOTER ============
function Footer() {
  return (
    <footer className="footer">
      <div className="shell">
        <div className="footer-mark"><span className="blink">SCALEDBOX</span></div>
        <div className="footer-row">
          <div className="footer-col">
            <strong>Studio</strong>
            <a href="#process">Method</a>
            <a href="#roles">Open Roles</a>
            <a href="#apply">Apply</a>
          </div>
          <div className="footer-col">
            <strong>Contact</strong>
            <a href="https://instagram.com/william_labussiere" target="_blank" rel="noopener noreferrer">@william_labussiere on Instagram</a>
            <a href="https://x.com/Willbuki" target="_blank" rel="noopener noreferrer">@Willbuki on X</a>
          </div>
          <div className="footer-col">
            <strong>Located</strong>
            <a>Dubai, UAE</a>
            <a>Operating: global</a>
          </div>
          <div className="footer-col">
            <strong>Index</strong>
            <a>Founded 2025</a>
            <a>Discipline: consumer</a>
            <a>Stack: AI-native</a>
          </div>
        </div>
        <div className="footer-bottom">
          <span>© 2026 scaledbox studio · dubai · global</span>
          <span>v.03 · 04.05.2026</span>
        </div>
      </div>
    </footer>
  );
}

// ============ APP ============
function App() {
  useReveal();
  return (
    <React.Fragment>
      <Cursor />
      <div className="grain"></div>
      <Nav />
      <Hero />
      <Ticker />
      <Process />
      <MarqueeBig />
      <Roles />
      <Apply />
      <Footer />
    </React.Fragment>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
