import React from "react";
import { createRoot } from "react-dom/client";
import {
  ArrowRight,
  Check,
  Cloud,
  Code2,
  Download,
  FileImage,
  Gauge,
  Globe2,
  HardDrive,
  Image,
  Layers3,
  Lock,
  Menu,
  Repeat2,
  ShieldCheck,
  Sparkles,
  UploadCloud,
  X
} from "lucide-react";
import DemoEvalStrip from "./demos/DemoEvalStrip";
import DemoDetailPage from "./demos/DemoDetailPage";
import { demoGroups, demoItems, demoPath, findDemoByHash, findDemoByPath, slugify } from "./demos/demoData";
import "../Content/tailwind.generated.css";
import "./styles.css";

const asset = (path) => path;

const pages = {
  "/": "home",
  "/Default.aspx": "home",
  "/Features.aspx": "features",
  "/Demos.aspx": "demos",
  "/Docs.aspx": "docs",
  "/Pricing.aspx": "pricing",
  "/About.aspx": "about",
  "/Customers.aspx": "customers",
  "/Download.aspx": "download",
  "/Contact.aspx": "contact",
  "/FAQ.aspx": "faq",
  "/Howtos.aspx": "howtos",
  "/ImageUpload.aspx": "image",
  "/DragDrop.aspx": "dragdrop",
  "/Security.aspx": "security",
  "/Deployment.aspx": "deployment",
  "/Requirements.aspx": "requirements",
  "/Screenshots.aspx": "screenshots",
  "/Changelog.aspx": "changelog",
  "/Upgrade.aspx": "upgrade",
  "/Privacy.aspx": "privacy",
  "/Terms.aspx": "terms",
  "/Support.aspx": "support"
};

const pageMeta = {
  home: {
    title: "AjaxUploader - ASP.NET Web Forms File Upload Control",
    description:
      "AjaxUploader 5.2 is an ASP.NET Web Forms upload control with resumable chunks, drag and drop, direct-to-cloud transfers, validation, and image workflows."
  },
  features: {
    title: "Features | AjaxUploader",
    description:
      "Explore AjaxUploader 5.2 features for ASP.NET Web Forms: chunked uploads, direct cloud transfers, image editing, validation, security, and accessibility."
  },
  demos: {
    title: "Demos | AjaxUploader",
    description:
      "Browse AjaxUploader 5.2 demos for Web Forms uploads, drag and drop, validation, direct-to-cloud transfers, image workflows, and custom UI."
  },
  docs: {
    title: "Docs | AjaxUploader",
    description:
      "Install, configure, license, and deploy AjaxUploader 5.2 with quick starts, migration notes, cloud signer recipes, and API documentation."
  },
  pricing: {
    title: "Pricing | AjaxUploader",
    description:
      "Buy perpetual AjaxUploader 5.2 licenses for ASP.NET Web Forms with no recurring fees, upgrade pricing, and source-code options."
  },
  about: {
    title: "About | AjaxUploader",
    description:
      "AjaxUploader is a long-running ASP.NET Web Forms upload-control product maintained by Richscripts for teams with production upload workflows."
  },
  customers: {
    title: "Customers | AjaxUploader",
    description:
      "AjaxUploader has served established .NET teams across industries that need reliable upload workflows inside ASP.NET Web Forms applications."
  },
  download: {
    title: "Download | AjaxUploader",
    description:
      "Download the AjaxUploader 5.2 evaluation package with Web Forms demos, documentation, binaries, and deployment examples."
  },
  contact: {
    title: "Contact | AjaxUploader",
    description:
      "Contact Richscripts for AjaxUploader trial, licensing, Web Forms deployment, upgrade, or ASP.NET Core CoreUpload guidance."
  },
  support: {
    title: "Support | AjaxUploader",
    description:
      "Get AjaxUploader support for installation, licensing, Web Forms integration, deployment, validation, and upload workflow troubleshooting."
  },
  faq: {
    title: "FAQ | AjaxUploader",
    description: "Answers about AjaxUploader licensing, ASP.NET Web Forms fit, upgrades, direct-to-cloud transfers, and ASP.NET Core alternatives."
  },
  howtos: {
    title: "How-tos | AjaxUploader",
    description: "Scenario-based AjaxUploader guides for chunked uploads, direct-to-S3 transfers, validation, image transforms, migration, and Companion broker setup."
  },
  image: {
    title: "Image Upload Demos | AjaxUploader",
    description: "Explore AjaxUploader image upload workflows including EXIF rotation, smart crop, overlays, filters, PDF thumbnails, and AVIF/WebP output."
  },
  dragdrop: {
    title: "Drag and Drop Uploads | AjaxUploader",
    description: "Build Web Forms drag-and-drop upload workflows with folder drops, clipboard paste, queue previews, progress states, and restore prompts."
  },
  security: {
    title: "Security | AjaxUploader",
    description: "Security-focused AjaxUploader guidance for server-side signatures, Companion broker OAuth, antiforgery, virus scanning, throttling, and encrypted queues."
  },
  deployment: {
    title: "Deployment | AjaxUploader",
    description: "Production deployment checklist for AjaxUploader on IIS, including handlers, request limits, temp folders, cloud signers, license files, and cleanup."
  },
  requirements: {
    title: "Requirements | AjaxUploader",
    description: "AjaxUploader requirements for ASP.NET Web Forms, .NET Framework, IIS, modern browsers, optional cloud storage, and Companion broker workflows."
  },
  screenshots: {
    title: "Screenshots | AjaxUploader",
    description: "Preview AjaxUploader drop zones, queue progress, single-file upload UI, cloud flows, and image workflow surfaces."
  },
  changelog: {
    title: "Changelog | AjaxUploader",
    description: "AjaxUploader 5.2 changelog covering Companion broker, cloud sources, headless hooks, image editor, GCS resumable uploads, locales, and accessibility."
  },
  upgrade: {
    title: "Upgrade to AjaxUploader 5.2 | AjaxUploader",
    description: "Upgrade AjaxUploader 4.x applications to 5.2 with compatibility shims, migration docs, new cloud strategies, and discounted upgrade pricing."
  },
  privacy: {
    title: "Privacy | AjaxUploader",
    description: "Privacy practices for AjaxUploader evaluation, licensing, downloads, and support communications."
  },
  terms: {
    title: "Terms | AjaxUploader",
    description: "General AjaxUploader license and service terms for evaluating, downloading, purchasing, and deploying the ASP.NET Web Forms upload control."
  }
};

