local EquipData = class("EquipData", BaseData)
local EquipEntity = require "app/userdata/equip/equip_entity"

local EquipCfg = ConfigManager:getConfig("equip")
local EquipLevelCfg = ConfigManager:getConfig("equip_level")
local EquipRefineCfg = ConfigManager:getConfig("equip_refine")
local EquipResonateCfg = ConfigManager:getConfig("equip_resonate")

function EquipData:ctor()
	self.data.isDirty = false
end

function EquipData:clear()
end

function EquipData:init(data)
	data = data or GConst.EMPTY_TABLE
	if EDITOR_MODE then
		Logger.logHighlight("装备数据")
		Logger.printTable(data)
	end
	if not data.equips then
		return
	end

	self.allEquips = {}
	if data.equips then
		for i, equip in pairs(data.equips) do
			self:addEquip(equip)
		end
	end
	self.slots = data.slots or {}
end

function EquipData:setDirty()
	self.data.isDirty = not self.data.isDirty
end

-- 武器功能是否开启
function EquipData:isWeaponOpen(showToast)
	if not ModuleManager:getIsOpen(ModuleManager.MODULE_KEY.EQUIP_WEAPON, not showToast) then
		return false
	end
	return true
end

--@region 配置
-- 获取配置
function EquipData:getConfig(id)
	if id then
		return EquipCfg[id]
	else
		return EquipCfg
	end
end

-- 获取强化配置
function EquipData:getLevelConfig(id)
	if id then
		return EquipLevelCfg[id]
	else
		return EquipLevelCfg
	end
end

-- 获取精炼配置
function EquipData:getRefineConfig(id)
	if id then
		return EquipRefineCfg[id]
	else
		return EquipRefineCfg
	end
end

-- 获取共鸣配置
function EquipData:getResonateConfig(id)
	if id then
		return EquipResonateCfg[id]
	else
		return EquipResonateCfg
	end
end

-- 部位  1-6分别对应头盔，护腕，衣服，裤子，鞋子，手套
function EquipData:getPart(id)
	return self:getConfig(id).type
end

-- 装备图标
function EquipData:getIconRes(id)
	return tostring(self:getConfig(id).icon)
end

-- 品质（颜色）
function EquipData:getQlt(id)
	return self:getConfig(id).qlt
end

-- 星级
function EquipData:getStar(id)
	return self:getConfig(id).star
end

-- 基础属性
function EquipData:getBaseAttr(id)
    return self:getConfig(id).base_attr
end

-- 装备名字
function EquipData:getName(id)
    return I18N:getText("equip", id, "name")
end

--@endregion

--@region 装备基础
function EquipData:addEquip(equip, itemGetType)
	if equip == nil then
		return
	end
	self.allEquips[equip.uid] = self:createEquipEntity(equip)
	if itemGetType then
		BIReport:postEquipGet(equip.uid, equip.cfg_id, itemGetType)
	end
	self:setDirty()
end

function EquipData:createEquipEntity(equip)
	return EquipEntity:create(equip)
end

function EquipData:getAllEquips()
	return self.allEquips
end

function EquipData:getEquipListByPart(part)
	local list = {}
	for _, v in pairs(self.allEquips) do
		if v:getPart() == part then
			table.insert(list, v)
		end
	end
	table.sort(list, function (a, b)
		return a:getPower() > b:getPower()
	end)
	return list
end

function EquipData:getEquipByUid(uid)
	if self.allEquips[uid] then
		return self.allEquips[uid]
	end
end
--@endregion

--@region 穿戴
--装备穿戴
function EquipData:onWearSuccess(soltId, uids)
    for i,uid in ipairs(uids) do
        local equip = self:getEquipByUid(uid)
        local part = equip:getPart()
        if part then
            local oldUid = self.slots[soltId].parts[part].equip_uid
            for i,info in ipairs(self.slots) do
                if i ~= soltId then
                    if info.parts[part].equip_uid == uid then
                        info.parts[part].equip_uid = oldUid
                    end
                end
            end
            self.slots[soltId].parts[part].equip_uid = uid
        end
    end
    self:setDirty()
    -- DataManager.ForceData:updateTeamPower()
