local ADDON_NAME, ns = ...

-- =============================================================
--  MT/OT TANK SYSTEM (EXTRACTED MODULE)
--  - Caches other tanks in group/raid
--  - Provides ns:GetTankModeState(unit) -> r,g,b,shouldFlash
-- =============================================================

ns.TankUnits = ns.TankUnits or {}

-- -------------------------------------------------------------
-- DB helper (new schema)
-- -------------------------------------------------------------
local function GetThreatDB()
    if not PlateOMaticDB then return nil end
    PlateOMaticDB.threat = PlateOMaticDB.threat or {}
    PlateOMaticDB.threat.colors = PlateOMaticDB.threat.colors or {}
    return PlateOMaticDB.threat
end

-- NOTE: role assignment can be unreliable in some group contexts.
-- For reporting, we allow a spec-role fallback for the player.
local function PlayerIsTankRole_ForReport()
    if (IsInGroup() or IsInRaid()) and UnitGroupRolesAssigned("player") == "TANK" then
        return true
    end

    if GetSpecialization and GetSpecializationRole then
        local spec = GetSpecialization()
        if spec then
            return GetSpecializationRole(spec) == "TANK"
        end
    end

    return false
end

local function ReportTanks()
    local inGroup = IsInGroup() or IsInRaid()

    local playerIsTank = PlayerIsTankRole_ForReport()
    local tankCount = #ns.TankUnits + (playerIsTank and 1 or 0)

    local names = {}
    if playerIsTank then
        local pn = UnitName("player")
        if pn then names[#names + 1] = pn .. " (you)" end
    end
    for _, u in ipairs(ns.TankUnits) do
        local n = UnitName(u)
        if n then names[#names + 1] = n end
    end
    table.sort(names)

    local sig = (inGroup and "G" or "S") .. ":" .. tostring(tankCount) .. ":" .. table.concat(names, ",")

    if ns._lastTankReportSig == sig then
        return
    end
    ns._lastTankReportSig = sig

    if not inGroup then
        print("|cFF00FF00Plate-o-Matic:|r Tank cache: solo (0 other tanks).")
        return
    end

    if tankCount == 0 then
        print("|cFF00FF00Plate-o-Matic:|r Tank cache: 0 tanks detected (roles not set?).")
    else
        print(string.format("|cFF00FF00Plate-o-Matic:|r Tank cache: %d tank(s): %s", tankCount, table.concat(names, ", ")))
    end
end

function ns:UpdateTankCache()
    if table.wipe then
        table.wipe(ns.TankUnits)
    else
        for i = #ns.TankUnits, 1, -1 do ns.TankUnits[i] = nil end
    end

    if not IsInGroup() and not IsInRaid() then
        ReportTanks()
        return
    end

    local prefix = IsInRaid() and "raid" or "party"
    local count = GetNumGroupMembers()
    local limit = IsInRaid() and count or (count - 1)

    for i = 1, limit do
        local unit = prefix .. i
        if UnitExists(unit) and not UnitIsUnit(unit, "player") then
            if UnitGroupRolesAssigned(unit) == "TANK" then
                ns.TankUnits[#ns.TankUnits + 1] = unit
            end
        end
    end

    ReportTanks()
end

-- =============================================================
--  Role helpers
-- =============================================================
local function PlayerIsTankRole()
    if IsInGroup() or IsInRaid() then
        if UnitGroupRolesAssigned("player") == "TANK" then
            return true
        end
    end

    if GetSpecialization and GetSpecializationRole then
        local spec = GetSpecialization()
        if spec then
            return GetSpecializationRole(spec) == "TANK"
        end
    end

    return false
end

-- =============================================================
--  Main decision function:
--  Returns tank-safe color if I have aggro,
--  off-tank color if another tank has it,
--  danger color if no tank has it.
-- =============================================================
function ns:GetTankModeState(unit)
    local tdb = GetThreatDB()
    if not tdb then
        return nil, nil, nil, false
    end

    if not tdb.tankModeEnabled then
        return nil, nil, nil, false
    end

    if not PlayerIsTankRole() then
        return nil, nil, nil, false
    end

    -- HARD GATES: unit must be valid + attackable
    if not unit or not UnitExists(unit) then
        return nil, nil, nil, false
    end
    if UnitCanAttack and not UnitCanAttack("player", unit) then
        return nil, nil, nil, false
    end

    -- IMPORTANT FIX:
    -- Gate on THE UNIT being in combat, not the player.
    -- Prevents “random plates” turning red/flash just because you are in combat.
    if not UnitAffectingCombat(unit) then
        return nil, nil, nil, false
    end

    local c = tdb.colors or {}

    -- NEW color keys (match THREAT_DEFAULTS you pasted in pom.lua)
    local cSafe = c.safe or { r = 0.2, g = 0.8, b = 0.2 }  -- tank has aggro
    local cOT   = c.ot   or { r = 0.6, g = 0.2, b = 1.0 }  -- off-tank has aggro
    local cBad  = c.high or { r = 1.0, g = 0.0, b = 0.0 }  -- nobody tanking it

    local status = UnitThreatSituation("player", unit) or 0
    status = tonumber(status) or 0

    -- I have aggro
    if status >= 3 then
        return cSafe.r, cSafe.g, cSafe.b, false
    end

    -- Optional OT check toggle (from new DB)
    if tdb.checkOffTank then
        for _, tankUnit in ipairs(ns.TankUnits) do
            if UnitExists(tankUnit) then
                local otStatus = UnitThreatSituation(tankUnit, unit) or 0
                otStatus = tonumber(otStatus) or 0

                -- Accept 2 or 3 as “OT has it”
                if otStatus >= 2 then
                    return cOT.r, cOT.g, cOT.b, false
                end
            end
        end
    end

    -- No tank has it (THIS UNIT is in combat, so this is meaningful)
    return cBad.r, cBad.g, cBad.b, true
end

-- NOTE:
-- We intentionally do NOT register events here anymore.
-- pom.lua already updates tank cache on relevant events, and keeping both
-- causes duplicate work and inconsistent ordering in refresh cycles.