function setDocumentMeta(meta) {
  const fallback = pageMeta.home;
  const next = meta || fallback;
  const canonicalUrl = `https://ajaxuploader.com${normalizeCanonicalPath(window.location.pathname)}`;
  document.title = next.title;
  upsertMeta("description", next.description);
  upsertMeta("twitter:description", next.description, "name");
  upsertMeta("twitter:title", next.title, "name");
  upsertMeta("og:title", next.title, "property");
  upsertMeta("og:description", next.description, "property");
  upsertMeta("og:url", canonicalUrl, "property");
  upsertLink("canonical", canonicalUrl);
}

function normalizeCanonicalPath(path) {
  if (!path || path === "/" || path === "/Default.aspx") return "/";
  return path;
}

function upsertMeta(name, content, attr = "name") {
  let tag = document.head.querySelector(`meta[${attr}="${name}"]`);
  if (!tag) {
    tag = document.createElement("meta");
    tag.setAttribute(attr, name);
    document.head.appendChild(tag);
  }
  tag.setAttribute("content", content);
}

function upsertLink(rel, href) {
  let tag = document.head.querySelector(`link[rel="${rel}"]`);
  if (!tag) {
    tag = document.createElement("link");
    tag.setAttribute("rel", rel);
    document.head.appendChild(tag);
  }
  tag.setAttribute("href", href);
}

function App() {
  const [path, setPath] = React.useState(window.location.pathname);
  const demo = findDemoByPath(path);
  const page = demo ? "demoDetail" : pages[path] || "home";

  React.useEffect(() => {
    if (demo) {
      setDocumentMeta({
        title: `${demo.title} Demo | AjaxUploader`,
        description: demo.lead
      });
      return;
    }
    setDocumentMeta(pageMeta[page] || pageMeta.home);
  }, [page, demo]);

  React.useEffect(() => {
    if (path === "/Demos.aspx" && window.location.hash) {
      const legacyDemo = findDemoByHash(window.location.hash);
      if (legacyDemo) {
        const nextPath = demoPath(legacyDemo.id);
        window.history.replaceState({}, "", nextPath);
        setPath(nextPath);
        return;
      }
    }

    const scrollToHash = () => {
      if (!window.location.hash) return;
      const target = document.getElementById(window.location.hash.slice(1));
      if (target) {
        target.scrollIntoView({ block: "start" });
      }
    };

    window.requestAnimationFrame(scrollToHash);
    const settledScroll = window.setTimeout(scrollToHash, 350);
    window.addEventListener("hashchange", scrollToHash);
    return () => {
      window.clearTimeout(settledScroll);
      window.removeEventListener("hashchange", scrollToHash);
    };
  }, [page, path]);

  React.useEffect(() => {
    const onPop = () => setPath(window.location.pathname);
    window.addEventListener("popstate", onPop);
    return () => window.removeEventListener("popstate", onPop);
  }, []);

  const navigate = React.useCallback((href) => {
    if (/^https?:|^mailto:|^\/document|^\/download/.test(href)) return;
    window.history.pushState({}, "", href);
    setPath(window.location.pathname);
    window.scrollTo({ top: 0, behavior: "smooth" });
  }, []);

  return (
    <Layout page={page} navigate={navigate}>
      {renderPage(page, demo)}
    </Layout>
  );
}

function Link({ href, navigate, children, className = "", ...props }) {
  const onClick = (event) => {
    if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
    if (!href || /^https?:|^mailto:|^\/document|^\/download/.test(href)) return;
    event.preventDefault();
    navigate(href);
  };
  return (
    <a href={href} onClick={onClick} className={className} {...props}>
      {children}
    </a>
  );
}

function getNavGroup(page) {
  if (page === "home") return "home";
  if (["demos", "demoDetail"].includes(page)) return "demos";
  if (page === "features") return "features";
  if (["docs", "faq", "howtos", "image", "dragdrop", "security", "deployment", "requirements", "screenshots", "changelog", "upgrade"].includes(page)) return "docs";
  if (["about", "customers", "contact", "support", "privacy", "terms"].includes(page)) return "about";
  if (["pricing", "download"].includes(page)) return "pricing";
  return page;
}

function Layout({ page, navigate, children }) {
  const [open, setOpen] = React.useState(false);
  const navGroup = getNavGroup(page);
  const nav = [
    ["Home", "/Default.aspx", "home"],
    ["Demos", "/Demos.aspx", "demos"],
    ["Features", "/Features.aspx", "features"],
    ["Docs", "/Docs.aspx", "docs"],
    ["Company", "/About.aspx", "about"],
    ["Pricing", "/Pricing.aspx", "pricing"]
  ];

  return (
    <div className="min-h-screen bg-white text-slate-800">
      <a className="skip-link" href="#mainContent">
        Skip to main content
      </a>
      <header className="site-header">
        <div className="site-header-inner">
          <Link href="/Default.aspx" navigate={navigate} className="brand-link" aria-label="AjaxUploader home">
            <span className="brand-mark">
              <UploadCloud size={22} />
            </span>
            <span>
              <strong>AjaxUploader</strong>
              <small>v5.2 · ASP.NET Web Forms</small>
            </span>
          </Link>
          <button className="menu-button" type="button" onClick={() => setOpen(!open)} aria-expanded={open} aria-label="Toggle navigation">
            {open ? <X size={22} /> : <Menu size={22} />}
          </button>
          <nav className={`main-nav ${open ? "is-open" : ""}`} aria-label="Main navigation">
            {nav.map(([label, href, key]) => (
              <Link key={href} href={href} navigate={(nextHref) => { setOpen(false); navigate(nextHref); }} className={navGroup === key ? "is-active" : ""} aria-current={navGroup === key ? "page" : undefined}>
                {label}
              </Link>
            ))}
            <Link href="/Download.aspx" navigate={(nextHref) => { setOpen(false); navigate(nextHref); }} className="download-link">
              Download Package
            </Link>
          </nav>
        </div>
      </header>
      <main id="mainContent" tabIndex="-1">
        {children}
      </main>
      <Footer page={page} navigate={navigate} />
    </div>
  );
}

