import { __awaiter } from '../../node_modules/.pnpm/@rollup_plugin-typescript@12.1.4_rollup@4.46.2_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.mjs';
import index from '../../node_modules/.pnpm/@fingerprintjs_fingerprintjs@5.1.0/node_modules/@fingerprintjs/fingerprintjs/dist/fp.esm.mjs';
import { isValidFingerprintId, FINGERPRINT_FIRST_TOUCH_STORAGE_KEY, FINGERPRINT_FIRST_TOUCH_COOKIE_NAME, FINGERPRINT_STORAGE_KEY, FINGERPRINT_COOKIE_NAME, FINGERPRINT_FIRST_TOUCH_HEADER, FINGERPRINT_HEADER_NAME, FINGERPRINT_SOURCE_REFER } from './fingerprint-shared.mjs';

/**
 * Fingerprint Client Utilities
 * 客户端专用的指纹生成和管理逻辑
 * 只能在浏览器环境中使用
 */
const FIRST_TOUCH_MAX_LENGTH = 2048;
const FIRST_TOUCH_COOKIE_DAYS = 30;
/**
 * 检查浏览器存储（localStorage 和 cookie）中的指纹 ID
 * 返回有效的 ID 或 null
 */
function checkStoredFingerprintId() {
    if (typeof window === 'undefined') {
        return null;
    }
    // 优先检查 localStorage
    const localStorageId = getLocalStorageValue(FINGERPRINT_STORAGE_KEY);
    if (localStorageId && isValidFingerprintId(localStorageId)) {
        return localStorageId;
    }
    // 检查 cookie
    const cookieId = getCookieValue(FINGERPRINT_COOKIE_NAME);
    if (cookieId && isValidFingerprintId(cookieId)) {
        // 同步到 localStorage
        setLocalStorageValue(FINGERPRINT_STORAGE_KEY, cookieId);
        return cookieId;
    }
    return null;
}
function normalizeString(value, maxLength = FIRST_TOUCH_MAX_LENGTH) {
    if (!value) {
        return undefined;
    }
    const trimmed = value.trim();
    if (!trimmed) {
        return undefined;
    }
    return trimmed.length > maxLength ? trimmed.slice(0, maxLength) : trimmed;
}
function readFirstTouchFromStorage() {
    if (typeof window === 'undefined') {
        return null;
    }
    const localStorageValue = getLocalStorageValue(FINGERPRINT_FIRST_TOUCH_STORAGE_KEY);
    if (localStorageValue) {
        const parsed = parseFirstTouchValue(localStorageValue);
        if (parsed) {
            syncFirstTouchStorage(parsed);
            return parsed;
        }
    }
    const cookieValue = getCookieValue(FINGERPRINT_FIRST_TOUCH_COOKIE_NAME);
    if (cookieValue) {
        const parsed = parseFirstTouchValue(cookieValue);
        if (parsed) {
            syncFirstTouchStorage(parsed);
            return parsed;
        }
    }
    return null;
}
function parseFirstTouchValue(value) {
    try {
        const decoded = decodeURIComponent(value);
        const parsed = JSON.parse(decoded);
        return sanitizeFirstTouchData(parsed);
    }
    catch (_a) {
        return null;
    }
}
function sanitizeFirstTouchData(data) {
    if (!data) {
        return null;
    }
    const sanitized = {
        landingUrl: normalizeString(data.landingUrl),
        landingPath: normalizeString(data.landingPath, 512),
        landingHost: normalizeString(data.landingHost, 255),
        externalReferrer: normalizeString(data.externalReferrer),
        capturedAt: normalizeString(data.capturedAt, 64),
        ref: normalizeString(data.ref, 512),
        utmSource: normalizeString(data.utmSource, 512),
        utmMedium: normalizeString(data.utmMedium, 512),
        utmCampaign: normalizeString(data.utmCampaign, 512),
        utmTerm: normalizeString(data.utmTerm, 512),
        utmContent: normalizeString(data.utmContent, 512),
        utmId: normalizeString(data.utmId, 512),
        gclid: normalizeString(data.gclid, 512),
        fbclid: normalizeString(data.fbclid, 512),
        msclkid: normalizeString(data.msclkid, 512),
        ttclid: normalizeString(data.ttclid, 512),
        twclid: normalizeString(data.twclid, 512),
        liFatId: normalizeString(data.liFatId, 512),
    };
    return Object.values(sanitized).some(Boolean) ? sanitized : null;
}
function serializeFirstTouchData(data) {
    return encodeURIComponent(JSON.stringify(data));
}
function syncFirstTouchStorage(data) {
    if (typeof window === 'undefined') {
        return;
    }
    const serialized = serializeFirstTouchData(data);
    setLocalStorageValue(FINGERPRINT_FIRST_TOUCH_STORAGE_KEY, serialized);
    setCookie(FINGERPRINT_FIRST_TOUCH_COOKIE_NAME, serialized, FIRST_TOUCH_COOKIE_DAYS);
}
function buildFirstTouchData() {
    var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
    if (typeof window === 'undefined') {
        return null;
    }
    const url = new URL(window.location.href);
    const data = sanitizeFirstTouchData({
        landingUrl: url.toString(),
        landingPath: url.pathname,
        landingHost: url.host,
        externalReferrer: document.referrer || undefined,
        capturedAt: new Date().toISOString(),
        ref: (_a = url.searchParams.get('ref')) !== null && _a !== void 0 ? _a : undefined,
        utmSource: (_b = url.searchParams.get('utm_source')) !== null && _b !== void 0 ? _b : undefined,
        utmMedium: (_c = url.searchParams.get('utm_medium')) !== null && _c !== void 0 ? _c : undefined,
        utmCampaign: (_d = url.searchParams.get('utm_campaign')) !== null && _d !== void 0 ? _d : undefined,
        utmTerm: (_e = url.searchParams.get('utm_term')) !== null && _e !== void 0 ? _e : undefined,
        utmContent: (_f = url.searchParams.get('utm_content')) !== null && _f !== void 0 ? _f : undefined,
        utmId: (_g = url.searchParams.get('utm_id')) !== null && _g !== void 0 ? _g : undefined,
        gclid: (_h = url.searchParams.get('gclid')) !== null && _h !== void 0 ? _h : undefined,
        fbclid: (_j = url.searchParams.get('fbclid')) !== null && _j !== void 0 ? _j : undefined,
        msclkid: (_k = url.searchParams.get('msclkid')) !== null && _k !== void 0 ? _k : undefined,
        ttclid: (_l = url.searchParams.get('ttclid')) !== null && _l !== void 0 ? _l : undefined,
        twclid: (_m = url.searchParams.get('twclid')) !== null && _m !== void 0 ? _m : undefined,
        liFatId: (_o = url.searchParams.get('li_fat_id')) !== null && _o !== void 0 ? _o : undefined,
    });
    return data;
}
function getOrCreateFirstTouchData() {
    const existing = readFirstTouchFromStorage();
    if (existing) {
        return existing;
    }
    const created = buildFirstTouchData();
    if (created) {
        syncFirstTouchStorage(created);
    }
    return created;
}
/**
 * 生成基于真实浏览器特征的fingerprint ID
 * 使用 FingerprintJS 收集浏览器特征并生成唯一标识
 */
