local _, ns = ...
local B, C, L, DB = unpack(ns)
--------------Thanks  nj55top`s iFrame
local colorbyclass = true									-- 血条按职业着色
local iURCEnable = false									-- 队友/目标/焦点超出治疗范围，框体变淡（仅作用于治疗职业）
local showPlayerSpeed = true								-- 显示玩家移动速度
local showTargetSpeed = true								-- 显示目标移动速度
local barMult = 1
local FONT_STRING = "Interface\\addons\\OrzUI\\Media\\Fonts\\Pixel.TTF"
local barTexture = "Interface\\Addons\\OrzUI\\Media\\Modules\\UFs-UI-StatusBar" -- 状态条材质
local hasTarget, updateElapsed
local function textUpdate(bar)
	if not bar then return end													-- Party Pet frames don't have a mana bar.
	local frame = bar.unitFrame
	if not frame or not frame.addPctText then return end
	local textType = GetCVar("statusTextDisplay")
	if bar.pctText then
		if textType ~= "NUMERIC" or bar.isZero == 1 then
			bar.pctText:SetText("")
		else
			local unit = bar.unit or frame.unit
			if not unit then return end
			local percent = UnitHealthPercent(unit, true, CurveConstants.ScaleTo100)
			if C.db["UFs"]["UFPctText"] and percent then
				bar.pctText:SetText(string.format("%d", percent))
			else
				bar.pctText:SetText("")
			end
		end
	end
	local value = bar:GetValue()
	if bar.TextString and textType == "NUMERIC" and bar.isZero == nil then
		if bar.capNumericDisplay then
			value = AbbreviateLargeNumbers(value)
		else
			value = BreakUpLargeNumbers(value)
		end
		bar.TextString:SetText(value)
	end
end

local function getHealthbarColor(unit)
	local color = {r=0.17, g=1.0, b=0.5}
	if (not unit) then return color end
	if ((UnitIsPlayer(unit) or unit == "pet")) and UnitClass(unit) then
		color = RAID_CLASS_COLORS[select(2, UnitClass(unit))]
	else
		color.r, color.g, color.b = UnitSelectionColor(unit)
	end

	if UnitCanAttack(unit, "player") then
		if ( not UnitPlayerControlled(unit) and UnitIsTapDenied(unit) ) then
			color.r, color.g, color.b = 0.5 * barMult, 0.5 * barMult, 0.5 * barMult
		end
	end
	return color
end

local function colorHPBar(bar, unit)
	if bar and not bar.lockValues and unit == bar.unit then
		if colorbyclass then
			local color = getHealthbarColor(unit)
			bar:SetStatusBarColor(color.r * barMult, color.g * barMult, color.b * barMult)
			bar:SetStatusBarDesaturated(true)

			--[[if UnitIsPlayer(unit) and UnitClass(unit) then
				local color = RAID_CLASS_COLORS[select(2, UnitClass(unit))]
				bar:SetStatusBarColor(color.r, color.g, color.b)
				bar:SetStatusBarDesaturated(true)
			else
				bar:SetStatusBarColor(0, 0.9, 0.3)			-- defaultColor
				bar:SetStatusBarDesaturated(false)
			end]]
		end
	end
end
hooksecurefunc("UnitFrameHealthBar_OnUpdate", textUpdate)
hooksecurefunc("UnitFrameHealthBar_Update", textUpdate)
hooksecurefunc("UnitFrameHealthBar_Update", colorHPBar)
hooksecurefunc("UnitFrameManaBar_OnUpdate", textUpdate)
hooksecurefunc("UnitFrameManaBar_Update", textUpdate)
hooksecurefunc("HealthBar_OnValueChanged", function(self) colorHPBar(self, self.unit) end)
hooksecurefunc("UnitFrame_Update", function(self)
	if self.name and self.unit then
		local color = UnitIsPlayer(self.unit) and RAID_CLASS_COLORS[select(2, UnitClass(self.unit))] or NORMAL_FONT_COLOR
		--self.name:SetTextColor(color.r, color.g, color.b)
	if self.name then
	    if UnitIsPlayer(self.unit) then 
		   self.name:SetTextColor(color.r, color.g, color.b)
		elseif UnitIsEnemy("player", "target") then 
		   self.name:SetTextColor(1,0,0) 
		elseif UnitIsFriend("player", "target") then 
		   self.name:SetTextColor(0,1,0)  
		else
		   self.name:SetTextColor(1,1,0) 
	end
	end
	end
end)

function CreateBarPctText(frame, ap, rp, x, y, fontsize)
	local bar = frame.healthbar
	if bar then
		bar.pctText = frame:CreateFontString(nil, "OVERLAY", "NumberFontNormal")
		bar.pctText:SetPoint(ap, bar, rp, x, y)
		bar.pctText:SetTextHeight(21) --height or 21
		bar.pctText:SetFont(FONT_STRING, fontsize, "OUTLINE")
		--bar.pctText:SetShadowColor(0, 0, 0)
		bar.pctText:SetText("")
		frame.addPctText = true
	end
end

--------------------------- Frames ----------------------------
CreateBarPctText(PlayerFrame, "RIGHT", "LEFT", -66, -3, 36)  --"LEFT", "RIGHT", 4, 0, 14
PlayerName:SetTextHeight(12)  --:Hide()
--PlayerName:SetFont(FONT_STRING, 14, "OUTLINE")	--玩家及目标名字字体，大小
CreateBarPctText(PetFrame, "RIGHT", "LEFT", -36, 0, 26)
PetName:SetTextHeight(12)
--PetName:SetFont(STANDARD_TEXT_FONT, 12, "OUTLINE") ----宠物名字文字大小
PetFrameHealthBarText:SetTextHeight(9)
PetFrameManaBarText:SetTextHeight(9)
CreateBarPctText(TargetFrame, "LEFT", "RIGHT", 66, -3, 36)  --"RIGHT", "LEFT", -4, 0, 14
TargetFrame.TargetFrameContent.TargetFrameContentMain.Name:SetTextHeight(13)
--TargetFrame.TargetFrameContent.TargetFrameContentMain.Name:SetFont(STANDARD_TEXT_FONT, 14, "OUTLINE")
TargetFrame.TargetFrameContent.TargetFrameContentContextual.NumericalThreat.text:SetTextHeight(10)
CreateBarPctText(TargetFrameToT, "BOTTOMRIGHT", "TOPRIGHT", 0, 16, 26)
--TargetFrameToT.Name:SetTextHeight(12)
--TargetFrameToT.Name:SetFont(FONT_STRING, 10, "OUTLINE")
CreateBarPctText(FocusFrame, "LEFT", "RIGHT", 60, 0, 26)
CreateBarPctText(FocusFrameToT, "BOTTOMRIGHT", "TOPRIGHT", 0, 15, 16)
--FocusFrame.TargetFrameContent.TargetFrameContentMain.Name:SetFont(FONT_STRING, 12, "OUTLINE")
for i = 1, MAX_BOSS_FRAMES do
	local bossFrame = _G["Boss"..i.."TargetFrame"]
	CreateBarPctText(bossFrame, "BOTTOMLEFT", "TOPRIGHT", 17, 17, 14)
	bossFrame.TargetFrameContent.TargetFrameContentContextual.NumericalThreat.text:SetTextHeight(10)
end


-- Binding Variables
BINDING_NAME_TARGETCLASSBUTTON_INSPECT = INSPECT
BINDING_NAME_TARGETCLASSBUTTON_TRADE = TRADE
BINDING_NAME_TARGETCLASSBUTTON_WHISPER = WHISPER
BINDING_NAME_TARGETCLASSBUTTON_FOLLOW = FOLLOW
BINDING_NAME_TARGETCLASSBUTTON_COMPARE_ACHIEVEMENTS = COMPARE_ACHIEVEMENTS

function CreateClassIcon(parent, scale, ap, rp, x, y)
	local icon = CreateFrame("Button", nil, parent)
	icon:Hide()
	icon:SetWidth(26*scale)
	icon:SetHeight(26*scale)
	icon:SetFrameLevel(parent:GetFrameLevel()+3)
	icon:SetPoint(ap, parent, rp, x, y)
	icon.tex = icon:CreateTexture(nil, "BACKGROUND")
	icon.tex:SetWidth(20*scale)
	icon.tex:SetHeight(20*scale)
	icon.tex:SetTexture("Interface\\TargetingFrame\\UI-Classes-Circles")
	icon.tex:SetPoint("CENTER")
	icon.lay = icon:CreateTexture(nil, "OVERLAY")
	icon.lay:SetWidth(36*scale)
	icon.lay:SetHeight(36*scale)
	icon.lay:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
	icon.lay:SetPoint("TOPLEFT")
	return icon
end

TargetFrame.icon = CreateClassIcon(TargetFrame, 1, "TOPRIGHT", "TOPRIGHT", -72, -16)
TargetFrame.icon:SetScript("OnMouseDown", function(self, button)
	if InCombatLockdown() then return end
	--if IsAltKeyDown() then InitiateTrade("target") else InspectUnit("target") end 
	--if (not UnitCanAttack("player","target") and UnitIsPlayer("target")) then
		if button == "LeftButton" then
			InspectUnit("target")
		elseif button == "RightButton" then
			InitiateTrade("target")  --if CheckInteractDistance("target",2) then InitiateTrade("target") end
		elseif button == "MiddleButton" then  --	StartDuel("target")
				local server = nil;
				local name, server = UnitName("target");
				local fullname = name;			
				if ( server and (not "target" or UnitRealmRelationship("target") ~= LE_REALM_RELATION_SAME) ) then
					fullname = name.."-"..server;
				end
				ChatFrameUtil.SendTell(fullname)
		elseif button == "Button4" then
			FollowUnit("target", 1)  --if CheckInteractDistance("target",4) then FollowUnit("target", 1); end
		else
			InspectAchievements("target")  --if CheckInteractDistance("target",1) then InspectAchievements("target") end
		end
	--end
end)
--TargetFrame.type = TargetFrame:CreateFontString(nil, "OVERLAY", "ReputationDetailFont")
--TargetFrame.type:SetPoint("BOTTOM", TargetFrame.icon, "TOP")
--TargetFrame.type:SetFont(STANDARD_TEXT_FONT, 12, "OUTLINE") ----目标类型名字文字大小
hooksecurefunc(TargetFrame, "Update", function(self)
	if not UnitExists(self.unit) then return end
	local type, color
	if UnitIsPlayer(self.unit) then
		if self.icon then
			local coord = CLASS_ICON_TCOORDS[select(2, UnitClass(self.unit))]
			self.icon.tex:SetTexCoord(unpack(coord))
			self.icon:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")
			self.icon:Show()
		end
		type = UnitRace(self.unit)
		if UnitFactionGroup(self.unit) == UnitFactionGroup("player") then
			color = GREEN_FONT_COLOR
		else
			color = RED_FONT_COLOR
		end
	else
		if self.icon then self.icon:Hide() end
		type = UnitCreatureType(self.unit) or ""
		if UnitCanAttack(self.unit, "player") then
			color = UnitPlayerControlled(self.unit) and ORANGE_FONT_COLOR or YELLOW_FONT_COLOR
		else
			color = HIGHLIGHT_FONT_COLOR
		end
	end
	if self.type then
		self.type:SetText(type)
		self.type:SetTextColor(color.r, color.g, color.b)
	end
	TargetFrame.TargetFrameContent.TargetFrameContentMain.HealthBarsContainer.HealthBar:SetStatusBarTexture(barTexture)
end)


-- PartyMember and Target/Focus Range Check for Healers
-- and Show Speed of Player and Target

local healingSpell = { ["德鲁伊"]   = "回春术",
					   ["牧师"]     = "快速治疗",
					   ["圣骑士"]   = "圣光闪现",
					   ["萨满祭司"] = "治疗之涌",
					   ["武僧"]     = "活血术",
					   ["唤魔师"]   = "活化烈焰"  }
local iURCSpell = healingSpell[UnitClass("player")] or nil

local function rangeCheck(frame)
	if not frame:IsShown() or not frame.unit then return end
	if not iURCSpell then return end											-- valid for Healers only
	local outRange = C_Spell.IsSpellInRange(iURCSpell, frame.unit) == false
	if outRange then
		frame:SetAlpha(0.5)
	else
		frame:SetAlpha(1)
	end
end

local SPEED_FORMAT_OPTIONS = {
	breakpointData = {
		{
			breakpoint = 0,
			abbreviation = "%",
			significandDivisor = 0.06999,
			fractionDivisor = 1,
			abbreviationIsGlobal = false,
		},
	},
}

PlayerFrame.speed = PlayerFrame:CreateFontString(nil, "OVERLAY", "NumberFontNormalGray")	-- NumberFontNormalYellow
PlayerFrame.speed:SetPoint("LEFT", PlayerFrame, "BOTTOMLEFT", 40, 14)
TargetFrame.speed = TargetFrame:CreateFontString(nil, "OVERLAY", "NumberFontNormalGray")
TargetFrame.speed:SetPoint("RIGHT", TargetFrame, "BOTTOMRIGHT", -34, 14)


local iFrame = CreateFrame("Frame")
iFrame:RegisterEvent("PLAYER_TARGET_CHANGED")
iFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
iFrame:SetScript("OnEvent", function(self, event, ...)
	if event == "PLAYER_TARGET_CHANGED" then
		hasTarget = UnitExists("target") and not UnitIsUnit("player", "target") and not UnitIsUnit("vehicle", "target")
	elseif event == "PLAYER_ENTERING_WORLD" then
		PlayerFrame.PlayerFrameContent.PlayerFrameContentMain.HealthBarsContainer.HealthBar:SetStatusBarTexture(barTexture)
		--PlayerFrame.PlayerFrameContent.PlayerFrameContentMain.ManaBarsContainer.ManaBar:SetStatusBarTexture(barTexture) 
		TargetFrame.TargetFrameContent.TargetFrameContentMain.HealthBarsContainer.HealthBar:SetStatusBarTexture(barTexture)
		--TargetFrame.TargetFrameContent.TargetFrameContentMain.ManaBarsContainer.ManaBar:SetStatusBarTexture(barTexture)
		TargetFrameToT.HealthBar:SetStatusBarTexture(barTexture) 
		TargetFrameToT.ManaBar:SetStatusBarTexture(barTexture) 
		PetFrameHealthBar:SetStatusBarTexture(barTexture)
		--FocusFrame.TargetFrameContent.TargetFrameContentMain.HealthBarsContainer.HealthBar:SetStatusBarTexture(barTexture)
		--FocusFrame.TargetFrameContent.TargetFrameContentMain.ManaBar:SetStatusBarTexture(barTexture) 
		--FocusFrameToT.HealthBar:SetStatusBarTexture(barTexture) 
	end
end)
iFrame:SetScript("OnUpdate", function(self, elapsed)
	updateElapsed = (updateElapsed or 0) + elapsed
	if updateElapsed > TOOLTIP_UPDATE_TIME then
		updateElapsed = 0
		if iURCEnable then
			rangeCheck(TargetFrame)
			rangeCheck(FocusFrame)
			for frame in PartyFrame.PartyMemberFramePool:EnumerateActive() do
				rangeCheck(frame)
			end
		end
		if showPlayerSpeed then
			local pSpeedText = ""
			pcall(function()
				local isGliding, canGlide, forwardSpeed = C_PlayerInfo.GetGlidingInfo()
				local playerSpeed = isGliding and forwardSpeed or GetUnitSpeed(PlayerFrame.unit)
				pSpeedText = AbbreviateNumbers(playerSpeed, SPEED_FORMAT_OPTIONS)
			end)
			PlayerFrame.speed:SetText(pSpeedText)
		end
		if showTargetSpeed then
			local tSpeedText = ""
			pcall(function()
				if hasTarget then
					local targetSpeed = GetUnitSpeed("target")
					tSpeedText = AbbreviateNumbers(targetSpeed, SPEED_FORMAT_OPTIONS)
				end
			end)
			TargetFrame.speed:SetText(tSpeedText)
		end
	end
end)
	-- 能量条改变背景
    hooksecurefunc("UnitFrameManaBar_UpdateType", function(self, manaBar)
        if self.unit then
            self:SetStatusBarTexture("Interface\\Addons\\OrzUI\\Media\\EnergyTex") 
            local powerType, powerToken, altR, altG, altB = UnitPowerType(self.unit);
            if (powerToken) then
                local color = PowerBarColor[powerToken];
				if (color) then
                	self:SetStatusBarColor(color.r * barMult, color.g * barMult, color.b * barMult)
				end
            end
        end
    end)

-----------------------------------------	     隐藏头像动态伤害      -----------------------------------------
--PlayerFrame.PlayerFrameContent.PlayerFrameContentMain.HitIndicator:Hide()
--PlayerFrame.PlayerFrameContent.PlayerFrameContentMain.HitIndicator:Hide()
PlayerFrame:UnregisterEvent("UNIT_COMBAT") PetFrame:UnregisterEvent("UNIT_COMBAT")

-- 血量简写以万为单位 - 遵循暴雪原版显示逻辑
-- === 创建数字格式化配置 ===
local numberFormatConfig = CreateAbbreviateConfig({
    {
        breakpoint = 1e10,      -- 123亿 1234亿
        abbreviation = LOCALE_zhCN and "亿" or "億",
        significandDivisor = 1e8,
        fractionDivisor = 1,
        abbreviationIsGlobal = false
    },
    {
        breakpoint = 1e9,       -- 12.3亿
        abbreviation = LOCALE_zhCN and "亿" or "億",
        significandDivisor = 1e7,
        fractionDivisor = 10,
        abbreviationIsGlobal = false
    },
    {
        breakpoint = 1e8,       -- 1.23亿
        abbreviation = LOCALE_zhCN and "亿" or "億",
        significandDivisor = 1e6,
        fractionDivisor = 100,
        abbreviationIsGlobal = false
    },
    {
        breakpoint = 1e7,       -- 1234万
        abbreviation = LOCALE_zhCN and "万" or "萬",
        significandDivisor = 1e4,
        fractionDivisor = 1,
        abbreviationIsGlobal = false
    },
    {
        breakpoint = 1e4,       -- 1.2万 12.3万 123.4万
        abbreviation = LOCALE_zhCN and "万" or "萬",
        significandDivisor = 1e3,
        fractionDivisor = 10,
        abbreviationIsGlobal = false
    },
    {
        breakpoint = 1,
        abbreviation = "",
        significandDivisor = 1,
        fractionDivisor = 1,
        abbreviationIsGlobal = false
    },
})

local numberAbbrevOptions = {config = numberFormatConfig}

-- === 核心函数：格式化"当前值/最大值" ===
local function FormatHealthValue(current, max)
    if not current or not max then return nil end
    
    -- 使用pcall安全调用AbbreviateNumbers
    local success1, currentStr = pcall(AbbreviateNumbers, current, numberAbbrevOptions)
    local success2, maxStr = pcall(AbbreviateNumbers, max, numberAbbrevOptions)
    
    if success1 and success2 then
        return currentStr .. "/" .. maxStr
    end
    
    return nil
end

-- === 核心函数：只格式化当前值 ===
local function FormatCurrentValue(current)
    if not current then return nil end
    
    local success, currentStr = pcall(AbbreviateNumbers, current, numberAbbrevOptions)
    return success and currentStr or tostring(current)
end

-- === 获取显示模式 ===
local function GetDisplayMode()
    return GetCVar("statusTextDisplay") or "NUMERIC"
end

-- === 安全获取血量值 ===
local function GetHealthValues(unit)
    if not unit then return nil, nil end
    
    local current = UnitHealth(unit)
    local max = UnitHealthMax(unit)
    
    if type(current) == "number" and type(max) == "number" then
        return current, max
    end
    return nil, nil
end

-- === 安全获取能量值 ===
local function GetPowerValues(unit)
    if not unit then return nil, nil, nil end
    
    local powerType = UnitPowerType(unit)
    local current = UnitPower(unit, powerType)
    local max = UnitPowerMax(unit, powerType)
    
    if type(current) == "number" and type(max) == "number" then
        return current, max, powerType
    end
    return nil, nil, powerType
end

-- === 更新血量文字 ===
local function UpdateHealthText(statusBar)
    local unit = statusBar.unit
    if not unit then return end
    
    -- 处理死亡和鬼魂状态
    if UnitIsDead(unit) or UnitIsGhost(unit) then
        if statusBar.TextString then statusBar.TextString:SetText("") end
        if statusBar.RightText then statusBar.RightText:SetText("") end
        return
    end
    
    local mode = GetDisplayMode()
    
    -- 百分比模式：不处理
    if mode == "PERCENT" then return end
    
    local current, max = GetHealthValues(unit)
    if not current or not max then return end
    
    if mode == "BOTH" then
        -- BOTH模式：只改RightText，只显示当前值（遵循暴雪原版）
        local formattedCurrent = FormatCurrentValue(current)
        if statusBar.RightText then
            statusBar.RightText:SetText(formattedCurrent)
        end
    else -- NUMERIC模式
        -- NUMERIC模式：显示"当前值/最大值"
        local formattedValue = FormatHealthValue(current, max)
        if formattedValue then
            if statusBar.TextString then
                statusBar.TextString:SetText(formattedValue)
            end
            if statusBar.RightText then
                statusBar.RightText:SetText(formattedValue)
            end
        end
    end
end

-- === 更新能量文字 ===
local function UpdatePowerText(statusBar)
    local unit = statusBar.unit
    if not unit then return end
    
    local mode = GetDisplayMode()
    
    -- 百分比模式：不处理
    if mode == "PERCENT" then return end
    
    local current, max, powerType = GetPowerValues(unit)
    if not current then return end
    
    -- 检查是否是法力值
    local isMana = (powerType == 0)
    
    if mode == "BOTH" then
        -- BOTH模式：只改RightText
        if statusBar.RightText then
            if isMana then
                -- 法力值：只显示当前值（遵循暴雪原版）
                statusBar.RightText:SetText(FormatCurrentValue(current))
            else
                -- 非法力值：直接显示数值
                statusBar.RightText:SetText(current)
            end
        end
    else -- NUMERIC模式
        if isMana then
            -- 法力值：显示"当前值/最大值"
            local formattedValue = FormatHealthValue(current, max)
            local displayText = formattedValue or tostring(current)
            
            if statusBar.TextString then
                statusBar.TextString:SetText(displayText)
            end
            if statusBar.RightText then
                statusBar.RightText:SetText(displayText)
            end
        else
            -- 非法力值：只显示当前值
            if statusBar.TextString then
                statusBar.TextString:SetText(current)
            end
            if statusBar.RightText then
                statusBar.RightText:SetText("")
            end
        end
    end
end

-- === 注册Hook ===
hooksecurefunc("UnitFrameHealthBar_OnUpdate", UpdateHealthText)
hooksecurefunc("UnitFrameManaBar_OnUpdate", UpdatePowerText)
