-- 装备图鉴
local Msg = require("core.Msg")
local EquipExcel = require("excel.equip").equip
local EquipRareExcel = require("excel.equip").rare
local EquipTeXiao = require("excel.equip").texiao
local ItemDefine = require("bag.ItemDefine")
local Grid = require("bag.Grid")
local EquipLogic = require("equip.EquipLogic")
local BagLogic = require("bag.BagLogic")
local EquipLogicGrid = require("equip.EquipLogicGrid")
local Lang = require("common.Lang")
local Broadcast = require("broadcast.Broadcast")
local HeroLogic = require("hero.HeroLogic")
local Util = require("common.Util")
local HeroGrowUp = require("absAct.HeroGrowUp")
local ObjHuman = require("core.ObjHuman")
local TriggerLogic = require("trigger.TriggerLogic")
local TriggerDefine = require("trigger.TriggerDefine")
local HeroExcel = require("excel.hero")
local HeroEquip = require("hero.HeroEquip")

local EQUIPREFINING_EFFECT = 1  -- 效果
local EQUIPREFINING_HERONAME = 2    -- 英雄名
local EQUIPEFINING_DEL_GOODID = 183  -- 消耗的物品ID
local EQUIPEFINING_DEL_TYPE_1 = 5   -- 重置效果消耗
local EQUIPEFINING_DEL_TYPE_2 = 1   -- 重置英雄名消耗

-- 取出合适的装备
local function getEquipGrid(human, bagIndex, heroUuid, pos)
    local equipGrid = human.db.equipBag[bagIndex]
    if not equipGrid then 
       -- 取英雄身上的
       local heroGrid, heroIndex = HeroLogic.getHeroGridByUuid(human, heroUuid)
       if not heroGrid then return end

       equipGrid = heroGrid.equip and heroGrid.equip[pos]

       return equipGrid, heroGrid, heroIndex
    end

    return equipGrid, nil, nil
end

-- 获得装备洗练数据中被锁定属性的数量, 索引...
local function getEquipLockAttrInfo(equipGrid)
    if not equipGrid or not equipGrid.attr or #equipGrid.attr <= 1 then
        return
    end

    local num = 0
    local idxList = {}

    for idx, attrInfo in ipairs(equipGrid.attr) do
        if attrInfo[4] and attrInfo[4] == 1 then
            num = num + 1
            idxList[idx] = idx
        end
    end

    return num, idxList
end



-- 查询装备图鉴 全部信息
function fenjieQuey(human, inputList)
    local indexTable = { }
    for i = 1, inputList[0] do
        local index = inputList[i]
        local equipGrid = human.db.equipBag[index]
        if not equipGrid then
            return
        end

        if not EquipRareExcel[equipGrid.quality] then return end

        if indexTable[index] then
            -- 重复id
            return
        end
        indexTable[index] = true
    end

    local itemList = { }
    for i = 1, inputList[0] do
        local index = inputList[i]
        local equipGrid = human.db.equipBag[index]

        local equipConfig = EquipExcel[equipGrid.id]
        if not equipConfig then return end

        for k, v in ipairs(EquipRareExcel[equipGrid.quality].disassembly) do
            itemList[v[1]] = itemList[v[1]] or 0
            itemList[v[1]] = itemList[v[1]] + v[2]
        end
    end

    local msgRet = Msg.gc.GC_EQUIP_FEN_JIE_QUERY
    local len = 0
    for k, v in pairs(itemList) do
       len = len + 1
       Grid.makeItem(msgRet.list[len], k, v)
    end
    msgRet.list[0] = len
    Msg.send(msgRet, human.fd)
end