function Footer({ page, navigate }) {
  const cols = [
    ["Resources", [["Features", "/Features.aspx"], ["FAQ", "/FAQ.aspx"], ["How-tos", "/Howtos.aspx"], ["Requirements", "/Requirements.aspx"], ["Security", "/Security.aspx"], ["Class Reference", "/document/"]]],
    ["Explore", [["Demo Gallery", "/Demos.aspx"], ["Drag and Drop", "/DragDrop.aspx"], ["Image Upload", "/ImageUpload.aspx"], ["Screenshots", "/Screenshots.aspx"], ["Downloads", "/Download.aspx"], ["Changelog", "/Changelog.aspx"]]],
    ["Company", [["About", "/About.aspx"], ["Customers", "/Customers.aspx"], ["Contact", "/Contact.aspx"], ["Privacy", "/Privacy.aspx"], ["Terms", "/Terms.aspx"]]]
  ];
  return (
    <footer className="site-footer">
      <div className="footer-grid">
        <div>
          <Link href="/Default.aspx" navigate={navigate} className="footer-brand">
            <span className="brand-mark"><UploadCloud size={20} /></span>
            AjaxUploader
          </Link>
          <p>A production-ready upload control for ASP.NET Web Forms with chunked uploads, drag-and-drop UX, image workflows, and direct-to-cloud strategies.</p>
          <div className="footer-pills">
            <span>15,000+ customers</span>
            <span>60+ countries</span>
            <span>Web Forms</span>
          </div>
        </div>
        {cols.map(([title, items]) => (
          <div key={title}>
            <h2>{title}</h2>
            {items.map(([label, href]) => (
              <Link key={href} href={href} navigate={navigate} className={pages[href] === page ? "is-active" : ""} aria-current={pages[href] === page ? "page" : undefined}>
                {label}
              </Link>
            ))}
          </div>
        ))}
      </div>
      <div className="footer-bottom">
        <span>Copyright 2026 AjaxUploader.com. All rights reserved.</span>
        <span>Built for ASP.NET Web Forms teams shipping upload-heavy applications.</span>
      </div>
    </footer>
  );
}

function renderPage(page, demo) {
  const map = {
    home: <HomePage />,
    features: <FeaturesPage />,
    demos: <DemosPage />,
    docs: <DocsPage />,
    pricing: <PricingPage />,
    about: <AboutPage />,
    customers: <CustomersPage />,
    download: <DownloadPage />,
    contact: <ContactPage />,
    support: <SupportPage />,
    faq: <FaqPage />,
    howtos: <HowtosPage />,
    image: <ImagePage />,
    dragdrop: <DragDropPage />,
    security: <SecurityPage />,
    deployment: <DeploymentPage />,
    requirements: <RequirementsPage />,
    screenshots: <ScreenshotsPage />,
    changelog: <ChangelogPage />,
    upgrade: <UpgradePage />,
    privacy: <LegalPage type="privacy" />,
    terms: <LegalPage type="terms" />,
    demoDetail: demo ? <DemoDetailPage demo={demo} /> : <DemosPage />
  };
  return map[page] || map.home;
}

function Hero({ eyebrow, title, lead, actions, media }) {
  return (
    <section className="hero">
      <div className="hero-bg" aria-hidden="true" />
      <div className="hero-grid">
        <div className="hero-copy">
          <p className="eyebrow">{eyebrow}</p>
          <h1>{title}</h1>
          <p>{lead}</p>
          {actions && <div className="hero-actions">{actions}</div>}
        </div>
        {media}
      </div>
    </section>
  );
}

function ButtonLink({ href, children, variant = "primary" }) {
  return <a className={`button ${variant}`} href={href}>{children}</a>;
}