end
--@endregion

--@region 六个部位装备的强化与精炼
--获取对应位置的装备Id
function EquipData:getPartEquipUid(slotId, part)
	local parts = self.slots[slotId].parts
	if parts then
		if part == nil then
			return parts
		else
			local partInfo = parts[part]
			if partInfo then
				return partInfo.equip_uid
			end
		end
	end
	return 0
end

-----获取强化等级
function EquipData:getPartLevel(slotId, part)
	local parts = self.slots[slotId].parts
	if parts then
		local partInfo = parts[part]
		if partInfo then
			return partInfo.level
		end
	end
	return 0
end

--获取精炼等级
function EquipData:getPartRefine(slotId, part)
	local parts = self.slots[slotId].parts
	if parts then
		local partInfo = parts[part]
		if partInfo then
			return partInfo.refine
		end
	end
	return 0
end

-- 精炼成功概率
function EquipData:getPartRefineFailPro(slotId, part)
	local parts = self.slots[slotId].parts
	if parts then
		local partInfo = parts[part]
		if partInfo then
			local cfgRefine = self:getRefineConfig(partInfo.refine + 1)
			if cfgRefine then
				return (cfgRefine.base_chance + partInfo.refine_fail * cfgRefine.chance_fail) / GConst.DEFAULT_FACTOR
			end
		end
	end
	return 0
end

function EquipData:getSlotAllAttr(slotId)
	local attr = {}
	for part = 1, 6 do
		local level = self:getPartLevel(slotId, part)
		local refine = self:getPartRefine(slotId, part)
		for i = 1, level do
			local cfg = self:getLevelConfig(i)
			if attr[cfg.base_attr_add.type] then
				attr[cfg.base_attr_add.type] = attr[cfg.base_attr_add.type] + cfg.base_attr_add.num
			else
				attr[cfg.base_attr_add.type] = cfg.base_attr_add.num
			end
		end
		local uid = self:getPartEquipUid(slotId, part)
		if uid ~= 0 then
			local equipEntity = self:getEquipByUid(uid)
			local equipAttrs = equipEntity:getExtraMap()
			local baseAttrs = equipEntity:getBaseAttr()
			if attr[baseAttrs.type] then
				attr[baseAttrs.type] = attr[baseAttrs.type] + baseAttrs.num
			else
				attr[baseAttrs.type] = baseAttrs.num
			end
			for i,extraAttr in pairs(equipAttrs) do
				local name = GFunc.getAttrNameById(extraAttr.id)
				if attr[name] then
					attr[name] = attr[name] + extraAttr.value
				else
					attr[name] = extraAttr.value
				end
				local nowAttr = self:getRefineAttrAdd(refine, extraAttr.id)
				if nowAttr then
					if attr[nowAttr.type] then
						attr[nowAttr.type] = attr[nowAttr.type] + nowAttr.num
					else
						attr[nowAttr.type] = nowAttr.num
					end
				end
			end
		end
	end
	local resonateLevel = self:getResonateLevel(1, slotId)
	local list = self:getResonateList(1)
	for i,v in ipairs(list) do
		if i <= resonateLevel then
			if attr[v.attr.type] then
				attr[v.attr.type] = attr[v.attr.type] + v.attr.num
			else
				attr[v.attr.type] = v.attr.num
			end
		else
			break
		end
	end
	local resonateQlt = self:getResonateLevel(2, slotId)
	list = self:getResonateList(2)
	for i,v in ipairs(list) do
		if i <= resonateQlt then
			if attr[v.attr.type] then
				attr[v.attr.type] = attr[v.attr.type] + v.attr.num
			else
				attr[v.attr.type] = v.attr.num
			end
		else
			break
		end
	end
	local resonateRefine = self:getResonateLevel(3, slotId)
	list = self:getResonateList(3)
	for i,v in ipairs(list) do
		if i <= resonateRefine then
			if attr[v.attr.type] then
				attr[v.attr.type] = attr[v.type] + v.attr.num
			else
				attr[v.attr.type] = v.attr.num
			end
		else
			break
		end
	end
	return attr