-- 查询装备图鉴 全部信息
function fenjieDo(human, inputList)
    local indexTable = { }
    for i = 1, inputList[0] do
        local index = inputList[i]
        local equipGrid = human.db.equipBag[index]
        if not equipGrid then
            return
        end

        if not EquipRareExcel[equipGrid.quality] then return end

        if indexTable[index] then
            -- 重复id
            return
        end
        indexTable[index] = true
    end

    local itemList = { }
    for i = 1, inputList[0] do
        local index = inputList[i]
        local equipGrid = human.db.equipBag[index]

        local equipConfig = EquipExcel[equipGrid.id]
        if not equipConfig then return end

        for k, v in ipairs(EquipRareExcel[equipGrid.quality].disassembly) do
            itemList[v[1]] = itemList[v[1]] or 0
            itemList[v[1]] = itemList[v[1]] + v[2]
        end

        EquipLogic.delEquip(human, index, "equip_fenjie")
		HeroGrowUp.onCallback(human, HeroGrowUp.TASKTYPE21, 1)
    end

    BagLogic.addItemList(human, itemList, "equip_fenjie")

    local msgRet = Msg.gc.GC_EQUIP_FEN_JIE_DO
    Msg.send(msgRet, human.fd)
end

-- 洗练查询
function randomQuery(human, bagIndex, heroUuid, pos)
    local equipGrid = getEquipGrid(human, bagIndex, heroUuid, pos)
    if not equipGrid then return end

    local rareExcel = EquipRareExcel[equipGrid.quality]
    if not rareExcel then return end


    local attrLockNum = getEquipLockAttrInfo(equipGrid)

    local msgRet = Msg.gc.GC_EQUIP_RAMDOM_QUERY
    Grid.makeItem(msgRet.equipOld, equipGrid.id, 1, nil, equipGrid, bagIndex)

    -- 当前洗练属性
    local washAttr = equipGrid.washAttr
    local washQuality = equipGrid.washQuality
    msgRet.equipNew[0] = 0
    if washAttr and washQuality then
        local washEquipGrid = EquipLogicGrid.createTempGrid(equipGrid.id, equipGrid.washAttr, equipGrid.washQuality)
        Grid.makeItem(msgRet.equipNew[1], washEquipGrid.id, 1, nil, washEquipGrid, bagIndex)
        msgRet.equipNew[0] = 1
    end

    msgRet.needItem[0] = #rareExcel.rebirth
    for i = 1, msgRet.needItem[0] do
        -- Grid.makeItem(msgRet.needItem[i], rareExcel.rebirth[i][1], rareExcel.rebirth[i][2])

        local itemCnt = rareExcel.rebirth[i][2]
        if attrLockNum and attrLockNum > 0 then
            itemCnt = itemCnt * (attrLockNum + 1)
        end

        Grid.makeItem(msgRet.needItem[i], rareExcel.rebirth[i][1], itemCnt)
    end

    Msg.send(msgRet, human.fd)
end

-- 已穿戴的装备
function putList(human, pos)
    local msgRet = Msg.gc.GC_EQUIP_PUT_LIST
    local cnt = 0
    for index = 1, human.db.heroBag[0] do
        local heroGrid = human.db.heroBag[index]
        if heroGrid and heroGrid.lv >= 2 then
            -- 所有部位
            if pos == 0 then
                for i = 1, ItemDefine.EQUIP_MAX_CNT do
                    local equipGrid = heroGrid.equip and heroGrid.equip[i]
                    if equipGrid then
                        cnt = cnt + 1
                        local net = msgRet.putList[cnt]
                        if i ~= ItemDefine.EQUIP_SUBTYPE_SHUIJIN then
                            Grid.makeItem(net.equip, equipGrid.id, 1, nil, equipGrid)
                            net.pos = i
                        end

                        if cnt >= 10 then
                            msgRet.isEnd = 0
                            msgRet.putList[0] = cnt
                            Msg.send(msgRet, human.fd)
                            cnt = 0
                        end
                    end
                end
            else
                local equipGrid = heroGrid.equip and heroGrid.equip[pos]
                if equipGrid then
                    cnt = cnt + 1
                    local net = msgRet.putList[cnt]
                    if i ~= ItemDefine.EQUIP_SUBTYPE_SHUIJIN then
                        Grid.makeItem(net.equip, equipGrid.id, 1, nil, equipGrid)
                        net.pos = pos
                    end

                    if cnt >= 10 then
                        msgRet.isEnd = 0
                        msgRet.putList[0] = cnt
                        Msg.send(msgRet, human.fd)
                        cnt = 0
                    end
                end
            end
        end
    end
    msgRet.isEnd = 1
    msgRet.putList[0] = cnt
    Msg.send(msgRet, human.fd)
