local addonName, NS = ...
local GR = _G["GRS_MainFrame"]

-- Import Helpers
local ParseDate = GR.RR.ParseDate

-- =========================================================================
-- DATABASE SCANNING
-- =========================================================================

function GR:RR_ScanDB()
    if not GRS_RaidRosterDB then GRS_RaidRosterDB = {} end
    if not GRS_RaidRosterDB.events then GRS_RaidRosterDB.events = {} end

    GR.RR.cache = {}
    local list = {}
    for id, evt in pairs(GRS_RaidRosterDB.events) do
        local counts = { TANK=0, HEALER=0, DPS=0, BENCH=0, TENTATIVE=0, ABSENT=0 }
        for role, members in pairs(evt.roster) do counts[role] = #members end
        evt.counts = counts
        table.insert(list, evt)
    end
    table.sort(list, function(a, b) 
        local tA = ParseDate(a.date) or 0
        local tB = ParseDate(b.date) or 0
        return tA < tB 
    end)
    GR.RR.cache = list
    if GR.RR_UpdateLeftPane then GR:RR_UpdateLeftPane() end
end

-- =========================================================================
-- EVENT SELECTION
-- =========================================================================

function GR:RR_SelectEvent(eventData)
    GR.RR.selectedEvent = eventData
    if not eventData then 
        GR.RR.currentRoster = nil
        if GR.RR_UpdateLeftPaneCounters then GR:RR_UpdateLeftPaneCounters() end
        if GR.RR_UpdateRaster then GR:RR_UpdateRaster(nil) end
        return 
    end
    GR.RR.currentRoster = eventData.roster
    if GR.RR_UpdateRaster then GR:RR_UpdateRaster() end
    if GR.RR_UpdateLeftPaneCounters then GR:RR_UpdateLeftPaneCounters() end
end

-- =========================================================================
-- MEMBER STATUS MANAGEMENT
-- =========================================================================

function GR:RR_UpdateMemberStatus(eid, target, role, status, ts)
    local evt = GRS_RaidRosterDB.events[eid]
    if not evt then return end
    
    local cleanName = Ambiguate(target, "none")
    
    -- Remove existing entry for this player (dedup)
    for r, list in pairs(evt.roster) do
        for i=#list, 1, -1 do
            if list[i].name == cleanName then table.remove(list, i) end
        end
    end
    
    -- Status Normalization
    if status then
        status = string.upper(strtrim(status))
    else
        status = "BENCH"
    end
    if status == "NO-SHOW" or status == "NOSHOW" then status = "NOSHOW" end
    
    -- Determine storage bucket
    local bucket = status
    if status == "PRESENT" then
        bucket = role and string.upper(strtrim(role)) or "DPS"
    end
    
    if not evt.roster[bucket] then evt.roster[bucket] = {} end
    
    -- Resolve class from guild roster
    local classFileName = "PRIEST"
    if IsInGuild() then
        local num = GetNumGuildMembers()
        for i = 1, num do
            local n, _, _, _, _, _, _, _, _, _, c = GetGuildRosterInfo(i)
            if n and Ambiguate(n, "none") == cleanName then classFileName = c; break end
        end
    end
    
    table.insert(evt.roster[bucket], {
        name = cleanName,
        class = classFileName,
        ts = ts,
        status = status,
        role = role
    })
    
    -- Update counts
    if not evt.counts then evt.counts = { TANK=0, HEALER=0, DPS=0 } end
    evt.counts.TANK = #(evt.roster["TANK"] or {})
    evt.counts.HEALER = #(evt.roster["HEALER"] or {})
    evt.counts.DPS = #(evt.roster["DPS"] or {})
    
    if GR.RR.selectedEvent and GR.RR.selectedEvent.id == eid then
        GR:RR_SelectEvent(evt)
    end
    if GRS_RR_InspectDlg and GRS_RR_InspectDlg:IsShown() and GR.RR.selectedEvent and GR.RR.selectedEvent.id == eid then
        GR:RR_OpenInspectDialog() 
    end
end

function GR:RR_RemoveMember(eid, target)
    local evt = GRS_RaidRosterDB.events[eid]
    if evt then
        for r, list in pairs(evt.roster) do
            for i=#list, 1, -1 do
                if list[i].name == target then table.remove(list, i) end
            end
        end
        
        if GR.RR.selectedEvent and GR.RR.selectedEvent.id == eid then
            GR:RR_SelectEvent(evt)
        end
        if GRS_RR_InspectDlg and GRS_RR_InspectDlg:IsShown() and GR.RR.selectedEvent and GR.RR.selectedEvent.id == eid then
            GR:RR_OpenInspectDialog()
        end
    end
end

-- =========================================================================
-- LOGGING
-- =========================================================================

