--[[
    Warband Nexus - Database Cleanup Module
    Removes duplicate characters and deprecated storage
]]

local ADDON_NAME, ns = ...

-- Debug print helper
local DebugPrint = ns.DebugPrint
local IsDebugModeEnabled = ns.IsDebugModeEnabled
local WarbandNexus = ns.WarbandNexus

--- True when itemStorage has at least one bucket for charKey (direct or alias).
---@param storage table|nil
---@param charKey string
---@return boolean
local function CharHasMigratedItemStorage(storage, charKey)
    if type(storage) ~= "table" or not charKey or charKey == "" then return false end
    local bucket = storage[charKey]
    if type(bucket) == "table" and next(bucket) then return true end
    if ns.VaultCharKeysMatch then
        for k, v in pairs(storage) do
            if type(v) == "table" and next(v) and ns.VaultCharKeysMatch(k, charKey) then
                return true
            end
        end
    end
    return false
end

-- DATABASE CLEANUP

---Clean duplicate characters and deprecated storage
---Should be called once on addon load
function WarbandNexus:CleanupDatabase()
    if not self.db or not self.db.global then
        return
    end
    
    -- Check if cleanup already ran this session (to prevent re-cleaning saved data)
    if self.db.profile.lastCleanupSession then
        local currentSession = time()
        -- If cleanup ran less than 1 hour ago, skip
        if (currentSession - self.db.profile.lastCleanupSession) < 3600 then
            return { duplicates = 0, invalidEntries = 0, deprecatedStorage = 0 }
        end
    end
    
    local cleaned = {
        duplicates = 0,
        invalidEntries = 0,
        deprecatedStorage = 0,
    }
    
    -- Remove structurally invalid character entries (repair legacy keys first)
    if self.db.global.characters then
        local toRemove = {}
        
        for charKey, charData in pairs(self.db.global.characters) do
            if self.IsCharacterRowStructurallyInvalid and self:IsCharacterRowStructurallyInvalid(charKey, charData) then
                toRemove[charKey] = true
                cleaned.invalidEntries = cleaned.invalidEntries + 1
            end
        end
        
        -- Remove invalid entries
        for key in pairs(toRemove) do
            self.db.global.characters[key] = nil
            DebugPrint("|cffff8000[WN Cleanup]|r Removed invalid character: " .. key)
        end
    end
    
    -- Duplicate roster rows (same GUID and/or legacy Name-Realm alias).
    if self.db.global.characters and ns.MigrationService and ns.MigrationService.DeduplicateCharacterRoster then
        local dupCount = ns.MigrationService:DeduplicateCharacterRoster(self.db) or 0
        cleaned.duplicates = cleaned.duplicates + dupCount
        if dupCount > 0 then
            DebugPrint("|cffff8000[WN Cleanup]|r Merged " .. tostring(dupCount) .. " duplicate character row(s)")
            if self.InvalidateGetAllCharactersCache then
                self:InvalidateGetAllCharactersCache()
            end
        end
    end

    if self.db.global.subsidiaryOrphanRemapV1 and ns.MigrationService and ns.MigrationService.PruneLegacySubsidiaryDuplicates then
        local pruned = ns.MigrationService:PruneLegacySubsidiaryDuplicates(self.db) or 0
        if pruned > 0 then
            cleaned.deprecatedStorage = cleaned.deprecatedStorage + pruned
            DebugPrint("|cffff8000[WN Cleanup]|r Pruned " .. tostring(pruned) .. " empty legacy subsidiary shell(s)")
        end
    end
    
    -- Clean deprecated storage structures (only when v2 itemStorage holds the data)
    if self.db.global.personalBanks then
        local pb = self.db.global.personalBanks
        local storage = self.db.global.itemStorage
        local removedPb = 0
        for charKey in pairs(pb) do
            if CharHasMigratedItemStorage(storage, charKey) then
                pb[charKey] = nil
                removedPb = removedPb + 1
            end
        end
        if removedPb > 0 then
            cleaned.deprecatedStorage = cleaned.deprecatedStorage + removedPb
            DebugPrint("|cffff8000[WN Cleanup]|r Pruned " .. removedPb .. " legacy personalBanks row(s) with itemStorage")
        end
        if not next(pb) then
            self.db.global.personalBanks = nil
        end
    end
    
    if self.db.global.warbandBankV2 then
        -- Old compressed warband storage (deprecated)
        self.db.global.warbandBankV2 = nil
        cleaned.deprecatedStorage = cleaned.deprecatedStorage + 1
    end

    if self.db.global.sessionCache then
        -- Old compressed session cache blob (subsystem removed)
        self.db.global.sessionCache = nil
        cleaned.deprecatedStorage = cleaned.deprecatedStorage + 1
    end

    -- Clean old per-character storage
    if self.db.global.characters then
        for charKey, charData in pairs(self.db.global.characters) do
            -- Remove old storage fields (moved to ItemsCacheService)
            if charData.personalBank then
                charData.personalBank = nil
                cleaned.deprecatedStorage = cleaned.deprecatedStorage + 1
            end
            
            if charData.bags and charData.bags.items then
                -- Old bag storage format
                charData.bags = nil
                cleaned.deprecatedStorage = cleaned.deprecatedStorage + 1
            end
        end
    end
    
    -- Clean old warband bank
    if self.db.global.warbandBank and self.db.global.warbandBank.items then
        -- Keep gold tracking, remove items (moved to ItemsCacheService)
        self.db.global.warbandBank.items = nil
        cleaned.deprecatedStorage = cleaned.deprecatedStorage + 1
    end

    -- Try Counter — remove statistic snapshot rows for characters no longer in db (deleted alts).
    -- TryCounterService registers this method after DatabaseCleanup loads; Core delays cleanup 10s so it exists.
    if self.PruneOrphanStatisticSnapshots then
        self:PruneOrphanStatisticSnapshots()
    end
    
    -- Mark cleanup as done for this session
    if not self.db.profile.lastCleanupSession then
        self.db.profile.lastCleanupSession = 0
    end
    self.db.profile.lastCleanupSession = time()
    
    -- Silently return results (no spam in chat)
    return cleaned
end

---Force cleanup (slash command)
function WarbandNexus:ForceCleanupDatabase()
    DebugPrint("|cff00ff00[WN Cleanup]|r Starting forced database cleanup...")
    
    -- Reset session check to allow forced cleanup
    if self.db.profile.lastCleanupSession then
        self.db.profile.lastCleanupSession = 0
    end
    
    local result = self:CleanupDatabase()
    
    if result.duplicates == 0 and result.invalidEntries == 0 and result.deprecatedStorage == 0 then
        DebugPrint("|cff00ff00[WN Cleanup]|r Database is already clean!")
    else
        if IsDebugModeEnabled and IsDebugModeEnabled() then
            DebugPrint(string.format("|cff00ff00[WN Cleanup]|r Removed %d duplicate(s), %d invalid(s), %d deprecated storage(s)",
                result.duplicates, result.invalidEntries, result.deprecatedStorage))
        end
        DebugPrint("|cff00ff00[WN Cleanup]|r Please /reload to see changes.")
    end
end

-- Module loaded - verbose logging removed
