<?php

namespace KeyLair;

/**
 * Demo accounts can see every admin page's real structure and counts --
 * a prospective buyer is meant to evaluate the whole product, not a
 * crippled subset -- but a handful of values are sensitive enough
 * (product key codes, claim link tokens, other staff's email addresses)
 * that they're swapped for a realistic-looking placeholder instead of
 * the real thing, purely at render time. The underlying database row is
 * never touched. Every method here is demo-only except keyCode(), which
 * is also masked for reviewer -- see its own doc comment.
 *
 * Each mapping is deterministic (seeded from the real value's own hash),
 * so the same real key/email/token always renders as the same fake one
 * for a given demo session -- copying it twice, or seeing it again on a
 * different page, doesn't look like a bug by changing every time.
 */
class DemoMask
{
    private static function isDemo(): bool
    {
        $user = Auth::user();
        return $user !== null && $user['role'] === 'demo';
    }

    /**
     * A product key / redemption code, e.g. "ASHF-3X9K-QP2M-7RT4". Unlike
     * every other method here, masked for reviewer as well as demo --
     * "never sees real key values" is reviewer's one actual restriction
     * (everywhere else it's full read access, same as content manager),
     * enforced elsewhere by keeping reviewer off key-value pages entirely
     * (see Auth::requireEditAccess()). A page reviewer CAN reach that
     * still surfaces a key value (e.g. Redemptions) needs it masked
     * in-line instead, same as demo. Preserves length and non-alphanumeric
     * separators (dashes, spaces) so the fake value still looks/lines up
     * like the real format.
     */
    public static function keyCode(string $real): string
    {
        if (Auth::canEdit() || $real === '') {
            return $real;
        }
        $alphabet = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
        $hash = hash('sha256', $real);
        $out = '';
        $i = 0;
        foreach (str_split($real) as $ch) {
            if (ctype_alnum($ch)) {
                $out .= $alphabet[hexdec($hash[$i % strlen($hash)]) % strlen($alphabet)];
                $i++;
            } else {
                $out .= $ch;
            }
        }
        return $out;
    }

    /** An email address -- stable per input, always resolves to the same @example.com address. */
    public static function email(string $real): string
    {
        if (!self::isDemo() || $real === '') {
            return $real;
        }
        return 'demo-user-' . substr(hash('crc32b', $real), 0, 6) . '@example.com';
    }

    /** A username, display name, or "creator tag" -- stable per input, picked from a fixed pool of obviously-fake names. */
    public static function name(string $real): string
    {
        if (!self::isDemo() || $real === '') {
            return $real;
        }
        $names = [
            'Alex Demo', 'Jordan Sample', 'Taylor Example', 'Morgan Test',
            'Casey Preview', 'Riley Mock', 'Jamie Placeholder', 'Drew Fixture',
        ];
        $idx = hexdec(substr(hash('crc32b', $real), 0, 4)) % count($names);
        return $names[$idx];
    }

    /**
     * A real claim link is a bearer credential -- whoever has the URL can
     * claim a real key from real stock, so a demo login can't just be
     * handed a masked-but-real one (a broken/scrambled token would 404,
     * and an unscrambled one would let a demo login actually deplete
     * real inventory). Instead it's pointed at the same built-in preview
     * mockups admin/preview.php already uses elsewhere (e.g. Design's
     * theme previews) to show what the claim page looks like without
     * any real product/key data behind it -- always available, never
     * expires, nothing to run out of. $isOverview picks the
     * multi-product "all products for this link" mockup instead of the
     * single-product platform-picker one, matching whichever the real
     * link would actually have shown.
     */
    public static function claimUrl(string $realUrl, string $realToken, bool $isOverview = false): string
    {
        if (!self::isDemo() || $realToken === '') {
            return $realUrl;
        }
        $key = $isOverview ? 'claim-overview' : 'product-page';
        return Helpers::baseUrl() . '/admin/preview.php?key=' . $key;
    }
}