end

-- 洗练
function randomDo(human, bagIndex, heroUuid, pos)
    local equipGrid = getEquipGrid(human, bagIndex, heroUuid, pos)
    if not equipGrid then return end

    local rareExcel = EquipRareExcel[equipGrid.quality]
    if not rareExcel then return end

    local attrLockNum, idxList = getEquipLockAttrInfo(equipGrid)

    for i = 1, #rareExcel.rebirth do
       local needItemID = rareExcel.rebirth[i][1]
       local needItemCnt = rareExcel.rebirth[i][2]

        if attrLockNum and attrLockNum > 0 then
            needItemCnt = needItemCnt * (attrLockNum + 1)
        end

       local nowItemCnt = BagLogic.getItemCnt(human, needItemID)
	   if nowItemCnt < needItemCnt then 
	   	  return Broadcast.sendErr(human, Util.format(Lang.XIANZHI_NO_ITEM, ItemDefine.getValue(needItemID,"name")))
	   end
    end

    for i = 1, #rareExcel.rebirth do
       local needItemID = rareExcel.rebirth[i][1]
       local needItemCnt = rareExcel.rebirth[i][2]

        if attrLockNum and attrLockNum > 0 then
            needItemCnt = needItemCnt * (attrLockNum + 1)
        end

       BagLogic.delItem(human, needItemID, needItemCnt, "equip_wash")
    end
    

    local excludeAttrList
    if idxList then
        excludeAttrList = {}
        for idx in pairs(idxList) do
            local attrType = equipGrid.attr[idx] and equipGrid.attr[idx][1]
            if attrType then
                excludeAttrList[attrType] = 1
            end
        end
    end


    local attr, quality = EquipLogic.randomAttr(equipGrid.id, true, equipGrid.quality, excludeAttrList)

    for idx in pairs(idxList or {}) do
        if attr[idx] and equipGrid.attr[idx] then
            attr[idx][1] = equipGrid.attr[idx][1] -- attrType
            attr[idx][2] = equipGrid.attr[idx][2] -- attrValue
            attr[idx][3] = equipGrid.attr[idx][3] -- color
        end
    end


    equipGrid.washAttr = attr
    equipGrid.washQuality = quality

    HeroGrowUp.onCallback(human, HeroGrowUp.TASKTYPE19, 1)

    Broadcast.sendErr(human, Lang.EQUIP_WASH_RANDOM_SUC)
    randomQuery(human, bagIndex, heroUuid, pos)

    TriggerLogic.PublishEvent(TriggerDefine.EQUIP_REFINEMENT, human.db._id, 1)
end

-- 洗练保存
function randomSave(human, bagIndex, heroUuid, pos)
    local equipGrid, heroGrid, heroIndex = getEquipGrid(human, bagIndex, heroUuid, pos)
    if not equipGrid then return end

    local washAttr = equipGrid.washAttr
    local washQuality = equipGrid.washQuality
    if not washAttr or not washQuality then return end

    -- equipGrid.attr = washAttr

    local _, idxList = getEquipLockAttrInfo(equipGrid)
    for idx, attrInfo in ipairs(washAttr) do
        if not idxList or not idxList[idx] then
            equipGrid.attr[idx] = attrInfo
        end
    end

    equipGrid.quality = washQuality
    equipGrid.washAttr = nil
    equipGrid.washQuality = nil
    EquipLogic.checkAttr(equipGrid)
    -- 更新背包的
    if not heroGrid then   
       EquipLogic.sendEquipChange(human, bagIndex, equipGrid, EquipLogic.EQUIP_BAG_OP_CHANGE)
    end

    Broadcast.sendErr(human, Lang.EQUIP_WASH_SAVE_SUC)
    randomQuery(human, bagIndex, heroUuid, pos)

    --刷新属性
    if heroGrid and heroIndex and heroGrid.id then
        -- if not heroGrid or not heroIndex or not then
        --     return Broadcast.sendErr(human, Lang.DRILL_CHOOSE_FRIEND_ERR_INFO)
        -- end
        ObjHuman.doCalcHero(human, heroIndex)
        HeroLogic.sendHeroBagDynamic(human, heroGrid.id, heroIndex)
    end
