local LrPrefs = import 'LrPrefs'

local Prefs = {}

local prefs = LrPrefs.prefsForPlugin()

-- Nullable-id keys use 0 as the "none" sentinel. Lua drops nil values from
-- table literals at construction time, so defaulting to nil would make these
-- keys invisible to pairs() — breaking the Prefs.config → Settings.show
-- round-trip (Settings iterates the returned config to decide what to save).
local CONFIG_DEFAULTS = {
    sourceMode = 'current',                 -- 'current' | 'single' | 'split'
    sourceCollectionId = 0,
    sourceCollectionLeftId = 0,
    sourceCollectionRightId = 0,
    minRating = 0,                          -- 0..5
    requiredFlag = 'either',                -- 'pick' | 'unflagged' | 'either'
    requiredColorLabel = 'any',             -- 'any' | 'red' | 'yellow' | 'green' | 'blue' | 'purple' | 'none'
    allowMixedOrientation = false,
    poolOrientation = 'any',                -- 'landscape' | 'portrait' | 'square' | 'any'
    pairLayout = 'horizontal',              -- 'horizontal' | 'vertical'
    windowSize = 'large',                   -- 'small' | 'medium' | 'large' | 'custom'
    customWidth = 1600,
    customHeight = 900,
    showMetadata = true,
    colorScheme = 'grey',                   -- 'white' | 'grey' | 'black'
    historyDepth = 50,
    targetSetId = 0,
    -- Minimum image size (longest side in pixels) we ask LR
    -- for via `requestJpegThumbnail`.  LR treats the argument
    -- as a FLOOR, not a cap: if the catalog's standard-
    -- preview cache holds a larger image, LR returns that
    -- directly; if the cache is smaller, LR builds from
    -- source (flaky on Windows — see bugs.md).  Default 1024
    -- is the safest floor: fits under every realistic LR
    -- Standard Preview Size option so the SDK call resolves
    -- via cache lookup, never a rebuild.  Catalog setting
    -- lives under Catalog Settings → Previews (LR Classic
    -- menu on Mac, Edit menu on Windows).  Valid values:
    -- 1024, 1440, 1680, 2048, 2880 (matching LR's options).
    imageSize = 1024,
    -- Which browser to launch the pair window in.
    -- 'auto' = prefer the running Chromium browser (Chrome
    -- or Edge) for fast launch with no cold-start cost; if
    -- none running, fall back to the first installed in
    -- preference order.  Specific names ('chrome', 'edge',
    -- 'brave') force that browser regardless of running-
    -- state.  See `Platform.chromiumBrowsers`,
    -- `Platform.runningBrowsers`, and `Launcher.findBrowser`
    -- for the resolution logic.  See ideas/focus-cohesion.md
    -- "Smarter browser choice" for the design rationale
    -- (cold-start cost vs. focus-on-close behavior).
    browserPref = 'auto',
}

-- Legacy colorScheme values (pre-rename of "Color scheme" →
-- "Background" with white/grey/black).  Mapped on read so a
-- user's old pref still resolves to a valid new value without
-- requiring a migration pass.
local COLOR_SCHEME_ALIASES = {
    lightroom = 'grey',
    dark = 'black',
    light = 'white',
}

function Prefs.config()
    local out = {}
    for k, v in pairs(CONFIG_DEFAULTS) do
        local current = prefs[k]
        if current == nil then current = v end
        out[k] = current
    end
    if COLOR_SCHEME_ALIASES[out.colorScheme] then
        out.colorScheme = COLOR_SCHEME_ALIASES[out.colorScheme]
    end
    return out
end

function Prefs.setConfig(updates)
    for k, v in pairs(updates) do
        if CONFIG_DEFAULTS[k] ~= nil then
            prefs[k] = v
        end
    end
    -- Bump a generation counter on every save so watchers can
    -- tell when the config changed without diffing every field.
    -- Browser polls /status, sees the counter tick, re-fetches
    -- getState to pick up filter changes, display prefs, etc.
    prefs.settingsGeneration = (prefs.settingsGeneration or 0) + 1
end

function Prefs.settingsGeneration()
    return prefs.settingsGeneration or 0
end

-- Bump the settings-generation counter without changing any
-- config.  Used by plugin-side actions (e.g. Rebuild snapshot)
-- that mutate State.currentPair without going through
-- Prefs.setConfig — the browser polls /status and refetches
-- getState when this counter changes, so it needs to tick for
-- any state change the browser should see.
function Prefs.bumpGeneration()
    prefs.settingsGeneration = (prefs.settingsGeneration or 0) + 1
end

local function sessionKey(catalogId, targetSetId, field)
    return string.format('session.%s.%s.%s',
        tostring(catalogId or 'default'),
        tostring(targetSetId or 'default'),
        field)
end

function Prefs.currentPair(catalogId, targetSetId)
    return prefs[sessionKey(catalogId, targetSetId, 'currentPair')]
end

function Prefs.setCurrentPair(catalogId, targetSetId, pair)
    prefs[sessionKey(catalogId, targetSetId, 'currentPair')] = pair
end

function Prefs.history(catalogId, targetSetId)
    return prefs[sessionKey(catalogId, targetSetId, 'history')] or {}
end

function Prefs.setHistory(catalogId, targetSetId, history)
    prefs[sessionKey(catalogId, targetSetId, 'history')] = history
end

function Prefs.pairCounter(catalogId, targetSetId)
    return prefs[sessionKey(catalogId, targetSetId, 'pairCounter')] or 0
end

function Prefs.incrementPairCounter(catalogId, targetSetId)
    local key = sessionKey(catalogId, targetSetId, 'pairCounter')
    local n = (prefs[key] or 0) + 1
    prefs[key] = n
    return n
end

function Prefs.windowGeometry()
    return prefs.windowGeometry or {}
end

function Prefs.setWindowGeometry(geom)
    prefs.windowGeometry = geom
end

function Prefs.clearSession(catalogId, targetSetId)
    prefs[sessionKey(catalogId, targetSetId, 'currentPair')] = nil
    prefs[sessionKey(catalogId, targetSetId, 'history')] = nil
end

local function snapshotKey(catalogId)
    return string.format('snapshot.%s', tostring(catalogId or 'default'))
end

function Prefs.snapshot(catalogId)
    return prefs[snapshotKey(catalogId)]
end

function Prefs.setSnapshot(catalogId, snap)
    prefs[snapshotKey(catalogId)] = snap
end

function Prefs.clearSnapshot(catalogId)
    prefs[snapshotKey(catalogId)] = nil
end

return Prefs
