local _AddonName, _EchoRaidTools = ...;


local module = _EchoRaidTools:GetModule("EditModeTools")

local eventFrame = CreateFrame("Frame")
local state = {
    partyMembers = 1,
    specID = 1,
}
local trackedProfiles = {}



local function getFirstActiveProfile(event)
    assert(event)
    local profilesToCheck = trackedProfiles[event]
    if not profilesToCheck then return end
    for name, funcs in pairs(profilesToCheck) do
        local shouldBeActive = true
        for i, func in ipairs(funcs) do
            if not func() then
                shouldBeActive = false
                break
            end
        end
        if shouldBeActive then return name end
    end
end

local function setProfile(profileName)
    if not profileName then return end
    local profiles, activeProfile = module:GetEditModeProfiles()
    for num, name in ipairs(profiles) do
        if name == profileName then
            if num == activeProfile then return end
            print(string.format("EditModeTools: Activating Profile %s", profileName))
            C_EditMode.SetActiveLayout(num)
            return
        end
    end
end

local function setFirstActiveProfile(event)
    setProfile(getFirstActiveProfile(event))
    C_Timer.After(1, function()
        local profileThatShouldBeActive = getFirstActiveProfile(event)
        local profiles, current = module:GetEditModeProfiles()
        local currentProfileName = profiles[current]
        if currentProfileName == profileThatShouldBeActive then return end
        setFirstActiveProfile(event)
    end)
end

local function onEvent(self, event, ...)
    local changed = false
    if event == "GROUP_ROSTER_UPDATE" then
        local members = GetNumGroupMembers()
        members = members == 0 and 1 or members
        changed = members ~= state.partyMembers
        state.partyMembers = members
    elseif event == "ACTIVE_PLAYER_SPECIALIZATION_CHANGED" then
        local specID = GetSpecializationInfo(GetSpecialization() or 0)
        changed = specID ~= state.specID
        state.specID = specID
    elseif event == "INSTANCE_GROUP_SIZE_CHANGED" or event == "PLAYER_MAP_CHANGED" then
        local name, instanceType, difficultyID, difficultyName, maxPlayers, dynamicDifficulty, isDynamic, instanceID, instanceGroupSize, LfgDungeonID =
            GetInstanceInfo()
        if instanceID == 1153 or instanceID == 1159 then difficultyID = 0 end -- garrison

        changed = state.difficultyID ~= difficultyID
        state.difficultyID = difficultyID
    elseif event == "FORCE" then
        for _event, _ in pairs(trackedProfiles) do
            onEvent(self, _event, ...)
        end
    end
    if changed then
        setFirstActiveProfile(event)
    end
end
eventFrame:SetScript("OnEvent", onEvent)


local function registerEvents(eventTable)
    eventFrame:UnregisterAllEvents()
    if not eventTable then return end
    for i, event in pairs(eventTable) do
        eventFrame:RegisterEvent(event)
    end
end

---full refresh
function module:UpdateEventHandler()
    trackedProfiles = {}
    if not module:GetModuleState() then
        registerEvents()
        return
    end



    local events = {}
    local profiles, currentProfile = module:GetEditModeProfiles()

    for i, name in ipairs(profiles) do
        local funcs = {}
        local profileEvents = {}
        local profileSettings = module:GetStoredSettingsForProfile(name)

        if profileSettings.Spec.Enabled then
            table.insert(funcs, function()
                return profileSettings.Spec.Specs[state.specID] and true or false
            end)
            table.insert(profileEvents, "ACTIVE_PLAYER_SPECIALIZATION_CHANGED")
        end

        if profileSettings.GroupSize.Enabled then
            table.insert(funcs, function()
                return state.partyMembers >= profileSettings.GroupSize.Min and
                    state.partyMembers <= profileSettings.GroupSize.Max and true or false
            end)
            table.insert(profileEvents, "GROUP_ROSTER_UPDATE")
        end

        if profileSettings.InstanceType and profileSettings.InstanceType.Enabled then
            table.insert(funcs, function()
                return profileSettings.InstanceType.InstanceTypes[state.difficultyID] and true or false
            end)
            table.insert(profileEvents, "INSTANCE_GROUP_SIZE_CHANGED")
            table.insert(profileEvents, "PLAYER_MAP_CHANGED")
        end

        for _, event in ipairs(profileEvents) do
            tInsertUnique(events, event)
            trackedProfiles[event] = trackedProfiles[event] or {}
            trackedProfiles[event][name] = funcs
        end
    end

    registerEvents(events)
    onEvent(nil, "FORCE")
end

--[[
    if not db.Profiles[profileName] then
        db.Profiles[profileName] = {}
        local profile = db.Profiles[profileName]
        profile.Spec = {}
        profile.Spec.Enabled = false
        profile.Spec.Specs = {}
        ---profile.Spec.Specs[123] = true
        profile.GroupSize = {}
        profile.GroupSize.Enabled = false
        profile.GroupSize.Min = 0
        profile.GroupSize.Max = 0
    end
    return db.Profiles[profileName]
]] --