function HomePage() {
  return (
    <>
      <section className="home-hero">
        <div className="hero-bg" aria-hidden="true" />
        <div className="home-grid">
          <div className="home-copy">
            <div className="pill-row">
              <span className="version-pill"><span /> v5.2 for ASP.NET Web Forms</span>
              <a className="core-pill" href="https://coreupload.com" target="_blank" rel="noreferrer">ASP.NET Core? Use CoreUpload <ArrowRight size={15} /></a>
            </div>
            <h1>Modern uploads for Web Forms apps that still run the business.</h1>
            <p>AjaxUploader 5.2 is the focused upload control for ASP.NET Web Forms teams that do not want a whole UI suite, a hand-wired JavaScript uploader, or a hosted upload service. Add resumable chunks, direct-to-cloud transfers, validation, image workflows, and 4.x compatibility inside the app you already have.</p>
            <div className="feature-rail">
              <span><HardDrive size={16} /> Companion broker</span>
              <span><Cloud size={16} /> 6 cloud sources</span>
              <span><Code2 size={16} /> Headless hooks</span>
              <span><Image size={16} /> AVIF / WebP editor</span>
            </div>
            <div className="hero-actions">
              <ButtonLink href="/Demos.aspx">Explore demos</ButtonLink>
              <ButtonLink href="/Download.aspx" variant="secondary">Download package</ButtonLink>
            </div>
            <p className="core-line">Building with ASP.NET Core, Razor, Blazor, or Minimal APIs? Use <a href="https://coreupload.com">CoreUpload</a>.</p>
            <div className="metrics">
              <div><strong>7</strong><span>upload strategies</span></div>
              <div><strong>28</strong><span>built-in locales</span></div>
              <div><strong>4.x</strong><span>compatibility shim</span></div>
            </div>
          </div>
          <PreviewCard />
        </div>
      </section>
      <LogoBand />
      <Section eyebrow="What you can ship" title="Production upload workflows without rebuilding the app.">
        <CardGrid items={[
          ["Direct-to-cloud transfers", "Upload directly to S3-compatible storage, Azure Blob, or Google Cloud Storage using server-generated signatures.", Cloud],
          ["Resume and recover", "IndexedDB-backed state lets interrupted uploads continue after reloads, tab crashes, and connection drops.", Repeat2],
          ["Validate before storage", "Check size, extensions, MIME type, image dimensions, duplicate files, custom rules, and scan hooks.", ShieldCheck]
        ]} />
      </Section>
      <ArchitectureStrip />
      <Section eyebrow="Competitive fit" title="Built for the gap between UI suites, JavaScript widgets, and hosted upload APIs." lead="AjaxUploader is for teams keeping serious Web Forms applications alive: self-hosted, server-control friendly, and priced as an uploader instead of a platform migration.">
        <div className="gap-grid">
          {[
            ["Versus UI suites", "Telerik, DevExpress, Syncfusion", "Suite upload controls are strongest when the team already owns the suite. AjaxUploader keeps the purchase and documentation centered on upload workflows."],
            ["Versus JS widgets", "Uppy, FilePond, legacy Fine Uploader", "JavaScript uploaders are flexible, but Web Forms teams still need server plumbing, validation, lifecycle events, temp storage, and deployment docs."],
            ["Versus SaaS upload APIs", "Uploadcare, Filestack, Cloudinary", "Hosted media APIs are powerful for CDN pipelines. AjaxUploader fits teams that need self-hosted control and sensitive files inside chosen infrastructure."]
          ].map(([label, title, text]) => <article key={title}><span>{label}</span><h3>{title}</h3><p>{text}</p></article>)}
        </div>
      </Section>
      <FinalCta />
    </>
  );
}

function ArchitectureStrip() {
  const steps = [
    ["1", "Web Forms page", "Drop in the server control and keep page lifecycle events."],
    ["2", "Upload strategy", "Choose chunked, direct-to-cloud, tus, or URL import per workflow."],
    ["3", "Server broker", "Sign cloud URLs, validate metadata, scan files, and finalize storage."],
    ["4", "Storage target", "Keep files on disk or send bytes straight to S3, Azure, or GCS."]
  ];
  return (
    <section className="architecture-strip" aria-label="AjaxUploader architecture">
      <div className="section-heading">
        <p>Architecture</p>
        <h2>Modern transport without moving the application shell.</h2>
      </div>
      <div className="architecture-flow">
        {steps.map(([num, title, text]) => (
          <article key={title}>
            <b>{num}</b>
            <h3>{title}</h3>
            <p>{text}</p>
          </article>
        ))}
      </div>
    </section>
  );
}

function PreviewCard() {
  return (
    <div className="preview-wrap">
      <div className="preview-window">
        <div className="preview-bar"><span /><span /><span /><b>Drop zone with chunked resume</b></div>
        <img src={asset("/Content/images/showcase/drop-zone-demo.png")} alt="AjaxUploader drag and drop upload UI" />
      </div>
      <div className="floating-card status"><span>Current upload</span><strong>release-assets.zip</strong><i><b /></i><small>74% uploaded · 4 parallel chunks</small></div>
      <div className="floating-card route"><span>Strategy</span><strong>Direct-to-S3</strong><small>Signed by Web Forms. Bytes bypass IIS.</small></div>
    </div>
  );
}

function LogoBand() {
  const brands = ["sony", "intel", "nokia", "siemens", "ibm", "microsoft"];
  return (
    <section className="logo-band">
      <p>Trusted upload technology for established .NET teams</p>
      <div>{brands.map((brand) => <span key={brand}><img src={`/Content/images/brands/${brand}.svg`} alt={brand} /></span>)}</div>
    </section>
  );
}

function Section({ eyebrow, title, lead, children, muted = false }) {
  return (
    <section className={`section ${muted ? "muted" : ""}`}>
      <div className="section-inner">
        <div className="section-heading">
          <p>{eyebrow}</p>
          <h2>{title}</h2>
          {lead && <span>{lead}</span>}
        </div>
        {children}
      </div>
    </section>
  );
}

function CardGrid({ items }) {
  return <div className="card-grid">{items.map(([title, text, Icon]) => <article key={title}><Icon size={24} /><h3>{title}</h3><p>{text}</p></article>)}</div>;
}

function FeaturesPage() {
  return (
    <>
      <Hero eyebrow="Features · v5.2" title="Every capability, one control." lead="AjaxUploader gives Web Forms teams modern upload workflows without replacing their application shell: direct cloud strategies, resumable chunks, validation, image handling, security controls, localization, and compatibility for legacy pages." media={<PreviewCard />} actions={<><ButtonLink href="/Demos.aspx">Browse demos</ButtonLink><ButtonLink href="/Pricing.aspx" variant="secondary">See pricing</ButtonLink></>} />
      <Section eyebrow="New in 5.2" title="Server-side cloud tokens, headless UI, and a pro image editor.">
        <CardGrid items={[
          ["Companion broker", "Self-hosted Node/Express OAuth and file-proxy broker. Provider secrets stay server-side.", HardDrive],
          ["6 cloud sources", "Google Drive, Dropbox, OneDrive, Box, Unsplash, and Companion-backed imports.", Cloud],
          ["Headless hooks", "React, Vue, Svelte, and Angular hooks expose files, progress, status, and actions.", Code2],
          ["Image editor", "Smart-crop, overlays, filters, EXIF info, and AVIF/WebP output.", FileImage],
          ["Seven strategies", "single, chunked, s3, azure, gcs, tus, and urlImport transport modes.", Layers3],
          ["Accessibility", "ARIA live-region announcements, reduced-motion support, focus handling, and RTL locales.", Globe2]
        ]} />
      </Section>
      <Section muted eyebrow="Security and control" title="Keep upload data inside infrastructure you choose." lead="AjaxUploader is designed for self-hosted Web Forms deployments where storage, signatures, scanning, and temp files are controlled by your application team." />
      <FeatureMatrix />
    </>
  );
}