end


-- 锁定/解锁装备洗练属性
function LockEquipAttr(human, bagIndex, heroUuid, pos, opType, attrIdx)
    if opType ~= 0 and opType ~= 1 then
        return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
    end

    local equipGrid = getEquipGrid(human, bagIndex, heroUuid, pos)
    if not equipGrid then
        return Broadcast.sendErr(human, Lang.EQUIP_GRID_ERR)
    end

    if not equipGrid.attr or #equipGrid.attr <= 1 then
        return Broadcast.sendErr(human, Lang.EQUIP_ATTR_CANNOT_LOCK)
    end

    -- 洗练结束才能锁定
    if equipGrid.washAttr then
        return Broadcast.sendErr(human, Lang.EQUIP_ATTR_CANNOT_LOCK)
    end
    

    if not equipGrid.attr[attrIdx] then
        return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
    end

    local attrLockNum, idxList = getEquipLockAttrInfo(equipGrid)

    if not attrLockNum then
        Broadcast.sendErr(human, Lang.EQUIP_ATTR_CANNOT_LOCK)
    end

    if opType == 1 then
        if attrLockNum + 1 >= #equipGrid.attr then
            return Broadcast.sendErr(human, Lang.EQUIP_ATTR_CANNOT_LOCK_ALL)
        end

        if idxList[attrIdx] then
            return Broadcast.sendErr(human, Lang.EQUIP_ATTR_LOCKED)
        end
    else
        if not idxList[attrIdx] then
            return Broadcast.sendErr(human, Lang.EQUIP_ATTR_UNLOCK)
        end
    end

    -- 更新数据
    equipGrid.attr[attrIdx][4] = opType

    -- 推送数据给客户端
    randomQuery(human, bagIndex, heroUuid, pos)
end


-- 取消装备未选择的洗练属性
function CancelEquipRandomAttr(human, bagIndex, heroUuid, pos)
    local equipGrid = getEquipGrid(human, bagIndex, heroUuid, pos)
    if not equipGrid then
        return Broadcast.sendErr(human, Lang.EQUIP_GRID_ERR)
    end

    equipGrid.washAttr = nil
    equipGrid.washQuality = nil

    randomQuery(human, bagIndex, heroUuid, pos)
end

local function EquipRefining_GetData(equipGrid, tMsgData)
     local baseRate = 1
    --装备特效
    local effectLen = 0
    local msgEffects = tMsgData.tLefteffects
    for effectId in pairs(equipGrid.effectList or {}) do
        effectLen = effectLen + 1
        local effectCfg = EquipTeXiao[effectId]

        msgEffects[effectLen].name = effectCfg.name
        msgEffects[effectLen].color = effectCfg.quality
        msgEffects[effectLen].attr.key = effectCfg.attrs[1][1]
        msgEffects[effectLen].attr.value = effectCfg.attrs[1][2]
    end
    msgEffects[0] = effectLen

    -- 英雄专属
    if equipGrid.exclusiveHeroId then
        local heroCfg = HeroExcel.hero[equipGrid.exclusiveHeroId]
        tMsgData.tLeftHero = heroCfg.name
    end
    
    if equipGrid.RefiningEffectList then
        effectLen = 0
        local tData = tMsgData.tRighteffects
        for effectId in pairs(equipGrid.RefiningEffectList) do
            effectLen = effectLen + 1
            local effectCfg = EquipTeXiao[effectId]

            tData[effectLen].name = effectCfg.name
            tData[effectLen].color = effectCfg.quality
            tData[effectLen].attr.key = effectCfg.attrs[1][1]
            tData[effectLen].attr.value = effectCfg.attrs[1][2]
        end
        tData[0] = effectLen
    end

    if equipGrid.RefiningHeroId then
        local heroCfg = HeroExcel.hero[equipGrid.RefiningHeroId]
        tMsgData.tRightHero = heroCfg.name
    end
