-- Persistent usage stats, aggregated across all catalogs the
-- plugin has run against. Rationale: users with multiple
-- Lightroom catalogs (work / personal, migrations in progress)
-- typically think about their plugin use as a single stream of
-- activity, not per-catalog. If per-catalog breakdowns become
-- useful later, the counters can be split without breaking the
-- aggregate: just add new keys alongside.
--
-- What we count:
--   pairs_viewed              -- every new pair composition shown
--                                (advance + reshuffleSide + refreshSnapshot).
--                                Back/swap don't count — those surface an
--                                already-seen pair.
--   pairs_saved               -- every successful save.
--   pairing_sessions_started  -- every fresh Launcher.start (menu re-clicks
--                                that just bring an existing dashboard to
--                                front don't count).
--   pairs_back                -- successful Back navigations (pair resolved
--                                from history).  Error paths don't count.
--   pairs_swap                -- successful left/right swaps.  Error paths
--                                don't count.
--   first_use_at              -- ISO 8601 UTC timestamp, stamped once on
--                                the very first plugin load (alongside
--                                install_id mint).  Impossible to backfill,
--                                so captured eagerly even though no current
--                                surface reads it.
--
-- Counter API keeps a catalogId parameter (unused at the moment)
-- so call sites don't change if we later re-introduce per-
-- catalog splits.

local LrPrefs = import 'LrPrefs'

local Stats = {}

local prefs = LrPrefs.prefsForPlugin()

-- Seed math.random so the UUID generator below produces distinct
-- sequences per plugin launch. Lua's PRNG is deterministic
-- without this — every run otherwise returns the same first
-- values. Only needs to happen once per module load.
math.randomseed(os.time() + math.floor((os.clock() or 0) * 1e6))
for _ = 1, 5 do math.random() end

-- Anonymous installation identifier. Not a user ID — it's a random
-- UUID minted on first plugin run and persisted to plugin-wide
-- LrPrefs. Rationale: if we ever wire up analytics, we need a
-- stable dedup key without collecting anything personal. This
-- ID changes on LR prefs wipe / fresh install / new machine,
-- which is the right granularity — it identifies "this plugin
-- installation's activity" not the human behind it.
local function generateUuidV4()
    -- RFC 4122 v4: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx where y is
    -- 8, 9, a, or b. Not crypto-grade (math.random isn't secure),
    -- but for an analytics dedup key this is plenty.
    local template = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
    return (template:gsub('[xy]', function(c)
        local v = (c == 'x') and math.random(0, 15) or math.random(8, 11)
        return string.format('%x', v)
    end))
end

-- ISO 8601 UTC timestamp.  Format: 2026-04-26T15:32:09Z.
-- Used for first_use_at; cheap and unambiguous across
-- timezones / locales.
local function nowIso()
    return os.date('!%Y-%m-%dT%H:%M:%SZ')
end

function Stats.installId()
    if not prefs['stats.install_id'] then
        prefs['stats.install_id'] = generateUuidV4()
        -- Stamp first_use_at on the same event that mints
        -- install_id.  Both represent "first time this
        -- installation was seen"; keeping them in lockstep
        -- avoids a second lazy-init code path and guarantees
        -- the timestamp is captured before any session-level
        -- counters tick.
        if not prefs['stats.first_use_at'] then
            prefs['stats.first_use_at'] = nowIso()
        end
    end
    return prefs['stats.install_id']
end

function Stats.firstUseAt()
    return prefs['stats.first_use_at']
end

local function bump(field)
    local k = 'stats.' .. field
    prefs[k] = (prefs[k] or 0) + 1
    return prefs[k]
end

function Stats.incrementViewed(_catalogId)
    return bump('pairs_viewed')
end

function Stats.incrementSaved(_catalogId)
    return bump('pairs_saved')
end

function Stats.incrementSessionStarted()
    return bump('pairing_sessions_started')
end

function Stats.incrementBack()
    return bump('pairs_back')
end

function Stats.incrementSwap()
    return bump('pairs_swap')
end

-- Snapshot of lifetime counters across all catalogs.
function Stats.snapshot()
    return {
        pairs_viewed             = prefs['stats.pairs_viewed']             or 0,
        pairs_saved              = prefs['stats.pairs_saved']              or 0,
        pairs_back               = prefs['stats.pairs_back']               or 0,
        pairs_swap               = prefs['stats.pairs_swap']               or 0,
        pairing_sessions_started = prefs['stats.pairing_sessions_started'] or 0,
        first_use_at             = prefs['stats.first_use_at'],
    }
end

return Stats