function FeatureMatrix() {
  const rows = [
    ["Web Forms server control", "Built in", "Generic integration", "Usually suite-bound"],
    ["Direct-to-cloud signing", "S3, Azure, GCS", "Custom server work", "Varies by suite"],
    ["4.x compatibility path", "Included", "Not applicable", "Not applicable"],
    ["Self-hosted cloud broker", "Included", "Separate service work", "Usually hosted or custom"],
    ["Perpetual uploader pricing", "Yes", "Open source or custom time", "Usually suite pricing"]
  ];
  return (
    <section className="feature-matrix">
      <div className="section-heading">
        <p>Why AjaxUploader</p>
        <h2>Focused on Web Forms upload work, not a whole UI platform.</h2>
      </div>
      <div className="matrix-table" role="table" aria-label="AjaxUploader comparison">
        <div role="row" className="matrix-head"><span>Capability</span><span>AjaxUploader</span><span>JS widget</span><span>UI suite</span></div>
        {rows.map((row) => <div role="row" key={row[0]}>{row.map((cell) => <span role="cell" key={cell}>{cell}</span>)}</div>)}
      </div>
    </section>
  );
}

function DemosPage() {
  let demoNumber = 0;

  return (
    <>
      <Hero eyebrow="Demo library · v5.2" title="The full v5.2 demo library, one click away." lead="Preview the upload patterns included with AjaxUploader, then download the package to run the Web Forms demos locally with real au:AjaxFileUpload controls." actions={<><ButtonLink href="/Download.aspx">Download demos</ButtonLink><ButtonLink href="/Docs.aspx" variant="secondary">Read setup docs</ButtonLink></>} />
      <section className="demo-index">
        {demoGroups.map(([title, demos]) => (
          <article key={title}>
            <h2>{title}<span>{demos.length} demos</span></h2>
            <div>
              {demos.map((demo) => {
                demoNumber += 1;
                const id = slugify(demo);
                const detail = demoItems.find((item) => item.id === id);
                return (
                  <a key={demo} href={demoPath(id)}>
                    <span>{demoNumber}</span>
                    <strong>{demo}</strong>
                    {detail && <small>{detail.lead}</small>}
                  </a>
                );
              })}
            </div>
          </article>
        ))}
      </section>
      <DemoEvalStrip />
    </>
  );
}

function DocsPage() {
  const docs = [
    ["Quick start", "Add the server control, register the handler, choose temp storage, and run the first upload locally.", "/document/guides/webforms-quick-start.html"],
    ["Migration guide", "Move from 4.x with compatibility namespaces and adopt v5.2 APIs gradually.", "/document/guides/migrating-from-4x.html"],
    ["Deployment", "Configure IIS limits, license files, temp folders, and production cleanup.", "/document/guides/deployment-and-licensing.html"],
    ["API reference", "Browse controls, events, providers, licensing, models, and services.", "/document/"]
  ];
  return (
    <>
      <Hero eyebrow="Documentation · v5.2" title="Install, configure, license, and deploy AjaxUploader 5.2." lead="Quick-start setup, signer recipes for the new cloud transports, the full class reference, and migration notes for teams moving from 4.x in one place." actions={<><ButtonLink href="/document/">Open docs</ButtonLink><ButtonLink href="/Download.aspx" variant="secondary">Download package</ButtonLink></>} />
      <section className="doc-paths" aria-label="Documentation paths">
        {docs.map(([title, text, href]) => <a key={title} href={href}><span>{title}</span><p>{text}</p><ArrowRight size={18} /></a>)}
      </section>
      <Section eyebrow="Start here" title="Documentation paths by job.">
        <CardGrid items={[
          ["Web Forms quick start", "Add the control, register the handler, configure temp storage, and handle server events.", Code2],
          ["Deployment and licensing", "IIS, request limits, permissions, license files, and production checklist.", ShieldCheck],
          ["Migration from 4.x", "Use the CuteWebUI compatibility namespace and move gradually to the 5.2 API.", Repeat2]
        ]} />
      </Section>
    </>
  );
}

function PricingPage() {
  const plans = [
    { name: "Domain", price: "$99", fit: "Best for one public Web Forms site.", text: "One production domain for a single Web Forms application.", features: ["Perpetual license", "All v5.2 demos", "Minor updates included"] },
    { name: "IP", price: "$199", fit: "Best for intranet or server-bound apps.", text: "One production IP or internal server deployment.", features: ["Internal deployment", "Cloud strategies", "Companion broker"] },
    { name: "Developer", price: "$399", fit: "Best for teams shipping multiple projects.", text: "Named-developer license for building multiple Web Forms projects.", features: ["Multiple projects", "Upgrade path", "Priority evaluation help"], featured: true },
    { name: "Source Code", price: "$3,999", fit: "Best for regulated or deeply customized apps.", text: "Full source-code license for teams requiring maximum control.", features: ["Source access", "Custom builds", "Long-term control"] }
  ];
  return (
    <>
      <Hero eyebrow="AjaxUploader 5.2" title="Perpetual licenses, no recurring fees." lead="AjaxUploader 5.2 licenses are perpetual. The self-hosted Companion broker, cloud strategies, headless hooks, image editor, demos, and documentation are all included." actions={<ButtonLink href="/Contact.aspx">Ask about licensing</ButtonLink>} />
      <section className="pricing-grid">{plans.map((plan) => <article className={plan.featured ? "is-featured" : ""} key={plan.name}><span>{plan.name}</span><strong>{plan.price}</strong><p>{plan.text}</p><em>{plan.fit}</em><ul className="plan-features">{plan.features.map((feature) => <li key={feature}><Check size={16} />{feature}</li>)}</ul><a href="/Contact.aspx">Contact sales</a></article>)}</section>
      <p className="core-note">Need ASP.NET Core? Choose <a href="https://coreupload.com">CoreUpload</a> instead.</p>
    </>
  );
}