end

local function EquipRefining_CheckCanDo(id)
    local itemConfig = ItemDefine.getConfig(id)
    if not itemConfig then
        return false
    end

    if itemConfig.subType ~= ItemDefine.EQUIP_SUBTYPE_RING and itemConfig.subType ~= ItemDefine.EQUIP_SUBTYPE_AMULET then
        return false
    end

    return true
end

local function EquipRefining_CheckEffect(tNowEffect, tGetEffect)
    local bRet = false

    if nil == _G.next(tGetEffect) and nil ~= _G.next(tNowEffect)  then
        return true
    end

    if nil ~= _G.next(tGetEffect) and nil == _G.next(tNowEffect) then
        return true
    end

    for effectId in pairs(tGetEffect) do
        if not tNowEffect[effectId] then
            bRet = true
            break
        end
    end

    return bRet
end

local function EquipRefining_CheckHeroID(nNowHeroID, nGetHeroID)
    local bRet = false
    if nNowHeroID then
        if not nGetHeroID then
            bRet = true
        else
            if nNowHeroID ~= nGetHeroID then
                bRet = true
            end
        end
    else
        if nGetHeroID then
            bRet = true
        end
    end

    return bRet
end

-- 装备精炼查询
function EquipRefiningQuery(human, bagIndex, heroUuid, pos)
    local equipGrid = getEquipGrid(human, bagIndex, heroUuid, pos)
    if not equipGrid then
        return Broadcast.sendErr(human, Lang.EQUIP_GRID_ERR)
    end

    if false == EquipRefining_CheckCanDo(equipGrid.id) then
        return 
    end

    local tMsgData = Msg.gc.GC_EQUIP_REFINING_QUERY

    tMsgData.tLefteffects[0] = 0
    tMsgData.tLeftHero = ""
    tMsgData.tRighteffects[0] = 0
    tMsgData.tRightHero = ""

    Grid.makeItem(tMsgData.tEffectItem, EQUIPEFINING_DEL_GOODID, EQUIPEFINING_DEL_TYPE_1)
    Grid.makeItem(tMsgData.tHeroItem, EQUIPEFINING_DEL_GOODID, EQUIPEFINING_DEL_TYPE_2)

    EquipRefining_GetData(equipGrid, tMsgData)
	
    Msg.send(tMsgData, human.fd)
end

