/* Before/After comparison slider — drag to reveal manual scraping setup vs Unblocker */

const { useState: useStateC, useRef: useRefC, useEffect: useEffectC, useCallback: useCallbackC } = React;

/* ---------- the two code samples ---------- */
const BEFORE_CODE = `// scrape azure.microsoft.com/pricing — without Unblocker
import { chromium } from "playwright";
import { getRotatingProxy } from "./proxy-pool";
import { solveHcaptcha } from "./captcha-solver";
import { randomFingerprint, USER_AGENTS } from "./fingerprints";

const EVASION_SCRIPT = \`
  Object.defineProperty(navigator, "webdriver", { get: () => undefined });
  Object.defineProperty(navigator, "plugins", { get: () => [1,2,3,4,5] });
  Object.defineProperty(navigator, "languages", { get: () => ["en-US","en"] });
  window.chrome = { runtime: {}, loadTimes: () => ({}), csi: () => ({}) };
  const origQuery = window.navigator.permissions.query;
  window.navigator.permissions.query = (p) => p.name === "notifications"
    ? Promise.resolve({ state: Notification.permission }) : origQuery(p);
  // ... 180 more lines of fingerprint patching ...
\`;

async function scrape(url, maxRetries = 8) {
  let lastError = "";
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const proxy = await getRotatingProxy({ country: "US", residential: true });
    const fp = randomFingerprint();
    const browser = await chromium.launch({
      headless: true,
      proxy: { server: proxy.url, username: proxy.user, password: proxy.pwd },
      args: [
        "--disable-blink-features=AutomationControlled",
        "--disable-features=IsolateOrigins,site-per-process",
        "--disable-site-isolation-trials",
      ],
    });
    const ctx = await browser.newContext({
      userAgent: USER_AGENTS[Math.floor(Math.random() * USER_AGENTS.length)],
      viewport: fp.viewport,
      locale: fp.locale,
      timezoneId: fp.timezone,
      extraHTTPHeaders: fp.headers,
    });
    await ctx.addInitScript(EVASION_SCRIPT);
    const page = await ctx.newPage();
    try {
      await page.waitForTimeout(800 + Math.random() * 1700);
      const resp = await page.goto(url, { waitUntil: "domcontentloaded", timeout: 45000 });
      if (!resp || resp.status() >= 400) {
        lastError = "status " + (resp ? resp.status() : "none");
        continue;
      }
      // Cloudflare interstitial — wait it out
      if ((await page.title()).includes("Just a moment")) {
        await page.waitForLoadState("networkidle", { timeout: 20000 });
      }
      // DataDome "Access Denied"
      if (await page.locator("text=Access Denied").count()) {
        lastError = "datadome blocked";
        continue;
      }
      // hCaptcha — solve it ($$$)
      const cap = page.locator("iframe[src*='hcaptcha']");
      if (await cap.count()) {
        const sk = await cap.first().getAttribute("data-sitekey");
        const token = await solveHcaptcha(sk, url);
        await page.evaluate("hcaptcha.execute('" + token + "')");
        await page.waitForTimeout(3000);
      }
      const html = await page.content();
      if (/captcha/i.test(html) || html.length < 5000) {
        lastError = "captcha leaked or empty body";
        continue;
      }
      await browser.close();
      return html;
    } catch (e) {
      lastError = e.message;
      await new Promise(r => setTimeout(r, Math.pow(2, attempt) * 1000));
    } finally {
      await browser.close().catch(() => {});
    }
  }
  throw new Error("All " + maxRetries + " retries failed: " + lastError);
}

const html = await scrape("https://azure.microsoft.com/api/v3/pricing/virtual-machines/page/details/windows/");`;

const AFTER_CODE = `// scrape azure.microsoft.com/pricing — with Unblocker
const res = await fetch("https://unblocker.usestring.ai/unblock", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    url: "https://azure.microsoft.com/api/v3/pricing/virtual-machines/page/details/windows/"
  })
});

const { html } = await res.json();
// done.`;

/* ---------- naive token highlighter ---------- */
const KEYWORDS = new Set([
  "const","let","var","async","await","function","return","if","else","for","while",
  "try","catch","finally","throw","new","import","from","export","default","class",
  "extends","this","true","false","null","undefined","continue","break","in","of",
  "typeof","instanceof","void"
]);

