_G.LIDCOUNCIL_CreateLootSessionHelpers_Impl = function(deps)
  deps = type(deps) == "table" and deps or {}

  local TrimText = deps.TrimText
  local DeepCopy = deps.DeepCopy
  local RootDB = deps.RootDB
  local GetLootProfile = deps.GetLootProfile
  local GetCharacterKey = deps.GetCharacterKey
  local NormalizeLootRollOptions = deps.NormalizeLootRollOptions
  local EnsureLootProfileDefaults = deps.EnsureLootProfileDefaults
  local EnsureLootProfilePermissionState = deps.EnsureLootProfilePermissionState
  local GetLootProfileMaster = deps.GetLootProfileMaster
  local GetLootProfileAccessInfo = deps.GetLootProfileAccessInfo
  local NormalizeLootProfileRole = deps.NormalizeLootProfileRole
  local GetLootProfileRoleLocal = deps.GetLootProfileRoleLocal
  local EnsureLootLedgerMetaEntry = deps.EnsureLootLedgerMetaEntry
  local GetLocalAutoPassEnabled = deps.GetLocalAutoPassEnabled
  local TouchLootProfile = deps.TouchLootProfile
  local TouchPermissions = deps.TouchPermissions
  local RemoveLootProfilePermissionMember = deps.RemoveLootProfilePermissionMember
  local SetLootProfilePermissionMember = deps.SetLootProfilePermissionMember

  local function FirstNonEmptyText(...)
    for index = 1, select("#", ...) do
      local candidate = TrimText(select(index, ...))
      if candidate ~= "" then
        return candidate
      end
    end
    return ""
  end

  local function ResolveBooleanValue(...)
    for index = 1, select("#", ...) do
      local candidate = select(index, ...)
      if candidate ~= nil then
        return candidate and true or false
      end
    end
    return nil
  end

  local function BuildLocalSessionMemberDetails(characterKey)
    local resolvedKey = TrimText(characterKey)
    local selfKey = type(GetCharacterKey) == "function" and TrimText(GetCharacterKey() or "") or ""
    if resolvedKey == "" or selfKey == "" or resolvedKey ~= selfKey then
      return {}
    end

    local className = ""
    local classFile = ""
    if type(UnitClass) == "function" then
      className, classFile = UnitClass("player")
      className = TrimText(className)
      classFile = TrimText(classFile)
    end

    local specName = ""
    local specIcon = ""
    if type(GetSpecialization) == "function" and type(GetSpecializationInfo) == "function" then
      local specIndex = GetSpecialization()
      if specIndex then
        local _, localizedSpecName, _, localizedSpecIcon = GetSpecializationInfo(specIndex)
        specName = TrimText(localizedSpecName)
        specIcon = TrimText(localizedSpecIcon)
      end
    end

    local addonVersion = ""
    if type(GetAddOnMetadata) == "function" then
      addonVersion = TrimText(GetAddOnMetadata("LidCouncil", "Version"))
    end
    if addonVersion == "" and type(C_AddOns) == "table" and type(C_AddOns.GetAddOnMetadata) == "function" then
      addonVersion = TrimText(C_AddOns.GetAddOnMetadata("LidCouncil", "Version"))
    end

    local clientVersion = ""
    if type(GetBuildInfo) == "function" then
      clientVersion = TrimText(select(1, GetBuildInfo()))
    end

    local localAutoPassEnabled = true
    if type(GetLocalAutoPassEnabled) == "function" then
      localAutoPassEnabled = GetLocalAutoPassEnabled() and true or false
    end

    return {
      className = className,
      classFile = classFile,
      specName = specName,
      specIcon = specIcon,
      addonVersion = addonVersion,
      clientVersion = clientVersion,
      localAutoPassEnabled = localAutoPassEnabled,
      lastSyncAt = time and time() or 0,
    }
  end

  local function ApplySessionMemberDetails(profile, memberKey, member, details)
    if type(member) ~= "table" then
      return nil
    end

    local resolvedKey = TrimText(memberKey)
    if resolvedKey == "" then
      return member
    end

    local incoming = type(details) == "table" and details or {}
    local fallback = BuildLocalSessionMemberDetails(resolvedKey)

    member.name = resolvedKey
    member.status = TrimText(incoming.status or member.status or "JOINED")
    if member.status == "" then
      member.status = "JOINED"
    end
    member.joinedAt = tonumber(incoming.joinedAt) or tonumber(member.joinedAt) or (time and time() or 0)
    if string.upper(member.status) == "JOINED" then
      member.leftAt = nil
    else
      member.leftAt = tonumber(incoming.leftAt) or tonumber(member.leftAt)
    end
    member.className = FirstNonEmptyText(incoming.className, member.className, fallback.className)
    member.classFile = FirstNonEmptyText(incoming.classFile, member.classFile, fallback.classFile)
    member.specName = FirstNonEmptyText(incoming.specName, member.specName, fallback.specName)
    member.specIcon = FirstNonEmptyText(incoming.specIcon, member.specIcon, fallback.specIcon)
    member.addonVersion = FirstNonEmptyText(incoming.addonVersion, member.addonVersion, fallback.addonVersion)
    member.clientVersion = FirstNonEmptyText(incoming.clientVersion, member.clientVersion, fallback.clientVersion)
    member.sharedProfileId = FirstNonEmptyText(incoming.sharedProfileId, incoming.profileId, member.sharedProfileId)
    member.settingsRevision = math.max(0, tonumber(incoming.settingsRevision) or tonumber(member.settingsRevision) or 0)
    member.permissionsRevision = math.max(0, tonumber(incoming.permissionsRevision) or tonumber(member.permissionsRevision) or 0)
    member.operationalRevision = math.max(0, tonumber(incoming.operationalRevision) or tonumber(member.operationalRevision) or 0)
    member.lootRevision = math.max(0, tonumber(incoming.lootRevision) or tonumber(member.lootRevision) or 0)
    member.sessionRevision = math.max(0, tonumber(incoming.sessionRevision) or tonumber(member.sessionRevision) or 0)
    member.settingsChecksum = FirstNonEmptyText(incoming.settingsChecksum, member.settingsChecksum)
    member.permissionsChecksum = FirstNonEmptyText(incoming.permissionsChecksum, member.permissionsChecksum)
    member.operationalChecksum = FirstNonEmptyText(incoming.operationalChecksum, member.operationalChecksum)
    member.lootChecksum = FirstNonEmptyText(incoming.lootChecksum, member.lootChecksum)
    member.sessionChecksum = FirstNonEmptyText(incoming.sessionChecksum, member.sessionChecksum)
    member.profileUpdatedAt = math.max(0, tonumber(incoming.profileUpdatedAt) or tonumber(incoming.updatedAt) or tonumber(member.profileUpdatedAt) or 0)
    member.localAutoPassEnabled = ResolveBooleanValue(
      incoming.localAutoPassEnabled,
      incoming.autoPassLocalEnabled,
      member.localAutoPassEnabled,
      fallback.localAutoPassEnabled,
      true
    )
    member.lastSyncAt = tonumber(incoming.lastSyncAt) or tonumber(incoming.syncAt) or tonumber(member.lastSyncAt) or tonumber(fallback.lastSyncAt) or (time and time() or 0)
    member.profileMaster = FirstNonEmptyText(incoming.profileMaster, incoming.master, member.profileMaster)
    local resolvedIncomingRole = TrimText(incoming.role or member.role)
    member.role = resolvedIncomingRole ~= "" and NormalizeLootProfileRole(resolvedIncomingRole) or ""

    local permissionsChanged = false
    local operationalChanged = false

    if member.profileMaster ~= "" or member.role ~= "" then
      local permissions = EnsureLootProfilePermissionState(profile, member.profileMaster)
      local priorMaster = TrimText(permissions.master)
      local priorRole = type(GetLootProfileRoleLocal) == "function" and GetLootProfileRoleLocal(profile, resolvedKey) or ""
      if member.profileMaster ~= "" and string.lower(TrimText(permissions.master)) ~= string.lower(member.profileMaster) then
        permissions.master = member.profileMaster
        permissionsChanged = true
      end
      if TrimText(permissions.master) ~= "" and type(RemoveLootProfilePermissionMember) == "function" then
        permissionsChanged = RemoveLootProfilePermissionMember(permissions, permissions.master) or permissionsChanged
      end
      if member.role ~= "" then
        if TrimText(permissions.master) ~= "" and string.lower(TrimText(permissions.master)) == string.lower(resolvedKey) then
          if type(RemoveLootProfilePermissionMember) == "function" then
            permissionsChanged = RemoveLootProfilePermissionMember(permissions, resolvedKey) or permissionsChanged
          end
        else
          if type(SetLootProfilePermissionMember) == "function" then
            SetLootProfilePermissionMember(permissions, resolvedKey, member.role)
          end
        end
      end
      permissionsChanged = permissionsChanged
        or priorMaster ~= TrimText(permissions.master)
        or priorRole ~= (type(GetLootProfileRoleLocal) == "function" and GetLootProfileRoleLocal(profile, resolvedKey) or "")
    end

    local meta = EnsureLootLedgerMetaEntry(profile, resolvedKey)
    if meta then
      if member.className ~= "" then
        operationalChanged = operationalChanged or meta.className ~= member.className
        meta.className = member.className
      end
      if member.classFile ~= "" then
        operationalChanged = operationalChanged or meta.classFile ~= member.classFile
        meta.classFile = member.classFile
      end
      if member.specName ~= "" then
        operationalChanged = operationalChanged or meta.specName ~= member.specName
        meta.specName = member.specName
      end
      if member.specIcon ~= "" then
        operationalChanged = operationalChanged or meta.specIcon ~= member.specIcon
        meta.specIcon = member.specIcon
      end
    end

    return member, {
      permissionsChanged = permissionsChanged,
      operationalChanged = operationalChanged,
    }
  end

  local function MakeSessionId()
    local now = time and time() or 0
    local randomPart = math.random(1000, 9999)
    return string.format("SESSION-%d-%d", now, randomPart)
  end

  local function NormalizeSessionStatus(status)
    local resolved = string.upper(TrimText(status or ""))
    if resolved == "" then
      resolved = "ACTIVE"
    end
    return resolved
  end

  local function IsOpenLootSessionStatus(status)
    local resolved = NormalizeSessionStatus(status)
    return resolved == "PREPARING" or resolved == "ACTIVE"
  end

  local function EnsureLootRootState(root)
    root = root or RootDB()
    root.sessionState = root.sessionState or {}
    if root.sessionState.active == nil then
      root.sessionState.active = false
    end
    root.sessionState.profileName = root.sessionState.profileName or nil
    root.sessionState.sessionId = root.sessionState.sessionId or nil
    root.sessionState.host = root.sessionState.host or nil
    root.sessionState.startedAt = tonumber(root.sessionState.startedAt) or nil
    return root.sessionState
  end

  local function SetLootRootSessionState(root, active, profileName, sessionId, host, startedAt)
    local state = EnsureLootRootState(root)
    state.active = active and true or false
    state.profileName = state.active and profileName or nil
    state.sessionId = state.active and sessionId or nil
    state.host = state.active and host or nil
    state.startedAt = state.active and (tonumber(startedAt) or 0) or nil
    return state
  end

  local function ActivateLocalSessionProfile(root, profileName)
    root = root or RootDB()
    local resolvedProfileName = TrimText(profileName)
    if resolvedProfileName == "" or type(root.profiles) ~= "table" or type(root.profiles[resolvedProfileName]) ~= "table" then
      return false
    end

    for otherName, otherProfile in pairs(root.profiles or {}) do
      if type(otherProfile) == "table" then
        EnsureLootProfileDefaults(otherProfile)
        otherProfile.settings = type(otherProfile.settings) == "table" and otherProfile.settings or {}
        otherProfile.settings.enabled = tostring(otherName) == tostring(resolvedProfileName)
      end
    end

    root.currentProfile = resolvedProfileName
    root.ui = type(root.ui) == "table" and root.ui or {}
    if resolvedProfileName ~= "Simulation" then
      root.ui.lastNonSimulationProfile = resolvedProfileName
    end
    return true
  end

  local function FindActiveSessionByState(root)
    root = root or RootDB()
    local state = EnsureLootRootState(root)
    if not state.active or not state.profileName or not state.sessionId then
      return nil
    end

    local profile = root.profiles[state.profileName]
    if type(profile) ~= "table" or type(profile.sessions) ~= "table" then
      return nil
    end

    for i = #profile.sessions, 1, -1 do
      local session = profile.sessions[i]
      if type(session) == "table" and session.id == state.sessionId then
        if not IsOpenLootSessionStatus(session.status) then
          return nil
        end
        return session, state.profileName, profile
      end
    end
    return nil
  end

  local function CollectActiveLootSessions(root)
    root = root or RootDB()
    local activeSessions = {}
    for profileName, profile in pairs(root.profiles or {}) do
      if type(profile) == "table" and type(profile.sessions) == "table" then
        for _, session in ipairs(profile.sessions) do
          if type(session) == "table" and IsOpenLootSessionStatus(session.status) then
            activeSessions[#activeSessions + 1] = {
              profile = profile,
              profileName = tostring(profileName),
              session = session,
            }
          end
        end
      end
    end

    table.sort(activeSessions, function(a, b)
      local aStarted = tonumber(a.session and a.session.startedAt) or 0
      local bStarted = tonumber(b.session and b.session.startedAt) or 0
      if aStarted == bStarted then
        local aProfile = string.lower(tostring(a.profileName or ""))
        local bProfile = string.lower(tostring(b.profileName or ""))
        if aProfile == bProfile then
          return string.lower(tostring(a.session and a.session.id or "")) < string.lower(tostring(b.session and b.session.id or ""))
        end
        return aProfile < bProfile
      end
      return aStarted > bStarted
    end)

    return activeSessions
  end

  local function NormalizeActiveLootSessions(root)
    root = root or RootDB()

    local activeSessions = CollectActiveLootSessions(root)
    local primarySession, primaryProfileName, primaryProfile = FindActiveSessionByState(root)
    if not primarySession and activeSessions[1] then
      primarySession = activeSessions[1].session
      primaryProfileName = activeSessions[1].profileName
      primaryProfile = activeSessions[1].profile
    end

    if primarySession then
      primarySession.profileName = primaryProfileName
      ActivateLocalSessionProfile(root, primaryProfileName)
      SetLootRootSessionState(root, true, primaryProfileName, primarySession.id, primarySession.host, primarySession.startedAt)
    else
      SetLootRootSessionState(root, false)
    end

    if #activeSessions > 1 then
      local endedAt = time and time() or 0
      for _, entry in ipairs(activeSessions) do
        local keepThis = primarySession and entry.session == primarySession and tostring(entry.profileName or "") == tostring(primaryProfileName or "")
        if not keepThis then
          entry.session.status = "FINISHED"
          entry.session.endedAt = tonumber(entry.session.endedAt) or endedAt
          entry.session.durationSeconds = math.max(0, (tonumber(entry.session.endedAt) or endedAt) - (tonumber(entry.session.startedAt) or (tonumber(entry.session.endedAt) or endedAt)))
          TouchLootProfile(entry.profile)
        end
      end
    end

    return primarySession, primaryProfileName, primaryProfile
  end

  local function FindLootSession(profile, sessionId)
    if type(profile) ~= "table" or type(profile.sessions) ~= "table" then
      return nil
    end
    local resolvedId = TrimText(sessionId)
    if resolvedId == "" then
      return nil
    end
    for i = #profile.sessions, 1, -1 do
      local session = profile.sessions[i]
      if type(session) == "table" and session.id == resolvedId then
        return session, i
      end
    end
    return nil
  end

  local function GetActiveLootSession()
    local root = RootDB()
    local state = EnsureLootRootState(root)
    if not state.active or not state.profileName or not state.sessionId then
      return nil
    end
    local profile = root.profiles[state.profileName]
    if type(profile) ~= "table" or type(profile.sessions) ~= "table" then
      return nil
    end
    for i = #profile.sessions, 1, -1 do
      local session = profile.sessions[i]
      if type(session) == "table" and session.id == state.sessionId then
        if not IsOpenLootSessionStatus(session.status) then
          SetLootRootSessionState(root, false)
          return nil
        end
        return session, state.profileName
      end
    end
    SetLootRootSessionState(root, false)
    return nil
  end

  local function StartLootSession(name)
    local profileName = TrimText(name)
    if profileName == "" then
      return false, "Create and select a loot profile before starting a loot session."
    end
    local access = GetLootProfileAccessInfo(profileName)
    if not access.canStartSession then
      return false, "Only the Master or a Council Member can start a loot session."
    end
    local root = RootDB()
    NormalizeActiveLootSessions(root)
    local existingSession = GetActiveLootSession()
    if existingSession then
      return false, "A loot session is already open."
    end
    local profile = select(1, GetLootProfile(profileName))
    local sessionId = MakeSessionId()
    local host = GetCharacterKey() or "Unknown"
    local startedAt = time and time() or 0
    EnsureLootProfilePermissionState(profile, GetLootProfileMaster(profileName) ~= "" and GetLootProfileMaster(profileName) or host)
    local session = {
      id = sessionId,
      profileName = profileName,
      remoteProfileName = profileName,
      profileId = TrimText(type(profile.meta) == "table" and profile.meta.profileId or ""),
      host = host,
      status = "PREPARING",
      startedAt = startedAt,
      endedAt = nil,
      durationSeconds = nil,
      acceptedBySelf = true,
      sharedByUpdate = false,
      sharedProfileReady = true,
      rollOptions = NormalizeLootRollOptions(profile.settings and profile.settings.rollOptions),
      members = {
        [host] = {
          name = host,
          status = "JOINED",
          joinedAt = startedAt,
        },
      },
    }
    profile.sessions[#profile.sessions + 1] = session
    local _, changeSet = ApplySessionMemberDetails(profile, host, session.members[host], {
      status = "JOINED",
      joinedAt = startedAt,
      lastSyncAt = startedAt,
    })
    SetLootRootSessionState(root, true, profileName, sessionId, host, startedAt)
    TouchLootProfile(profile)
    if type(changeSet) == "table" and changeSet.permissionsChanged and type(TouchPermissions) == "function" then
      TouchPermissions(profile)
    end
    return session
  end

  local function ActivateLootSession(name, sessionId)
    local root = RootDB()
    local activeSession, activeProfileName = GetActiveLootSession()
    if type(activeSession) ~= "table" or TrimText(activeProfileName) == "" then
      return false, "Prepare a loot session before starting it."
    end

    local profileName = TrimText(name)
    if profileName == "" then
      profileName = activeProfileName
    end
    if TrimText(activeProfileName) ~= profileName then
      return false, "Only the prepared session profile can be started."
    end

    local resolvedSessionId = TrimText(sessionId)
    if resolvedSessionId ~= "" and TrimText(activeSession.id) ~= resolvedSessionId then
      return false, "Prepared session id does not match."
    end

    local access = GetLootProfileAccessInfo(profileName)
    if not access.canStartSession then
      return false, "Only the Master or a Council Member can start a prepared loot session."
    end

    local selfKey = TrimText(GetCharacterKey() or "")
    if selfKey == "" or string.lower(TrimText(activeSession.host or "")) ~= string.lower(selfKey) then
      return false, "Only the prepared session host can start the session."
    end

    local status = NormalizeSessionStatus(activeSession.status)
    if status == "ACTIVE" then
      return activeSession, profileName
    end
    if status ~= "PREPARING" then
      return false, "Only prepared sessions can be started."
    end

    local profile = root.profiles and root.profiles[profileName] or nil
    if type(profile) ~= "table" then
      return false, "Prepared session profile is missing."
    end

    activeSession.status = "ACTIVE"
    activeSession.activatedAt = time and time() or 0
    activeSession.rollOptions = NormalizeLootRollOptions(profile.settings and profile.settings.rollOptions)
    activeSession.sharedProfileReady = true
    SetLootRootSessionState(root, true, profileName, activeSession.id, activeSession.host, activeSession.startedAt)
    TouchLootProfile(profile)
    return activeSession, profileName
  end

  local function GetLootSession(name, sessionId)
    local profile, profileName = GetLootProfile(name)
    local session = FindLootSession(profile, sessionId)
    return session, profileName, profile
  end

  local function JoinLootSession(name, sessionData, joinMode)
    local root = RootDB()
    local profileName = TrimText(name)
    if profileName == "" then
      return false, "A valid loot profile is required to join this loot session."
    end
    local data = type(sessionData) == "table" and DeepCopy(sessionData) or {}
    local sessionId = TrimText(data.id or data.sessionId)
    if sessionId == "" then
      return false, "Session id is required."
    end

    NormalizeActiveLootSessions(root)
    local existingSession, existingProfileName = GetActiveLootSession()
    local incomingStatus = TrimText(data.status)
    if incomingStatus == "" then
      incomingStatus = "PREPARING"
    end
    if existingSession and IsOpenLootSessionStatus(incomingStatus) then
      local sameSession = tostring(existingSession.id or "") == tostring(sessionId)
        and tostring(existingProfileName or existingSession.profileName or "") == tostring(profileName)
      if not sameSession then
        return false, "A loot session is already open."
      end
    end

    local profile = select(1, GetLootProfile(profileName))
    local session = FindLootSession(profile, sessionId)
    if type(session) ~= "table" then
      session = {
        id = sessionId,
        profileName = profileName,
        remoteProfileName = TrimText(data.remoteProfileName or data.profileName or profileName),
        host = nil,
        status = incomingStatus,
        startedAt = tonumber(data.startedAt) or (time and time() or 0),
        activatedAt = tonumber(data.activatedAt),
        endedAt = nil,
        durationSeconds = nil,
        acceptedBySelf = false,
        sharedByUpdate = false,
        sharedProfileReady = data.sharedProfileReady ~= false,
        rollOptions = NormalizeLootRollOptions(data.rollOptions),
        members = {},
      }
      profile.sessions[#profile.sessions + 1] = session
    end

    session.profileName = profileName
    session.remoteProfileName = TrimText(data.remoteProfileName or data.profileName or session.remoteProfileName or profileName)
    session.profileId = TrimText(data.profileId or session.profileId or "")
    session.host = TrimText(data.host or session.host or "")
    if session.host == "" then
      session.host = "Unknown"
    end
    EnsureLootProfilePermissionState(profile, TrimText(data.profileMaster) ~= "" and data.profileMaster or session.host)
    session.status = TrimText(data.status or session.status or incomingStatus)
    if session.status == "" then
      session.status = incomingStatus
    end
    session.startedAt = tonumber(data.startedAt) or tonumber(session.startedAt) or (time and time() or 0)
    session.activatedAt = tonumber(data.activatedAt) or tonumber(session.activatedAt)
    session.endedAt = tonumber(data.endedAt) or tonumber(session.endedAt)
    session.durationSeconds = tonumber(data.durationSeconds) or tonumber(session.durationSeconds)
    if data.sharedProfileReady ~= nil then
      session.sharedProfileReady = data.sharedProfileReady and true or false
    elseif session.sharedProfileReady == nil then
      session.sharedProfileReady = true
    end
    if type(data.rollOptions) == "table" and #data.rollOptions > 0 then
      session.rollOptions = NormalizeLootRollOptions(data.rollOptions)
    elseif type(session.rollOptions) ~= "table" or #session.rollOptions == 0 then
      session.rollOptions = NormalizeLootRollOptions(profile.settings and profile.settings.rollOptions)
    end

    local resolvedJoinMode = TrimText(joinMode)
    if resolvedJoinMode == "UPDATE" then
      session.acceptedBySelf = false
      session.sharedByUpdate = true
    elseif resolvedJoinMode ~= "" then
      session.acceptedBySelf = true
      session.sharedByUpdate = false
    elseif session.acceptedBySelf == nil then
      session.acceptedBySelf = false
    end

    local permissionsChanged = false
    if type(data.members) == "table" then
      session.members = {}
      for memberKey, member in pairs(data.members) do
        local resolvedKey = TrimText(memberKey ~= "" and memberKey or (type(member) == "table" and member.name or ""))
        if resolvedKey ~= "" then
          session.members[resolvedKey] = {
            name = resolvedKey,
            status = TrimText(type(member) == "table" and member.status or "JOINED"),
            joinedAt = tonumber(type(member) == "table" and member.joinedAt) or session.startedAt,
          }
          if session.members[resolvedKey].status == "" then
            session.members[resolvedKey].status = "JOINED"
          end
          local _, changeSet = ApplySessionMemberDetails(profile, resolvedKey, session.members[resolvedKey], type(member) == "table" and member or nil)
          permissionsChanged = permissionsChanged or (type(changeSet) == "table" and changeSet.permissionsChanged) or false
        end
      end
    else
      session.members = session.members or {}
    end

    if session.host and session.host ~= "" then
      session.members[session.host] = session.members[session.host] or {
        name = session.host,
        status = "JOINED",
        joinedAt = session.startedAt,
      }
      local hostDetails = {
        profileMaster = data.profileMaster,
        localAutoPassEnabled = false,
      }
      local _, changeSet = ApplySessionMemberDetails(profile, session.host, session.members[session.host], hostDetails)
      permissionsChanged = permissionsChanged or (type(changeSet) == "table" and changeSet.permissionsChanged) or false
    end

    if IsOpenLootSessionStatus(session.status) then
      ActivateLocalSessionProfile(root, profileName)
      SetLootRootSessionState(root, true, profileName, session.id, session.host, session.startedAt)
    else
      local state = EnsureLootRootState(root)
      if state.sessionId == session.id and state.profileName == profileName then
        SetLootRootSessionState(root, false)
      end
    end

    TouchLootProfile(profile)
    if permissionsChanged and type(TouchPermissions) == "function" then
      TouchPermissions(profile)
    end
    return session, profileName
  end

  local function StopLootSession()
    local root = RootDB()
    local session, profileName = GetActiveLootSession()
    if not session then
      return false, "No active session."
    end

    local endedAt = time and time() or 0
    session.status = "FINISHED"
    session.endedAt = endedAt
    session.durationSeconds = math.max(0, endedAt - (tonumber(session.startedAt) or endedAt))
    for _, member in pairs(type(session.members) == "table" and session.members or {}) do
      if type(member) == "table" and string.upper(TrimText(member.status or "JOINED")) == "JOINED" then
        member.leftAt = tonumber(member.leftAt) or endedAt
      end
    end
    SetLootRootSessionState(root, false)
    local profile = root.profiles[profileName]
    TouchLootProfile(profile)
    return true, session
  end

  local function AddLootSessionMember(characterKey)
    local session, profileName = GetActiveLootSession()
    if not session then
      return false, "No active session."
    end
    local memberKey = TrimText(characterKey)
    if memberKey == "" then
      return false, "Character-Realm is required."
    end
    session.members = session.members or {}
    session.members[memberKey] = session.members[memberKey] or {
      name = memberKey,
      status = "JOINED",
      joinedAt = time and time() or 0,
    }
    local root = RootDB()
    local profile = type(profileName) == "string" and root.profiles and root.profiles[profileName] or nil
    if type(profile) == "table" then
      local _, changeSet = ApplySessionMemberDetails(profile, memberKey, session.members[memberKey], nil)
      TouchLootProfile(profile)
      if type(changeSet) == "table" and changeSet.permissionsChanged and type(TouchPermissions) == "function" then
        TouchPermissions(profile)
      end
    end
    return true
  end

  local function UpsertLootSessionMember(name, sessionId, characterKey, memberData)
    local session, _, profile = GetLootSession(name, sessionId)
    if not session then
      return false, "Session not found."
    end

    local memberKey = TrimText(characterKey)
    if memberKey == "" then
      return false, "Character-Realm is required."
    end

    local details = type(memberData) == "table" and memberData or {}
    session.members = session.members or {}
    session.members[memberKey] = session.members[memberKey] or {
      name = memberKey,
      status = "JOINED",
      joinedAt = tonumber(details.joinedAt) or (time and time() or 0),
    }

    local member = session.members[memberKey]
    local _, changeSet = ApplySessionMemberDetails(profile, memberKey, member, details)

    if details.suppressProfileTouch ~= true then
      TouchLootProfile(profile)
    end
    if details.suppressProfileTouch ~= true and type(changeSet) == "table" and changeSet.permissionsChanged and type(TouchPermissions) == "function" then
      TouchPermissions(profile)
    end
    return true, member
  end

  local function RemoveLootSessionMember(name, sessionId, characterKey)
    local session, _, profile = GetLootSession(name, sessionId)
    if not session then
      return false, "Session not found."
    end

    local memberKey = TrimText(characterKey)
    if memberKey == "" then
      return false, "Character-Realm is required."
    end
    if string.lower(TrimText(session.host)) == string.lower(memberKey) then
      return false, "The session host cannot be removed from their own session."
    end

    session.members = type(session.members) == "table" and session.members or {}
    local storedKey = nil
    for key in pairs(session.members) do
      if string.lower(TrimText(key)) == string.lower(memberKey) then
        storedKey = key
        break
      end
    end
    if not storedKey then
      return false, "Session member not found."
    end

    local member = session.members[storedKey]
    if type(member) ~= "table" then
      member = {
        name = storedKey,
        joinedAt = time and time() or 0,
      }
      session.members[storedKey] = member
    end
    member.status = "REMOVED"
    member.leftAt = time and time() or 0
    TouchLootProfile(profile)
    return true, member
  end

  local function FinishLootSession(name, sessionId, endedAt, status)
    local root = RootDB()
    local session, profileName, profile = GetLootSession(name, sessionId)
    if not session then
      return false, "Session not found."
    end

    local resolvedEndedAt = tonumber(endedAt) or (time and time() or 0)
    session.status = TrimText(status or session.status or "FINISHED")
    if session.status == "" then
      session.status = "FINISHED"
    end
    session.endedAt = resolvedEndedAt
    session.durationSeconds = math.max(0, resolvedEndedAt - (tonumber(session.startedAt) or resolvedEndedAt))
    for _, member in pairs(type(session.members) == "table" and session.members or {}) do
      if type(member) == "table" and string.upper(TrimText(member.status or "JOINED")) == "JOINED" then
        member.leftAt = tonumber(member.leftAt) or resolvedEndedAt
      end
    end

    local state = EnsureLootRootState(root)
    if state.sessionId == session.id and state.profileName == profileName then
      SetLootRootSessionState(root, false)
    end

    TouchLootProfile(profile)
    return true, session
  end

  return {
    EnsureLootRootState = EnsureLootRootState,
    SetLootRootSessionState = SetLootRootSessionState,
    FindActiveSessionByState = FindActiveSessionByState,
    CollectActiveLootSessions = CollectActiveLootSessions,
    NormalizeActiveLootSessions = NormalizeActiveLootSessions,
    FindLootSession = FindLootSession,
    StartLootSession = StartLootSession,
    ActivateLootSession = ActivateLootSession,
    GetLootSession = GetLootSession,
    JoinLootSession = JoinLootSession,
    GetActiveLootSession = GetActiveLootSession,
    StopLootSession = StopLootSession,
    AddLootSessionMember = AddLootSessionMember,
    UpsertLootSessionMember = UpsertLootSessionMember,
    RemoveLootSessionMember = RemoveLootSessionMember,
    FinishLootSession = FinishLootSession,
  }
end