function GR:RR_AddLogEntry(author, description)
    if not GRS_RaidRosterDB.logs then GRS_RaidRosterDB.logs = {} end
    local entry = { ts = GetServerTime(), author = author, desc = description }
    table.insert(GRS_RaidRosterDB.logs, 1, entry)
    if #GRS_RaidRosterDB.logs > 100 then
        table.remove(GRS_RaidRosterDB.logs)
    end
    if GRS_RR_LogFrame and GRS_RR_LogFrame:IsShown() and GRS_RR_LogFrame.UpdateLog then
        GRS_RR_LogFrame.UpdateLog()
    end
end

-- =========================================================================
-- CLASS COUNTS (For Tracking Panels)
-- =========================================================================

function GR:RR_FetchClassCounts(includeOffline)
    local counts = {}
    if not IsInGuild() then return counts end
    if C_GuildInfo and C_GuildInfo.GuildRoster then C_GuildInfo.GuildRoster() elseif _G.GuildRoster then _G.GuildRoster() end
    local num = GetNumGuildMembers()
    for i = 1, num do
        local name, _, _, _, _, _, _, _, online, _, classFile = GetGuildRosterInfo(i)
        if classFile then
            if includeOffline or online then
                counts[classFile] = (counts[classFile] or 0) + 1
            end
        end
    end
    return counts
end

-- =========================================================================
-- DATA HELPERS (From Retail)
-- =========================================================================

function GR.RR.GetFullPlayerName()
    local name = UnitName("player")
    return name
end

function GR.RR.GetCanonicalName(fullName)
    if not fullName then return "Unknown" end
    return Ambiguate(fullName, "none")
end

function GR.RR.GetRegionName()
    -- TBC doesn't have GetCurrentRegion, default to EU
    return "eu"
end

function GR.RR.GetFactionID()
    local factionGroup = UnitFactionGroup("player")
    if factionGroup == "Alliance" then return 1 else return 2 end
end

-- =========================================================================
-- SNAPSHOT & TRACKING HELPERS
-- =========================================================================

function GR:RR_TakeSnapshot(panelKey)
    local evt = GR.RR.selectedEvent
    if not evt then return end
    
    GR:RR_AddLogEntry("SYSTEM", "Attendance state verified for " .. (evt.name or "Event"))
    
    if GR.RR.trackingPanels[panelKey] then
        GR.RR.trackingPanels[panelKey].Update()
    end
end

function GR:RR_GetSortedEventIDs(limit)
    if not GRS_RaidRosterDB or not GRS_RaidRosterDB.events then return {} end
    
    local list = {}
    for id, evt in pairs(GRS_RaidRosterDB.events) do
        local ts = GR.RR.ParseDate(evt.date) or 0
        table.insert(list, {id = id, ts = ts})
    end
    
    table.sort(list, function(a,b) return a.ts < b.ts end)
    
    local out = {}
    local start = math.max(1, #list - limit + 1)
    for i = start, #list do
        table.insert(out, list[i].id)
    end
    return out
end

function GR:RR_GetSmartStatus(evtID, playerName)
    local function ScanRoster(rStruct, targetName)
        if not rStruct then return nil end
        local cleanTarget = Ambiguate(targetName, "none")
        for role, members in pairs(rStruct) do
            for _, m in ipairs(members) do
                local cleanName = Ambiguate(m.name or "", "none")
                if cleanTarget == cleanName then
                    return m.status or role
                end
            end
        end
        return nil
    end
    
    local evt = GRS_RaidRosterDB.events[evtID]
    if evt and evt.roster then
        local status = ScanRoster(evt.roster, playerName)
        if status then return status, false end
    end
    
    return nil, false
end

function GR:RR_GetEventDetails(evtID)
    local evt = GRS_RaidRosterDB.events[evtID]
    if evt then
        return { date = evt.date, name = evt.name }
    end
    return { date = nil, name = nil }
end

function GR:RR_RefreshUI(evtID)
    if GR.RR.selectedEvent and GR.RR.selectedEvent.id == evtID then
        GR:RR_SelectEvent(GRS_RaidRosterDB.events[evtID])
    end
    if GRS_RR_InspectDlg and GRS_RR_InspectDlg:IsShown() and GR.RR.selectedEvent and GR.RR.selectedEvent.id == evtID then
        GR:RR_OpenInspectDialog()
    end
    if GR.RR.trackingPanels then
        for _, p in pairs(GR.RR.trackingPanels) do p.Update() end
    end
end

-- =========================================================================
-- COLOR HELPERS (For RaiderIO-like display, returns plain white in TBC)
-- =========================================================================

function GR.RR.ScoreColor(score)
    -- TBC has no RaiderIO scores, return plain white
    return "|cffffffff"
end

function GR.RR.RaidProgressColor(str)
    if not str or str == "-" then return "|cff808080" end
    if string.find(str, "(%d+)/(%d+)") then
        local k, t = string.match(str, "(%d+)/(%d+)")
        if k == t then return "|cff1eff00" end 
    end
    return "|cffffffff" 
end

