"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTimeOffset = getTimeOffset;
exports.setTimeOffset = setTimeOffset;
exports.checkClockDrift = checkClockDrift;
exports.syncTimeWithServer = syncTimeWithServer;
exports.getSyncedDate = getSyncedDate;
exports.getSystemDate = getSystemDate;
exports.getSystemTime = getSystemTime;
exports.initializeTimeSync = initializeTimeSync;
const react_native_1 = require("react-native");
let timeOffset = 0;
let hasWarned = false;
let OriginalDate = Date;
const CLOCK_DRIFT_THRESHOLD_MS = 5000; // 5 seconds
function getTimeOffset() {
    return timeOffset;
}
function setTimeOffset(offset) {
    timeOffset = offset;
}
function checkClockDrift(serverTime) {
    const serverDate = new Date(serverTime);
    const clientDate = new Date();
    const drift = Math.abs(serverDate.getTime() - clientDate.getTime());
    if (drift > CLOCK_DRIFT_THRESHOLD_MS) {
        const driftSeconds = Math.round(drift / 1000);
        if (!hasWarned) {
            hasWarned = true;
            console.warn(`clock drift detected: ${driftSeconds}s difference from server time. ` +
                `this may cause issues with time-sensitive operations. ` +
                `please sync your system clock.`);
        }
        return { hasDrift: true, driftMs: drift, driftSeconds };
    }
    else {
        return {
            hasDrift: false,
            driftMs: drift,
            driftSeconds: Math.round(drift / 1000),
        };
    }
}
function syncTimeWithServer(serverTime, networkLatencyMs) {
    const serverDate = new OriginalDate(serverTime);
    const clientDate = new OriginalDate();
    const offset = serverDate.getTime() - clientDate.getTime() - networkLatencyMs;
    setTimeOffset(offset);
}
function getSyncedDate() {
    const now = new Date();
    if (timeOffset !== 0) {
        return new Date(now.getTime() + timeOffset);
    }
    return now;
}
function getSystemDate() {
    return new OriginalDate();
}
function getSystemTime() {
    return OriginalDate.now();
}
function initializeTimeSync() {
    if (react_native_1.Platform.OS !== "web") {
        return;
    }
    // store original Date
    OriginalDate = Date;
    const OriginalDatePrototype = OriginalDate.prototype;
    // create patched Date constructor
    function PatchedDate(...args) {
        // If called as a function (no `new`), forward to original Date to get the string form
        if (!(this instanceof PatchedDate)) {
            return OriginalDate.apply(undefined, args);
        }
        // If called as a constructor, construct a Date with synced time when no args provided
        if (args.length === 0) {
            const syncedTime = OriginalDate.now() + timeOffset;
            return Reflect.construct(OriginalDate, [syncedTime], PatchedDate);
        }
        // Otherwise construct with the provided arguments
        return Reflect.construct(OriginalDate, args, PatchedDate);
    }
    // copy static methods
    PatchedDate.now = function () {
        return OriginalDate.now() + timeOffset;
    };
    PatchedDate.parse = OriginalDate.parse;
    PatchedDate.UTC = OriginalDate.UTC;
    // copy prototype
    PatchedDate.prototype = OriginalDatePrototype;
    // replace global Date
    globalThis.Date = PatchedDate;
}
//# sourceMappingURL=time-sync.js.map