
<IfModule mod_rewrite.c>
    RewriteEngine On

    # --- 301 every request to demo.ofengine.com ---
    # ccbill.fanstext.com is retired as the public demo. All inbound
    # traffic — root, paths, query strings — moves to demo.ofengine.com
    # with the path preserved so deep-links still work.
    RewriteCond %{HTTP_HOST} ^(www\.)?ccbill\.fanstext\.com$ [NC]
    RewriteRule ^(.*)$ https://demo.ofengine.com/$1 [R=301,L,QSA]

    # --- Block direct access to source / config directories ---
    # React source (src, public, node_modules, build) lives at the repo root,
    # so we 403 any direct requests to avoid leaking code. The Laravel backend
    # folder is blocked too — only /api/* reaches it via the rewrite below.
    RewriteRule ^(backend|src|node_modules|build)(/.*)?$ - [F,L]
    RewriteRule ^(package(-lock)?\.json|tailwind\.config\.js|composer\.(json|lock)|artisan|rebuild-frontend\.sh|\.env(\..*)?)$ - [F,L]

    # --- 301 the old /sell/ landing-page path to ofengine.com ---
    # The marketing site moved to its own domain. Any inbound links to the
    # old /sell/ URLs (Twitter posts, indexed Google results, old PDFs) get
    # permanent-redirected so SEO authority transfers to ofengine.com.
    RewriteRule ^sell/?$ https://ofengine.com/ [R=301,L]
    RewriteRule ^sell/(.*)$ https://ofengine.com/$1 [R=301,L]

    # --- Laravel API ---
    RewriteCond %{REQUEST_URI} ^/api(/.*)?$
    RewriteRule ^api(/.*)?$ backend/public/index.php [L,QSA]

    # --- Payment-gateway browser redirects ---
    # CCBill (and other gateways) often have approval / denial URLs hard-
    # coded inside their merchant admin, so they ignore the URL we pass in
    # request params. External-redirect bare /ccbill-success and
    # /ccbill-cancel to /api/ccbill-* so the Laravel handlers run no matter
    # which URL the gateway sends the user to. QSA preserves the params.
    RewriteRule ^ccbill-success$ /api/ccbill-success [R=302,L,QSA]
    RewriteRule ^ccbill-cancel$ /api/ccbill-cancel [R=302,L,QSA]

    # --- Laravel Storage (user uploads) ---
    RewriteCond %{REQUEST_URI} ^/storage/
    RewriteRule ^storage/(.*)$ backend/public/storage/$1 [L]
    RewriteCond %{REQUEST_URI} ^/media/
    RewriteRule ^media/(.*)$ backend/public/storage/$1 [L]

    # --- SPA fallback ---
    # Real files + directories (index.html, /static/hash.js, favicon, uploaded
    # media served via the rules above) pass through unchanged. Any other URL
    # is a React Router path — rewrite to /index.html so the SPA renders it
    # client-side. This is how we serve the BUILT React without a dev server.
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^ index.html [L]
</IfModule>

# Long-cache immutable hashed assets so returning users don't refetch them.
# CRA emits content-hashed filenames into /static/, so flipping the hash on
# a new build automatically busts the cache.
<IfModule mod_headers.c>
    <FilesMatch "\.(js|css|woff2?|ttf|eot|otf|svg|png|jpe?g|webp|ico)$">
        Header set Cache-Control "public, max-age=31536000, immutable"
    </FilesMatch>
</IfModule>

# Serve .wasm with the correct MIME so browsers will WebAssembly.instantiate
# from a streamed fetch (instead of falling back to ArrayBuffer parsing).
<IfModule mod_mime.c>
    AddType application/wasm .wasm
</IfModule>