function AboutPage() {
  return (
    <>
      <Hero eyebrow="About · v5.2" title="Built for long-lived Web Forms applications." lead="AjaxUploader is a long-running upload-control product line maintained for teams that still depend on ASP.NET Web Forms. v5.2 brings self-hosted cloud brokering, modern transports, headless hooks, and image workflows without forcing a rewrite of existing .aspx pages." />
      <Stats />
      <Section eyebrow="What we focus on" title="Focused depth for one demanding problem domain.">
        <CardGrid items={[
          ["Web Forms specialization", "Built for the page lifecycle, server events, and ViewState model.", Code2],
          ["Modern transport stack", "Classic, chunked, direct-cloud, tus, and URL-import strategies.", Layers3],
          ["Long-term maintenance", "Shipping since 2003 with compatibility paths for older pages.", Repeat2]
        ]} />
      </Section>
    </>
  );
}

function Stats() {
  return <section className="stats"><div><strong>2003</strong><span>Company established</span></div><div><strong>15k+</strong><span>Customers served</span></div><div><strong>60+</strong><span>Countries reached</span></div></section>;
}

function DownloadPage() {
  return (
    <>
      <Hero eyebrow="Download" title="Evaluate AjaxUploader 5.2 locally." lead="Download the package, open the Web Forms demo app, and test the uploader on localhost without a production license key." actions={<a className="button primary" href="/download/AjaxUploader-5.2.0-download-package.zip"><Download size={18} /> Download ZIP</a>} />
      <section className="download-checklist" aria-label="Download package checklist">
        <div><strong>5.2 package</strong><span>Demo app, binaries, docs, class reference, and deployment notes.</span></div>
        <div><strong>Local evaluation</strong><span>Runs on localhost without a production license key.</span></div>
        <div><strong>Web Forms first</strong><span>Server-control examples for upload-heavy ASP.NET Web Forms apps.</span></div>
      </section>
      <Section eyebrow="Included" title="Everything needed for a Web Forms evaluation.">
        <CardGrid items={[
          ["Demo application", "Runnable examples for upload strategies, validation, drag and drop, and image workflows.", Layers3],
          ["Class reference", "Generated API documentation, migration notes, and deployment guidance.", Code2],
          ["Companion examples", "Server-side cloud broker configuration and signer integration samples.", HardDrive]
        ]} />
      </Section>
    </>
  );
}

function ContactPage() {
  const [status, setStatus] = React.useState("");
  const handleSubmit = (event) => {
    event.preventDefault();
    setStatus("Thanks. This React preview keeps the form local; use sales@richscripts.com to send the request.");
  };
  return (
    <section className="contact-page">
      <div>
        <p className="eyebrow">Contact</p>
        <h1>Talk to us about trials, licensing, or deployment.</h1>
        <p>Reach out if you need help evaluating the demo package, choosing a license, or deciding whether your project should use AjaxUploader or CoreUpload.</p>
        <p><strong>Sales:</strong> <a href="mailto:sales@richscripts.com">sales@richscripts.com</a></p>
        <p><strong>Support:</strong> <a href="mailto:support@richscripts.com">support@richscripts.com</a></p>
        <p>Aurora, Ontario, Canada</p>
      </div>
      <form onSubmit={handleSubmit}>
        <label>Full name<input placeholder="Jane Smith" autoComplete="name" required /></label>
        <label>Work email<input type="email" placeholder="jane@company.com" autoComplete="email" required /></label>
        <label>What do you need?<select defaultValue="Trial package"><option>Trial package</option><option>Licensing help</option><option>Deployment help</option><option>ASP.NET Core recommendation</option></select></label>
        <label>Message<textarea placeholder="Tell us about your upload use case" required /></label>
        <button type="submit">Send request</button>
        {status && <p className="form-status" role="status">{status}</p>}
      </form>
    </section>
  );
}

function SupportPage() {
  const paths = [
    ["Installation", "Handler registration, bin deployment, license files, and Web.config setup.", Code2],
    ["Upload failures", "IIS request limits, temp-folder permissions, chunk recovery, and validation errors.", ShieldCheck],
    ["Cloud workflows", "Direct-to-S3, Azure Blob, GCS, Companion broker, and server-side signing.", Cloud],
    ["Upgrades", "Migration from 4.x, compatibility namespaces, and adopting v5.2 transports gradually.", Repeat2]
  ];
  return (
    <>
      <Hero eyebrow="Support" title="Help for production Web Forms upload workflows." lead="Get focused support for AjaxUploader installation, licensing, IIS deployment, validation rules, direct-to-cloud signing, and upgrade planning." actions={<><ButtonLink href="mailto:support@richscripts.com">Email support</ButtonLink><ButtonLink href="/Docs.aspx" variant="secondary">Open docs</ButtonLink></>} />
      <section className="support-grid" aria-label="Support topics">
        {paths.map(([title, text, Icon]) => <article key={title}><Icon size={22} /><h2>{title}</h2><p>{text}</p></article>)}
      </section>
      <section className="support-steps">
        <div>
          <span>Faster troubleshooting</span>
          <h2>Send the details that prove where the upload is failing.</h2>
        </div>
        <ol>
          <li><strong>Version and license type</strong><p>Include the AjaxUploader package version, license scope, and whether this is local, staging, or production.</p></li>
          <li><strong>Server context</strong><p>Share IIS version, .NET Framework version, request-size limits, temp path, and relevant Web.config handler entries.</p></li>
          <li><strong>Upload scenario</strong><p>Name the demo or feature involved, expected file sizes, validation rules, browser, and any network or console error.</p></li>
        </ol>
      </section>
    </>
  );
}