end

function EquipData:getResonateLevelValue(type, value, value2)
	local list = self:getResonateList(type)
	local lv = 0
	local nextLv = 0
	local attrNum = 0
	local attrNextNum = 0
	for i,v in ipairs(list) do
		if type == 1 or type == 3 then
			if v.parameter[1] <= value then
				lv = i
				attrNum = attrNum + v.attr.num
			else
				nextLv = v.parameter
				attrNextNum = attrNum + v.attr.num
				break
			end
		elseif type == 2 then
			local isTrue = false
			if v.parameter[1] < value then
				isTrue = true
			elseif v.parameter[1] == value and v.parameter[2] <= value2 then
				isTrue = true
			end
			if isTrue then
				lv = i
				attrNum = attrNum + v.attr.num
			else
				nextLv = v.parameter
				attrNextNum = attrNum + v.attr.num
				break
			end
		end
	end
	return lv, nextLv, attrNum / GConst.DEFAULT_FACTOR, attrNextNum / GConst.DEFAULT_FACTOR, table.nums(list)
end

function EquipData:getResonateLevel(type, slotId)
	if type == 1 then
		local minLv = 999
		for i = 1, 6 do
			local level = self:getPartLevel(slotId, i)
			if level < minLv then
				minLv = level
			end
		end
		return self:getResonateLevelValue(type, minLv)
	elseif type == 2 then
		local qlt = 99
		local star = 99
		for i = 1, 6 do
			local uid = self:getPartEquipUid(slotId, i)
			local equip = self:getEquipByUid(uid)
			if equip == nil then
				qlt = 0
				star = 0
				break
			end
			local q = equip:getQlt()
			local s = equip:getStar()
			if qlt > q then
				qlt = q
				star = s
			elseif qlt == q then
				if star > s then
					qlt = q
					star = s
				end
			end
		end
		return self:getResonateLevelValue(type, qlt, star)
	elseif type == 3 then
		local minRefine = 999
		for i = 1, 6 do
			local refine = self:getPartRefine(slotId, i)
			if refine < minRefine then
				minRefine = refine
			end
		end
		return self:getResonateLevelValue(type, minRefine)
	end
end

function EquipData:getLevelCost(refine)
	local cfg = self:getLevelConfig(refine)
	if cfg then
		return cfg.cost
	end
end
function EquipData:getRefineCost(refine)
	local cfg = self:getRefineConfig(refine)
	if cfg then
		return cfg.cost
	end
end
function EquipData:getRefineNeedLevel(refine)
	local cfg = self:getRefineConfig(refine)
	if cfg then
		return cfg.equip_level
	end
end

function EquipData:getEquipUseForce(uid)
	local equip = self:getEquipByUid(uid)
	local mainTeam = DataManager.ForceData:getTeamList(ModuleManager.BattleManager.BATTLE_TYPE.STAGE)
	local part = equip:getPart()
	for i,info in ipairs(self.slots) do
		if info.parts[part] and info.parts[part].equip_uid and info.parts[part].equip_uid == uid then
			return mainTeam[i]
		end
	end
end
--@endregion

--@region 装备分解
-- 分解额外返还
function EquipData:getResolveReward(id)
	return self:getConfig(id).decompose
end

-- 装备分解成功
function EquipData:onResolveSuccess(uids)
	if EDITOR_MODE then
		Logger.logHighlight("装备分解")
		Logger.printTable(uids)
	end

	for i, id in pairs(uids) do
		self.allEquips[id] = nil
	end
	self:setDirty()
end
--@endregion

return EquipData