--[[
  Commercial profile entitlement (SKU separation).
  Not DRM — filters customer UI to licensed profile IDs.

  Resolution order:
  1. ML_ENTITLEMENT_TIER env (portrait_wedding | full_collection) for lab smoke
  2. license/entitlement.json (JsonLite decode) when present
  3. Embedded portrait_wedding allow-list (default for Portrait & Wedding pack)

  full_collection tier: all profiles passing PublicCatalog.isCustomerVisible() are allowed.
]]
local LrPathUtils = import "LrPathUtils"

local M = {}

M.SKU_PORTRAIT_WEDDING = "AS-PW-099"
M.SKU_FULL_COLLECTION = "AS-FULL-249"
M.BUILD_ENTITLEMENT = 186

M.PORTRAIT_WEDDING_PROFILE_IDS = {
    "portra_400_accurate_prototype",
    "portra_400_skinsafe_prototype",
    "fuji_400h_accurate_prototype",
    "fuji_400h_cc",
    "portra_160_accurate_prototype",
    "portra_800_accurate_prototype",
    "kodak_pro_image_100",
    "fuji_reala_500d",
    "fuji_astia_100f",
    "pro_neg_std",
    "gold_200",
    "kodak_oktar",
    "konica_centuria_100",
    "senova_light",
    "colorplus_200",
    "vision3_250d",
    "bw_delta_100",
    "bw_xp2",
}

local PORTRAIT_WEDDING_ALLOW = {}
for _, id in ipairs(M.PORTRAIT_WEDDING_PROFILE_IDS) do
    PORTRAIT_WEDDING_ALLOW[id] = true
end

local cachedState = nil

local function trim(s)
    return tostring(s or ""):gsub("^%s+", ""):gsub("%s+$", "")
end

local function readFile(path)
    local fh = io.open(path, "r")
    if not fh then
        return nil
    end
    local body = fh:read("*a")
    fh:close()
    return body
end

local function envTierOverride()
    if type(os.getenv) ~= "function" then
        return nil
    end
    local tier = trim(os.getenv("ML_ENTITLEMENT_TIER"))
    if tier == "portrait_wedding" or tier == "full_collection" then
        return tier
    end
    return nil
end

local function allowMapFromIdList(idList)
    local map = {}
    if type(idList) ~= "table" then
        return map
    end
    for _, id in ipairs(idList) do
        local key = trim(id)
        if key ~= "" then
            map[key] = true
        end
    end
    return map
end

local function loadEntitlementJson(pluginPath)
    if type(pluginPath) ~= "string" or pluginPath == "" then
        return nil
    end
    local jsonPath = LrPathUtils.child(pluginPath, "license/entitlement.json")
    local raw = readFile(jsonPath)
    if not raw or trim(raw) == "" then
        return nil
    end
    local okJson, json = pcall(function()
        return dofile(LrPathUtils.child(pluginPath, "lib/JsonLite.lua"))
    end)
    if not okJson or not json or type(json.decode) ~= "function" then
        return nil
    end
    local okDecode, parsed = pcall(function()
        return json.decode(raw)
    end)
    if okDecode and type(parsed) == "table" then
        return parsed
    end
    return nil
end

local function resolveState()
    if cachedState ~= nil then
        return cachedState
    end

    local pluginPath = (_PLUGIN and _PLUGIN.path) or ""
    local tier = "portrait_wedding"
    local envTier = envTierOverride()
    if envTier then
        tier = envTier
    end

    local productName = "Analog Signature Portrait & Wedding Film System"
    local sku = M.SKU_PORTRAIT_WEDDING
    local upgradeSku = M.SKU_FULL_COLLECTION
    local allowMap = nil

    local fileData = loadEntitlementJson(pluginPath)
    if type(fileData) == "table" then
        local fileTier = trim(fileData.licenseTier)
        if fileTier == "portrait_wedding" or fileTier == "full_collection" then
            tier = fileTier
        end
        if type(fileData.product) == "string" and trim(fileData.product) ~= "" then
            productName = trim(fileData.product)
        end
        if type(fileData.sku) == "string" and trim(fileData.sku) ~= "" then
            sku = trim(fileData.sku)
        end
        if type(fileData.upgradeSku) == "string" and trim(fileData.upgradeSku) ~= "" then
            upgradeSku = trim(fileData.upgradeSku)
        end
    end

    if envTier then
        tier = envTier
    end

    if tier == "full_collection" then
        allowMap = nil
        productName = "Full Analog Signature Collection"
        sku = M.SKU_FULL_COLLECTION
    else
        tier = "portrait_wedding"
        allowMap = PORTRAIT_WEDDING_ALLOW
        if type(fileData) == "table" and type(fileData.allowedProfiles) == "table" then
            local fromFile = allowMapFromIdList(fileData.allowedProfiles)
            if next(fromFile) ~= nil then
                allowMap = fromFile
            end
        end
    end

    cachedState = {
        licenseTier = tier,
        allowMap = allowMap,
        productName = productName,
        sku = sku,
        upgradeSku = upgradeSku,
        profileCount = tier == "full_collection" and 0 or #M.PORTRAIT_WEDDING_PROFILE_IDS,
    }
    return cachedState
end

function M.reload()
    cachedState = nil
    return resolveState()
end

function M.getLicenseTier()
    return tostring((resolveState()).licenseTier or "portrait_wedding")
end

function M.getProductName()
    return tostring((resolveState()).productName or "")
end

function M.getSku()
    return tostring((resolveState()).sku or "")
end

function M.getUpgradeSku()
    return tostring((resolveState()).upgradeSku or M.SKU_FULL_COLLECTION)
end

function M.isFullCollection()
    return M.getLicenseTier() == "full_collection"
end

function M.isProfileAllowed(emulsionId)
    local id = tostring(emulsionId or "")
    if id == "" or id == "__original__" then
        return true
    end
    local state = resolveState()
    if state.licenseTier == "full_collection" or state.allowMap == nil then
        return true
    end
    return state.allowMap[id] == true
end

function M.getAllowedProfileIds()
    local state = resolveState()
    if state.licenseTier == "full_collection" or state.allowMap == nil then
        return nil
    end
    local ids = {}
    for id, allowed in pairs(state.allowMap) do
        if allowed == true then
            ids[#ids + 1] = id
        end
    end
    table.sort(ids)
    return ids
end

function M.getUpgradeBanner()
    if M.isFullCollection() then
        return nil
    end
    if M.getSku() == "AS-DEMO-000" then
        return "Demo active - Leicachrome and HP5 unlocked. Unlock the Full Collection for all film worlds."
    end
    return "Portrait & Wedding Pack active - Upgrade to Full Collection for all film worlds."
end

return M