function CustomersPage() {
  const industries = [
    ["Healthcare", "Patient documents, intake forms, lab attachments, and secure internal portals."],
    ["Education", "Assignments, media submissions, admissions files, and staff document workflows."],
    ["Manufacturing", "CAD attachments, inspection photos, supplier documents, and field reports."],
    ["Software teams", "Issue attachments, customer uploads, migration tools, and admin consoles."]
  ];
  return (
    <>
      <Hero eyebrow="Customers" title="Trusted by established .NET teams." lead="AjaxUploader has served production upload workflows across healthcare, education, finance, government, manufacturing, and software teams." />
      <LogoBand />
      <Stats />
      <section className="customer-industries" aria-label="Customer use cases">
        {industries.map(([title, text]) => <article key={title}><h2>{title}</h2><p>{text}</p></article>)}
      </section>
      <section className="customer-proof">
        <div>
          <span>Why teams keep it</span>
          <h2>It fits the application they already run.</h2>
          <p>AjaxUploader is useful when the upload surface is only one part of a mature Web Forms application. Teams keep server events, validation patterns, deployment controls, and familiar Web.config ownership while adding modern upload behavior.</p>
        </div>
        <PreviewCard />
      </section>
    </>
  );
}

function FaqPage() {
  const faqs = [
    ["Is AjaxUploader for ASP.NET Core?", "AjaxUploader is for ASP.NET Web Forms. For ASP.NET Core, Razor, Blazor, or Minimal APIs, use CoreUpload."],
    ["Will existing 4.x pages still work?", "Yes. AjaxUploader 5.2 includes a CuteWebUI compatibility namespace so many 4.x pages keep compiling while you migrate gradually."],
    ["Are licenses subscription based?", "No. Licenses are perpetual, with discounted major-version upgrades for existing customers."],
    ["Can uploads bypass IIS?", "Yes. Direct-to-S3, Azure Blob, and GCS strategies let browser bytes go straight to storage using server-generated signatures."]
  ];
  return <><Hero eyebrow="FAQ · v5.2" title="Answers to the questions teams ask before rollout." lead="Short answers for licensing, migration, ASP.NET Core fit, and production deployment." /><section className="faq-list">{faqs.map(([q, a]) => <details key={q} open><summary>{q}</summary><p>{a}</p></details>)}</section></>;
}

function HowtosPage() {
  return <SimpleResourcePage eyebrow="How-to guides · v5.2" title="Scenario-based guides for common upload workflows." items={["Configure chunked uploads", "Add direct-to-S3 transfers", "Validate file type and size", "Resize and transform images", "Migrate from AjaxUploader 4.x", "Use the Companion broker"]} />;
}

function ImagePage() {
  return <SimpleResourcePage eyebrow="Image handling · v5.2" title="A full image pipeline: smart-crop, overlays, filters, AVIF/WebP." items={["EXIF auto-rotate", "Content-aware crop", "Text and sticker overlays", "Filter presets", "AVIF and WebP output", "PDF poster thumbnails"]} />;
}

function DragDropPage() {
  return <SimpleResourcePage eyebrow="Drag and drop" title="Drag, drop, paste, preview, and recover uploads." items={["Whole-page drop target", "Folder drop support", "Clipboard paste", "Queue preview", "Progress states", "Restore prompt"]} />;
}

function SecurityPage() {
  return <SimpleResourcePage eyebrow="Security" title="Self-hosted upload control for sensitive Web Forms apps." items={["Server-side cloud signatures", "Companion broker keeps OAuth tokens server-side", "Antiforgery integration", "Virus scan hook", "Rate-limiting demos", "Client-side AES-GCM queue encryption"]} />;
}

function DeploymentPage() {
  return <SimpleResourcePage eyebrow="Deployment" title="Production checklist for IIS and Web Forms." items={["Handler registration", "Request size limits", "Temp folder permissions", "Cloud signer configuration", "License file placement", "Monitoring and cleanup"]} />;
}

function RequirementsPage() {
  return <SimpleResourcePage eyebrow="Requirements" title="Runs where Web Forms teams still ship." items={["ASP.NET Web Forms", ".NET Framework 4.x", "IIS or IIS Express", "Modern browser for HTML5 uploads", "Optional Node broker for Companion", "Optional cloud storage account"]} />;
}

function ScreenshotsPage() {
  const shots = [
    ["Drop zone workflow", "/Content/images/showcase/drop-zone-demo.png", "AjaxUploader drag and drop upload UI"],
    ["Queue and progress", "/Content/images/showcase/queue-demo.png", "AjaxUploader queue with progress states"],
    ["Single-file upload", "/Content/images/showcase/single-file-demo.png", "AjaxUploader single file upload UI"]
  ];
  return <><Hero eyebrow="Screenshots" title="See the upload UI in action." lead="Preview the drop zone, progress states, cloud flows, and image workflow surfaces." /><section className="screenshots">{shots.map(([title, src, alt]) => <figure className="screenshot-card" key={src}><img src={src} alt={alt} /><figcaption>{title}</figcaption></figure>)}</section></>;
}

function ChangelogPage() {
  return <SimpleResourcePage eyebrow="Changelog" title="AjaxUploader 5.2 release highlights." items={["Companion broker", "Box cloud source", "Unsplash source", "Headless framework hooks", "Content-aware image editor", "Direct-to-GCS resumable strategy", "28 built-in locales", "Accessibility improvements"]} />;
}

function UpgradePage() {
  return <SimpleResourcePage eyebrow="Upgrade" title="Upgrade to AjaxUploader 5.2." items={["Keep 4.x pages compiling", "Adopt new transport strategies gradually", "Add cloud sources when needed", "Use migration docs and demo app", "Discounted upgrade pricing for existing licenses"]} />;
}