function tokenize(line) {
  const out = [];
  let r = line;
  while (r.length) {
    let m;
    if ((m = r.match(/^(\/\/.*$|#.*$)/))) out.push(["c-c", m[0]]);
    else if ((m = r.match(/^"(?:[^"\\]|\\.)*"/))) out.push(["c-s", m[0]]);
    else if ((m = r.match(/^'(?:[^'\\]|\\.)*'/))) out.push(["c-s", m[0]]);
    else if ((m = r.match(/^`(?:[^`\\]|\\.)*`/))) out.push(["c-s", m[0]]);
    else if ((m = r.match(/^\d+(?:\.\d+)?/))) out.push(["c-n", m[0]]);
    else if ((m = r.match(/^[A-Za-z_$][A-Za-z0-9_$]*/))) {
      const w = m[0];
      if (KEYWORDS.has(w)) out.push(["c-k", w]);
      else if (/^[A-Z]/.test(w)) out.push(["c-n", w]);
      else if (r.slice(w.length).startsWith("(")) out.push(["c-f", w]);
      else out.push(["", w]);
    } else {
      m = [r[0]];
      out.push(["", m[0]]);
    }
    r = r.slice(m[0].length);
  }
  return out;
}

function HighlightedCode({ code }) {
  const lines = code.split("\n");
  return (
    <>
      {lines.map((line, i) => (
        <div key={i} className="ba-line">
          {tokenize(line).map(([cls, txt], j) =>
            cls ? <span key={j} className={cls}>{txt}</span> : <span key={j}>{txt}</span>
          )}
          {line.length === 0 ? "\u00A0" : null}
        </div>
      ))}
    </>
  );
}

/* ---------- the slider component ---------- */
function BeforeAfterSlider() {
  const [pos, setPos] = useStateC(50);
  const [dragging, setDragging] = useStateC(false);
  const containerRef = useRefC(null);

  const setFromClientX = useCallbackC((clientX) => {
    const el = containerRef.current;
    if (!el) return;
    const rect = el.getBoundingClientRect();
    const pct = ((clientX - rect.left) / rect.width) * 100;
    setPos(Math.max(0, Math.min(100, pct)));
  }, []);

  useEffectC(() => {
    if (!dragging) return;
    const onMove = (e) => {
      const x = e.touches ? e.touches[0].clientX : e.clientX;
      setFromClientX(x);
      e.preventDefault();
    };
    const onUp = () => setDragging(false);
    window.addEventListener("pointermove", onMove);
    window.addEventListener("pointerup", onUp);
    window.addEventListener("pointercancel", onUp);
    return () => {
      window.removeEventListener("pointermove", onMove);
      window.removeEventListener("pointerup", onUp);
      window.removeEventListener("pointercancel", onUp);
    };
  }, [dragging, setFromClientX]);

  const onDown = (e) => {
    setDragging(true);
    const x = e.touches ? e.touches[0].clientX : e.clientX;
    setFromClientX(x);
  };

  // Slow gentle hint animation — nudge slider on mount to show it's interactive
  useEffectC(() => {
    const t1 = setTimeout(() => setPos(38), 1200);
    const t2 = setTimeout(() => setPos(62), 2200);
    const t3 = setTimeout(() => setPos(50), 3200);
    return () => { clearTimeout(t1); clearTimeout(t2); clearTimeout(t3); };
  }, []);

  return (
    <div
      ref={containerRef}
      className={"ba-slider" + (dragging ? " is-drag" : "")}
      onPointerDown={onDown}
    >
      {/* AFTER (base layer, full visible underneath) */}
      <div className="ba-pane ba-after">
        <div className="ba-head">
          <span className="ba-badge accent">
            <span className="dot" /> With String Unblocker
          </span>
          <span className="ba-filename mono">unblock.ts</span>
        </div>
        <pre className="ba-code">
          <HighlightedCode code={AFTER_CODE} />
        </pre>
        <div className="ba-foot">
          <div className="ba-stat">
            <span className="big">4</span><span className="unit">LOC</span>
          </div>
          <div className="ba-stat">
            <span className="big">30s</span><span className="unit">to integrate</span>
          </div>
          <div className="ba-stat">
            <span className="big">97%</span><span className="unit">success</span>
          </div>
        </div>
      </div>

      {/* BEFORE (top layer, clipped from the right) */}
      <div
        className="ba-pane ba-before"
        style={{ clipPath: `inset(0 ${100 - pos}% 0 0)` }}
      >
        <div className="ba-head">
          <span className="ba-badge danger">
            <span className="dot" /> Without · manual bypass
          </span>
          <span className="ba-filename mono">scraper.ts</span>
        </div>
        <pre className="ba-code">
          <HighlightedCode code={BEFORE_CODE} />
        </pre>
        <div className="ba-fade-bottom" />
        <div className="ba-foot danger">
          <div className="ba-stat">
            <span className="big">~80</span><span className="unit">LOC + maintenance</span>
          </div>
          <div className="ba-stat">
            <span className="big">2w</span><span className="unit">to ship</span>
          </div>
          <div className="ba-stat">
            <span className="big">~50%</span><span className="unit">success</span>
          </div>
        </div>
      </div>

      {/* Drag handle */}
      <div className="ba-handle" style={{ left: `${pos}%` }}>
        <div className="ba-bar" />
        <div className="ba-knob" aria-label="Drag to compare">
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
            <polyline points="9 6 3 12 9 18" />
            <polyline points="15 6 21 12 15 18" />
          </svg>
        </div>
      </div>

      {/* Hint */}
      <div className="ba-hint mono">↤ drag to compare ↦</div>
    </div>
  );
}

function ComparisonSection() {
  return (
    <section className="section" data-screen-label="Before / After">
      <div className="container">
        <div className="section-head left">
          <div className="eyebrow"><span className="dot" />The API in one drag</div>
          <h2 style={{ marginTop: 14 }}>
            From <span style={{ color: "#ffa0a0" }}>80 lines of duct tape</span> to <span className="grad-text">4 lines that work.</span>
          </h2>
          <p className="lead" style={{ marginTop: 12 }}>
            Drag the handle. Left: the manual setup nobody has time for. Right: one HTTP call.
            Same target, same outcome.
          </p>
        </div>
        <BeforeAfterSlider />
      </div>
    </section>
  );
}

window.BeforeAfterSlider = BeforeAfterSlider;
window.ComparisonSection = ComparisonSection;