function generateFingerprintId() {
    return __awaiter(this, void 0, void 0, function* () {
        if (typeof window === 'undefined') {
            throw new Error('generateFingerprintId can only be used in browser environment');
        }
        // 检查现有 ID
        const existingId = checkStoredFingerprintId();
        if (existingId) {
            console.log('Using existing fingerprint ID:', existingId);
            return existingId;
        }
        try {
            // 使用 FingerprintJS 生成指纹
            const fp = yield index.load();
            const result = yield fp.get();
            const fingerprintId = `fp_${result.visitorId}`;
            // 存储到 localStorage 和 cookie
            setLocalStorageValue(FINGERPRINT_STORAGE_KEY, fingerprintId);
            setCookie(FINGERPRINT_COOKIE_NAME, fingerprintId, 365);
            console.log('Generated new fingerprint ID:', fingerprintId);
            return fingerprintId;
        }
        catch (error) {
            console.warn('Failed to generate fingerprint with FingerprintJS:', error);
            // 降级方案：生成基于时间戳和随机数的 ID
            const fallbackId = `fp_fallback_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
            setLocalStorageValue(FINGERPRINT_STORAGE_KEY, fallbackId);
            setCookie(FINGERPRINT_COOKIE_NAME, fallbackId, 365);
            console.log('Generated fallback fingerprint ID:', fallbackId);
            return fallbackId;
        }
    });
}
/**
 * 获取当前的fingerprint ID
 */
function getFingerprintId() {
    return checkStoredFingerprintId();
}
/**
 * 设置fingerprint ID到存储
 */
function setFingerprintId(fingerprintId) {
    if (typeof window === 'undefined') {
        throw new Error('setFingerprintId can only be used in browser environment');
    }
    if (!isValidFingerprintId(fingerprintId)) {
        throw new Error('Invalid fingerprint ID');
    }
    setLocalStorageValue(FINGERPRINT_STORAGE_KEY, fingerprintId);
    setCookie(FINGERPRINT_COOKIE_NAME, fingerprintId, 365);
}
/**
 * 清除fingerprint ID
 */
function clearFingerprintId() {
    if (typeof window === 'undefined') {
        throw new Error('clearFingerprintId can only be used in browser environment');
    }
    removeLocalStorageValue(FINGERPRINT_STORAGE_KEY);
    deleteCookie(FINGERPRINT_COOKIE_NAME);
}
/**
 * 获取或生成fingerprint ID
 * 如果不存在则自动生成新的
 */
function getOrGenerateFingerprintId() {
    return __awaiter(this, void 0, void 0, function* () {
        const existingId = checkStoredFingerprintId();
        if (existingId) {
            console.log('Retrieved existing fingerprint ID:', existingId);
            return existingId;
        }
        return yield generateFingerprintId();
    });
}
/**
 * 创建包含fingerprint ID的fetch headers
 */
function createFingerprintHeaders() {
    return __awaiter(this, void 0, void 0, function* () {
        const fingerprintId = yield getOrGenerateFingerprintId();
        const headers = {
            [FINGERPRINT_HEADER_NAME]: fingerprintId,
        };
        const firstTouch = getOrCreateFirstTouchData();
        if (firstTouch) {
            headers[FINGERPRINT_FIRST_TOUCH_HEADER] = serializeFirstTouchData(firstTouch);
        }
        return headers;
    });
}
/**
 * Hook for generating fingerprint headers
 */
function useFingerprintHeaders() {
    return createFingerprintHeaders;
}
/**
 * Create a fetch wrapper that automatically includes fingerprint headers
 */
function createFingerprintFetch() {
    return (url, init) => __awaiter(this, void 0, void 0, function* () {
        const fingerprintHeaders = yield createFingerprintHeaders();
        const headers = Object.assign(Object.assign(Object.assign({}, fingerprintHeaders), { [FINGERPRINT_SOURCE_REFER]: document.referrer || '' }), ((init === null || init === void 0 ? void 0 : init.headers) || {}));
        return fetch(url, Object.assign(Object.assign({}, init), { headers }));
    });
}
// Cookie 辅助函数 (私有)
function getCookieValue(name) {
    var _a;
    if (typeof document === 'undefined') {
        return null;
    }
    try {
        const value = `; ${document.cookie}`;
        const parts = value.split(`; ${name}=`);
        if (parts.length === 2) {
            return ((_a = parts.pop()) === null || _a === void 0 ? void 0 : _a.split(';').shift()) || null;
        }
        return null;
    }
    catch (_b) {
        return null;
    }
}
function setCookie(name, value, days) {
    if (typeof document === 'undefined') {
        return;
    }
    try {
        const expires = new Date();
        expires.setTime(expires.getTime() + days * 24 * 60 * 60 * 1000);
        document.cookie = `${name}=${value};expires=${expires.toUTCString()};path=/;SameSite=Lax`;
    }
    catch (_a) {
        // Ignore storage failures so attribution never blocks page flow.
    }
}
function deleteCookie(name) {
    if (typeof document === 'undefined') {
        return;
    }
    try {
        document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/`;
    }
    catch (_a) {
        // Ignore storage failures so attribution never blocks page flow.
    }
}
function getLocalStorageValue(key) {
    if (typeof window === 'undefined') {
        return null;
    }
    try {
        return window.localStorage.getItem(key);
    }
    catch (_a) {
        return null;
    }
}
function setLocalStorageValue(key, value) {
    if (typeof window === 'undefined') {
        return;
    }
    try {
        window.localStorage.setItem(key, value);
    }
    catch (_a) {
        // Ignore storage failures so attribution never blocks page flow.
    }
}
function removeLocalStorageValue(key) {
    if (typeof window === 'undefined') {
        return;
    }
    try {
        window.localStorage.removeItem(key);
    }
    catch (_a) {
        // Ignore storage failures so attribution never blocks page flow.
    }
}

export { clearFingerprintId, createFingerprintFetch, createFingerprintHeaders, generateFingerprintId, getFingerprintId, getOrCreateFirstTouchData, getOrGenerateFingerprintId, setFingerprintId, useFingerprintHeaders };