-- 开始装备精炼
function EquipRefiningDo(human, bagIndex, heroUuid, pos, nOperate)
    local equipGrid = getEquipGrid(human, bagIndex, heroUuid, pos)
    if not equipGrid then
        return Broadcast.sendErr(human, Lang.EQUIP_GRID_ERR)
    end

    if false == EquipRefining_CheckCanDo(equipGrid.id) then
        return 
    end

    local nNeedNum = nOperate == EQUIPREFINING_EFFECT and EQUIPEFINING_DEL_TYPE_1 
        or (nOperate == EQUIPREFINING_HERONAME and EQUIPEFINING_DEL_TYPE_2 or (EQUIPEFINING_DEL_TYPE_1 + EQUIPEFINING_DEL_TYPE_2))

    local nowItemCnt = BagLogic.getItemCnt(human, EQUIPEFINING_DEL_GOODID)
    if nowItemCnt < nNeedNum then 
        return Broadcast.sendErr(human, Util.format(Lang.XIANZHI_NO_ITEM, ItemDefine.getValue(EQUIPEFINING_DEL_GOODID,"name")))
    end

    BagLogic.delItem(human, EQUIPEFINING_DEL_GOODID, nNeedNum, "equip_wash")

    local tNowEffect = {}
    if equipGrid.effectList then
        for effectId in pairs (equipGrid.effectList) do
            tNowEffect[effectId] = 1
        end
    end

    if nOperate == EQUIPREFINING_EFFECT then
        for i = 1, 15, 1 do
            equipGrid.RefiningEffectList = EquipLogic.randEffectAttrList(equipGrid.id)
            if true == EquipRefining_CheckEffect(tNowEffect, equipGrid.RefiningEffectList) then
                break
            end
        end
    elseif EQUIPREFINING_HERONAME == nOperate then
        for i = 1, 15, 1 do
            equipGrid.RefiningHeroId = EquipLogic.randHeroExclusive(equipGrid.id)
            if true == EquipRefining_CheckHeroID(equipGrid.exclusiveHeroId, equipGrid.RefiningHeroId) then
                break
            end
        end
    else
        for i = 1, 15, 1 do
            equipGrid.RefiningEffectList = EquipLogic.randEffectAttrList(equipGrid.id)
            equipGrid.RefiningHeroId = EquipLogic.randHeroExclusive(equipGrid.id)
            if true == EquipRefining_CheckEffect(tNowEffect, equipGrid.RefiningEffectList) and 
                true == EquipRefining_CheckHeroID(equipGrid.exclusiveHeroId, equipGrid.RefiningHeroId) then
                break
            end
        end
    end

    local tMsgData = Msg.gc.GC_EQUIP_REFINING_DO
    tMsgData.tLeftHero = ""
    tMsgData.tRightHero = ""
    tMsgData.tLefteffects[0] = 0
    tMsgData.tRighteffects[0] = 0
    EquipRefining_GetData(equipGrid, tMsgData)

    Msg.send(tMsgData, human.fd)
end

-- 放弃精炼
function EquipRefiningAbandon(human, bagIndex, heroUuid, pos)
    local equipGrid = getEquipGrid(human, bagIndex, heroUuid, pos)
    if not equipGrid then
        return Broadcast.sendErr(human, Lang.EQUIP_GRID_ERR)
    end

    if false == EquipRefining_CheckCanDo(equipGrid.id) then
        return 
    end

    if equipGrid.RefiningEffectList then
        equipGrid.RefiningEffectList = nil
    end

    if equipGrid.RefiningHeroId then
        equipGrid.RefiningHeroId = nil
    end
    
    EquipRefiningQuery(human, bagIndex, heroUuid, pos)
end

function EquipRefiningSave(human, bagIndex, heroUuid, pos)
    local equipGrid, heroGrid, heroIndex = getEquipGrid(human, bagIndex, heroUuid, pos)
    if not equipGrid then
        return Broadcast.sendErr(human, Lang.EQUIP_GRID_ERR)
    end

    if false == EquipRefining_CheckCanDo(equipGrid.id) then
        return
    end

    if equipGrid.RefiningEffectList then
        equipGrid.effectList = equipGrid.RefiningEffectList
    end

    if equipGrid.RefiningHeroId then
        equipGrid.exclusiveHeroId = equipGrid.RefiningHeroId
    end

    equipGrid.RefiningEffectList = nil
    equipGrid.RefiningHeroId = nil

    EquipLogic.checkAttr(equipGrid)
    if not heroGrid then   
       EquipLogic.sendEquipChange(human, bagIndex, equipGrid, EquipLogic.EQUIP_BAG_OP_CHANGE)
    end

     --刷新属性
    if heroGrid and heroIndex and heroGrid.id then
        ObjHuman.doCalcHero(human, heroIndex)
        HeroLogic.sendHeroBagDynamic(human, heroGrid.id, heroIndex)
        HeroEquip.query(human, heroGrid.id, heroIndex)
    end

    EquipRefiningQuery(human, bagIndex, heroUuid, pos)
end