function SimpleResourcePage({ eyebrow, title, items }) {
  const useCases = [
    "Works with existing .aspx pages",
    "Server-control friendly",
    "Covered by runnable demos"
  ];
  return (
    <>
      <Hero eyebrow={eyebrow} title={title} lead="Focused guidance for teams evaluating, deploying, or upgrading AjaxUploader in ASP.NET Web Forms applications." />
      <section className="resource-grid">
        {items.map((item) => (
          <article key={item}>
            <Check size={20} />
            <div>
              <strong>{item}</strong>
              <span>{resourceDetail(item)}</span>
            </div>
          </article>
        ))}
      </section>
      <section className="resource-strip" aria-label={`${eyebrow} fit`}>
        {useCases.map((item) => <span key={item}>{item}</span>)}
      </section>
      <section className="inline-cta">
        <div>
          <h2>Want to see it running?</h2>
          <p>Open the demo library or download the package and test the workflow locally.</p>
        </div>
        <div>
          <a href="/Demos.aspx">Browse demos</a>
          <a href="/Download.aspx">Download package</a>
        </div>
      </section>
    </>
  );
}

function resourceDetail(item) {
  const details = {
    "Configure chunked uploads": "Tune chunk size, retries, parallelism, and server assembly for large files.",
    "Add direct-to-S3 transfers": "Sign parts from Web Forms while file bytes bypass IIS.",
    "Validate file type and size": "Reject invalid files early with clear queue-level feedback.",
    "Resize and transform images": "Prepare thumbnails, previews, and storage-ready variants.",
    "Migrate from AjaxUploader 4.x": "Use compatibility shims while adopting v5.2 features gradually.",
    "Use the Companion broker": "Keep cloud OAuth tokens server-side for remote sources.",
    "EXIF auto-rotate": "Correct phone-camera orientation before previews or storage.",
    "Content-aware crop": "Keep focal points visible when users crop images.",
    "Text and sticker overlays": "Annotate images before upload for media workflows.",
    "Filter presets": "Apply lightweight visual adjustments before queue submission.",
    "AVIF and WebP output": "Export modern formats with graceful fallback.",
    "PDF poster thumbnails": "Show useful queue previews for PDF uploads.",
    "Whole-page drop target": "Let users drop files anywhere on upload-heavy forms.",
    "Folder drop support": "Preserve folder-oriented workflows where browsers allow it.",
    "Clipboard paste": "Accept screenshots and copied images without a file picker.",
    "Queue preview": "Show staged files, statuses, and validation before submission.",
    "Progress states": "Expose live state with accessible progress semantics.",
    "Restore prompt": "Recover interrupted queues after reloads or tab crashes.",
    "Server-side cloud signatures": "Keep storage credentials out of browser code.",
    "Companion broker keeps OAuth tokens server-side": "Broker cloud-source imports through infrastructure you control.",
    "Antiforgery integration": "Pair upload endpoints with Web Forms security controls.",
    "Virus scan hook": "Quarantine or reject files before final storage.",
    "Rate-limiting demos": "Model upload throttling for public-facing forms.",
    "Client-side AES-GCM queue encryption": "Protect queued browser-side data between sessions.",
    "Handler registration": "Register upload handlers cleanly for IIS deployments.",
    "Request size limits": "Set Web.config and IIS limits for realistic upload sizes.",
    "Temp folder permissions": "Avoid production failures from locked upload directories.",
    "Cloud signer configuration": "Wire S3, Azure, and GCS signer services explicitly.",
    "License file placement": "Keep production license files in predictable app locations.",
    "Monitoring and cleanup": "Track temp storage and remove orphaned chunks.",
    "ASP.NET Web Forms": "Designed around server controls and page lifecycle behavior.",
    ".NET Framework 4.x": "Targets long-lived applications still running on .NET Framework.",
    "IIS or IIS Express": "Evaluate locally, then deploy with standard IIS hosting.",
    "Modern browser for HTML5 uploads": "Uses native file APIs for drag, drop, chunking, and progress.",
    "Optional Node broker for Companion": "Use only when server-side cloud OAuth brokering is needed.",
    "Optional cloud storage account": "Needed for direct-to-cloud strategy demos.",
    "Companion broker": "New cloud-source broker for server-side OAuth.",
    "Box cloud source": "Box joins the built-in remote-source set.",
    "Unsplash source": "Search and import royalty-free images into the queue.",
    "Headless framework hooks": "Expose uploader state to custom React, Vue, Svelte, and Angular UI.",
    "Content-aware image editor": "Crop, annotate, filter, and export modern image formats.",
    "Direct-to-GCS resumable strategy": "Stream uploads straight to Google Cloud Storage sessions.",
    "28 built-in locales": "Includes RTL-capable locale coverage for global forms.",
    "Accessibility improvements": "Adds live regions, focus handling, and reduced-motion support.",
    "Keep 4.x pages compiling": "Compatibility namespace keeps old pages moving while you upgrade.",
    "Adopt new transport strategies gradually": "Move individual workflows to cloud or resumable strategies as needed.",
    "Add cloud sources when needed": "Introduce Drive, Dropbox, OneDrive, Box, and Unsplash workflows selectively.",
    "Use migration docs and demo app": "Lean on runnable examples instead of guessing integration details.",
    "Discounted upgrade pricing for existing licenses": "Existing license holders can upgrade without buying fresh."
  };
  return details[item] || "Part of the AjaxUploader 5.2 Web Forms workflow set.";
}

function LegalPage({ type }) {
  const isPrivacy = type === "privacy";
  return (
    <section className="legal-page">
      <p className="eyebrow">{isPrivacy ? "Privacy" : "Terms of service"}</p>
      <h1>{isPrivacy ? "Privacy practices for AjaxUploader." : "General terms for using AjaxUploader."}</h1>
      <p>{isPrivacy ? "We collect only the information needed to support evaluation, licensing, downloads, and customer support." : "Each license purchase grants a perpetual, non-exclusive right to use AjaxUploader within the scope of the selected license type."}</p>
      <h2>Customer responsibility</h2>
      <p>You are responsible for validating uploaded files, securing storage destinations, and configuring your application according to your deployment requirements.</p>
      <h2>Support</h2>
      <p>Technical support is provided through the contact form and support email for installation, configuration, and integration questions.</p>
    </section>
  );
}

function FinalCta() {
  return <section className="final-cta"><div><h2>Try it in a Web Forms project today.</h2><p>Download the package, open the demos, and test locally without a production license key.</p></div><a href="/Download.aspx">Download package</a></section>;
}

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