local addonName, RF = ...

-------------------------------------------------------------------------------
-- AttendanceManager: track per-Team raid attendance sessions and compute a
-- rolling attendance % per member. Recording is always manual (an officer
-- clicks "Record Attendance" while grouped) -- there is no automatic
-- detection here.
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
-- Live group/raid membership
-------------------------------------------------------------------------------
function RF:GetCurrentGroupMemberNames()
    local names = {}
    if IsInRaid() then
        local n = GetNumGroupMembers()
        for i = 1, n do
            local name, realm = UnitName("raid" .. i)
            if name then
                local full = (realm and realm ~= "") and (name .. "-" .. realm) or name
                tinsert(names, Ambiguate(full, "guild"))
            end
        end
    elseif IsInGroup() then
        -- Party unit IDs exclude the player; GetNumGroupMembers() counts the
        -- player, so party indices run 1..(count-1) and "player" is added separately.
        local pName, pRealm = UnitName("player")
        local pFull = (pRealm and pRealm ~= "") and (pName .. "-" .. pRealm) or pName
        tinsert(names, Ambiguate(pFull, "guild"))
        local n = GetNumGroupMembers()
        for i = 1, n - 1 do
            local name, realm = UnitName("party" .. i)
            if name then
                local full = (realm and realm ~= "") and (name .. "-" .. realm) or name
                tinsert(names, Ambiguate(full, "guild"))
            end
        end
    end
    return names
end

-------------------------------------------------------------------------------
-- Compute (without writing) who on `teamID` is currently in the player's
-- group. Returns a sorted name array, or (nil, errString) on failure.
-------------------------------------------------------------------------------
function RF:PreviewAttendanceSession(teamID)
    local team = RF:GetTeam(teamID)
    if not team then return nil, "No such team" end
    if not (IsInRaid() or IsInGroup()) then return nil, "You are not in a group or raid" end

    local groupNames = RF:GetCurrentGroupMemberNames()
    local present = {}
    for _, n in ipairs(groupNames) do
        if team.members[n] then tinsert(present, n) end
    end
    table.sort(present)
    return present
end

-------------------------------------------------------------------------------
-- Record (or merge into) today's attendance session for teamID.
-- Returns the session record, or (nil, errString).
-------------------------------------------------------------------------------
function RF:RecordAttendanceSession(teamID)
    local present, err = RF:PreviewAttendanceSession(teamID)
    if not present then return nil, err end
    if #present == 0 then return nil, "No members of this team detected in your current group" end

    local guildDB = RF:GetGuildDB()
    if not guildDB then return nil, "No guild data" end
    if not guildDB.attendance[teamID] then guildDB.attendance[teamID] = {} end
    local sessions = guildDB.attendance[teamID]

    local d, ts = date("%Y-%m-%d"), time()
    local existing
    for _, s in ipairs(sessions) do
        if s.date == d then existing = s; break end
    end

    local session
    if existing then
        for _, n in ipairs(present) do existing.attendees[n] = true end
        existing.ts = ts
        session = existing
    else
        local attendeeSet = {}
        for _, n in ipairs(present) do attendeeSet[n] = true end
        session = { date = d, sessionEpoch = ts, ts = ts, attendees = attendeeSet }
        tinsert(sessions, session)
        while #sessions > RF.MAX_ATTENDANCE_SESSIONS do
            tremove(sessions, 1)
        end
    end

    local team = RF:GetTeam(teamID)
    RF:AddLog("ATTENDANCE", format("Recorded attendance for %s: %d present (%s)", team and team.name or teamID, #present, d))
    RF:FireCallbacks("ATTENDANCE_CHANGED", teamID)
    return session
end

-------------------------------------------------------------------------------
-- Rolling-window stats: { totalSessions = N, memberCounts = { [name] = presentCount } }
-------------------------------------------------------------------------------
function RF:GetTeamAttendanceStats(teamID, days)
    days = days or RF.ATTENDANCE_LOOKBACK_DAYS
    local guildDB = RF:GetGuildDB()
    local stats = { totalSessions = 0, memberCounts = {} }
    if not guildDB or not guildDB.attendance[teamID] then return stats end

    local cutoff = time() - days * 86400
    for _, s in ipairs(guildDB.attendance[teamID]) do
        if s.sessionEpoch >= cutoff then
            stats.totalSessions = stats.totalSessions + 1
            for n in pairs(s.attendees) do
                stats.memberCounts[n] = (stats.memberCounts[n] or 0) + 1
            end
        end
    end
    return stats
end

-------------------------------------------------------------------------------
-- Convenience single-member lookup. Returns nil (not 0) when there is no
-- session data in the window yet, so the UI can render "-" instead of a
-- misleading 0%.
-------------------------------------------------------------------------------
function RF:GetMemberAttendancePercent(teamID, memberName, days)
    local stats = RF:GetTeamAttendanceStats(teamID, days)
    if stats.totalSessions == 0 then return nil end
    local present = stats.memberCounts[memberName] or 0
    return math.floor((present / stats.totalSessions) * 100 + 0.5), present, stats.totalSessions
end
