-- 玩家 功能函数模块
local Config = require("Config")
local Json = require("common.Json")
local Msg = require("core.Msg")
local MonsterExcel = require("excel.monster")
local ObjHuman = require("core.ObjHuman")
local CombatPosLogic = require("combat.CombatPosLogic")
local CombatLogic = require("combat.CombatLogic")
local CombatDefine = require("combat.CombatDefine")
local JjcDB = require("jjc.JjcDB")
local HeroGrid = require("hero.HeroGrid")
local RoleDefine = require("role.RoleDefine")
local RoleDBLogic = require("role.RoleDBLogic")
local UnionDBLogic = require("union.UnionDBLogic")
local MoshouLogic = require("moshou.MoshouLogic")
local SettingLogic = require("setting.SettingLogic")
local RoleExcel = require("excel.role")
local Lang = require("common.Lang")
local Util = require("common.Util")
local FriendDBLogic = require("friend.FriendDBLogic")
local HeroLogic = require("hero.HeroLogic")
local UnionLogic = require("union.UnionLogic")
local RoleHeadLogic = require("role.RoleHeadLogic")
local UnionExcel = require("excel.union")
local FilterUtil = require("common.FilterUtil")
local Broadcast = require("broadcast.Broadcast")
local RoleRealmLogic = require("roleSystem.RoleRealmLogic")
local Timer = require("core.Timer")


FieldRoleBase = {identity=1, name=1, lv=1, vipLv=1, systemSet=1, head=1, headFrame=1, body=1, chenghao=1, unionUuid=1, zhandouli=1, blue=1, yellow=1,birthday = 1,sex = 1,signature = 1}
local FAKE_HUMAN = {db = nil}

BIRTHDAY_TYPE = 1
SEX_TYPE = 2
SIGNATURE_TYPE = 4

function makeRoleBaseFields(fields)
    fields._id = "1" 
    for key in pairs(FieldRoleBase) do
        fields[key] = 1
    end
end

local TEMP_COMBAT_FIELD = nil
function getCombatField()
    if not TEMP_COMBAT_FIELD then
        TEMP_COMBAT_FIELD = {}
        for k in pairs(CombatLogic.FieldsCombat) do
            TEMP_COMBAT_FIELD[k] = 1
        end
        makeRoleBaseFields(TEMP_COMBAT_FIELD)
    end
    return TEMP_COMBAT_FIELD
end

-- 删除多余的数据
function clear2MinNet(db, net)
    for key in pairs(FieldRoleBase) do
        if net[key] and (not db or not db[key]) then
            net[key] = nil
        end
    end
end

-- 构造rolebase 结构体
function getRoleBase(human, net, combatType, isMinNet)
    local db = human and human.db
    net.uuid = db and (db._id or db.uuid) or ""
    net.name = tostring(db and db.name or "")
    net.lv = db and db.lv or 0
    net.identity = db and db.identity or ""
    net.head = db and db.head or 0
    net.headFrame = db and db.headFrame or RoleDefine.DEFAULT_HEAD_FRAME
    net.body = db and db.body or 0
    net.createTime = db and db.createTime or 0
    if db and db.signIn then
        net.signInCnt = (db.signIn.cnt or 0) + 1
    else
        net.signInCnt = 1
    end
    net.birthday = net.birthday or {}
    net.birthday.year = (db and db.birthDay) and db.birthDay.year or 1970
    net.birthday.month = (db and db.birthDay) and db.birthDay.month or 1
    net.birthday.day = (db and db.birthDay) and db.birthDay.day or 1
    net.sex = db and db.sex or 1
    net.signature = db and db.signature or ""
    net.chenghaoID = db and db.chenghao or 0
    net.chenghaoName = ""
    if db and db.chenghao and RoleExcel.chenghao[db.chenghao] then
        net.chenghaoName = RoleExcel.chenghao[db.chenghao].name
    end
    net.unionUuid = db and db.unionUuid or ""
    net.bannerID = getUnionBannerID(db)
    net.zhandouli = db and db.zhandouli or 0
    net.serverName = Config.SVR_NAME
    if combatType and db and db.combatHero then
        net.zhandouli = CombatPosLogic.getCombatHeroZDL(human, combatType)
    end
    net.blue = net.blue or {}
    net.blue.lv = (db and db.blue) and db.blue.lv or 0
    net.blue.year = (db and db.blue and db.blue.year) and 1 or 0
    net.blue.lux = (db and db.blue and db.blue.lux) and 1 or 0
    net.yellow = net.yellow or {}
    net.yellow.lv = (db and db.yellow) and db.yellow.lv or 0
    net.yellow.year = (db and db.yellow and db.yellow.year) and 1 or 0
    net.yellow.lux = (db and db.yellow and db.yellow.lux) and 1 or 0

    net.realmName = RoleRealmLogic.getRealmName(human)
    net.nServerIndex = Config.SVR_INDEX
    
    if isMinNet then
       clear2MinNet(db, net)
    end
    return (db ~= nil)
end 

function getRoleBaseByUuid(uuid, net, combatType, isMinNet)
    FAKE_HUMAN.db = nil 
    if uuid and uuid ~= "" then
        local fields = getCombatField()
        FAKE_HUMAN.db = RoleDBLogic.getDb(uuid, fields)
    end
    return getRoleBase(FAKE_HUMAN, net, combatType, isMinNet), FAKE_HUMAN
end

function makeRoleBase(data, net, combatType, isMinNet)
    FAKE_HUMAN.db = data
    return getRoleBase(FAKE_HUMAN, net, combatType, isMinNet)
end

function makePlayInfo(net, uuid, nCombatType)
    if not uuid or uuid == "" then return end
    net.yjUuid = ""
    local fields = getCombatField()
    local db = RoleDBLogic.getDb(uuid, fields)
    if not db then 
        return makePlayInfoByOther(net, uuid) -- 假人
    end
    FAKE_HUMAN.db = db

	-- 真人
    local combatType = nCombatType or CombatDefine.COMBAT_TYPE1
    local combatHero = CombatPosLogic.getCombatHeros(FAKE_HUMAN, combatType)
    if nil == _G.next(combatHero) then
        print("'[makePlayInfo] 获取不到对应的英雄数据, 取默认阵容 combatType = "..combatType)
        combatHero = CombatPosLogic.getCombatHeros(FAKE_HUMAN, CombatDefine.COMBAT_TYPE1)
    end

    local union = UnionDBLogic.getUnion(db.unionUuid)
    
    getRoleBase(FAKE_HUMAN, net.roleBase,combatType)

    net.moshouBody = MoshouLogic.getCombatMoshouBody(FAKE_HUMAN,combatType)
    net.defenceList[0] = 0
    for i = 1, CombatDefine.COMBAT_HERO_CNT do
        local uuid = combatHero and combatHero[i]
        local heroGrid = HeroLogic.getHeroGridByUuid(FAKE_HUMAN, uuid)
        if heroGrid then
            net.defenceList[0] = net.defenceList[0] + 1
            local defenceNet = net.defenceList[net.defenceList[0]]
            HeroGrid.makeHeroSimple(defenceNet, heroGrid, heroGrid.bagIndex, FAKE_HUMAN)

            if i == CombatDefine.COMBAT_HERO_CNT then
                net.yjUuid = uuid
            end
        end
    end
    net.vipLv = db.vipLv or 0 
    -- vip 大于14  不管是否屏蔽 客户端都显示 王者VIP
    if SettingLogic.isNoShowVip(FAKE_HUMAN) == true and net.vipLv ~= 0 and net.vipLv < 14 then
		net.vipLv = -1
	end  
    net.unionName = union and union.name or ""
    net.svrName = Config.SVR_NAME

    net.isFriend = 0
    if FriendDBLogic.isBlackFriend(FAKE_HUMAN.db._id,uuid) then
        net.isFriend = 2
    elseif FriendDBLogic.isFriend(FAKE_HUMAN.db._id,uuid) then
        net.isFriend = 1
    end

    return true
end

-- 获取玩家公会旗帜
function getUnionBannerID(db)
    if db then
        local union = UnionDBLogic.getUnion(db.unionUuid)
        if union then
            return union.bannerID
        end
    end
    return 0
end

function makeOtherPlayInfo(net,jjcData)
    if not jjcData then return end

    local monsterOutID = jjcData.monsterOutID
    local monsterOutConfig = MonsterExcel.monsterOut[monsterOutID]

    FAKE_HUMAN.db = jjcData

    getRoleBase(FAKE_HUMAN, net.roleBase)

    if net.moshouBody then
        net.moshouBody = 0
    end

    net.defenceList[0] = 0
    for i = 1, CombatDefine.COMBAT_HERO_CNT do
        local monsterConfig = monsterOutConfig.member[i]
        local monsterID = monsterConfig and monsterConfig[1]
        if monsterID and monsterID > 0 then
            local monsterLv = monsterConfig and monsterConfig[2]
            local others = HeroGrid.createOthers(monsterLv)
            net.defenceList[0] = net.defenceList[0] + 1
            local defenceNet = net.defenceList[net.defenceList[0]]
            HeroGrid.makeHeroSimpleByMonsterID(defenceNet, monsterID, others)
            net.defenceList[i].index = i
        end
    end
end

function makePlayInfoByOther(net, uuid)
    local jjcData = JjcDB.getJjcData(uuid)
    if not jjcData then return end

    makeOtherPlayInfo(net,jjcData)
    net.vipLv = 0    
    net.isFriend = 0
    net.unionName = ""
    net.svrName = Config.SVR_NAME
    
    return true
end

CHANGE_BASEINFO_FAIL = 0
CHANGE_BASEINFO_SUCCESS = 1

-- 更改基础信息查询
function changeBaseInfoQuery(human,type)
    local msgRet = Msg.gc.GC_ROLE_CHANGE_BASEINFO_QUERY
    msgRet.price = RoleExcel.define[type].zuanshi
	if human.db.changeBase == nil or human.db.changeBase[type] == nil then
        msgRet.price = 0
    end
	Msg.send(msgRet,human.fd)
end

-- 更改基础信息
function changeBaseInfo(human,type,param)
    local msgRet = Msg.gc.GC_ROLE_CHANGE_BASEINFO
    msgRet.ret = CHANGE_BASEINFO_FAIL

    if human.db.changeBase ~= nil and human.db.changeBase[type] ~= nil then
        -- 不是免费，且钻石不够
        if RoleExcel.define[type].zuanshi ~= 0 and human.db.zuanshi < RoleExcel.define[type].zuanshi then
            msgRet.tip = Lang.COMMON_NO_ZUANSHI
            Msg.send(msgRet,human.fd)
            return 
        end
        human.db.changeBase[type] = human.db.changeBase[type] + 1
	    ObjHuman.decZuanshi(human, -RoleExcel.define[type].zuanshi, "change_baseinfo")
    else
        -- 首次免费
        human.db.changeBase = human.db.changeBase or {}
        human.db.changeBase[type] = 1
    end

    if type == BIRTHDAY_TYPE then
        -- 改生日
        local tb = Util.split(param, "|")
        if tb[1] and tb[2] and tb[3] then
            local tbTemp = {}
            tbTemp.year = tonumber(tb[1])
            tbTemp.month = tonumber(tb[2])
            tbTemp.day = tonumber(tb[3])
            local time = os.time(tbTemp)
            local now = os.time()
            -- time == nil 意味着时间小于1970.01.01 时间合法
            if time ~= nil and time >= now then
                msgRet.tip = Lang.CHANGE_BASEINFO_TIME_ERR
                Msg.send(msgRet,human.fd)
                return 
            end
            human.db.birthDay = {}
            human.db.birthDay.year = tbTemp.year
            human.db.birthDay.month = tbTemp.month
            human.db.birthDay.day = tbTemp.day

            msgRet.ret = CHANGE_BASEINFO_SUCCESS
            msgRet.tip = Lang.CHANGE_BASEINFO_TIP
            Msg.send(msgRet,human.fd)
            return 
        end
        msgRet.tip = Lang.CHANGE_BASEINFO_TIME_ERR
        Msg.send(msgRet,human.fd)
        return 
    elseif type == SEX_TYPE then
        -- 改性别
        if param == human.db.sex then
            msgRet.tip = Lang.CHANGE_BASEINFO_NO_EFFECT_ERR
            Msg.send(msgRet,human.fd)
            return
        end
        human.db.sex = tonumber(param)
        msgRet.ret = CHANGE_BASEINFO_SUCCESS
        msgRet.tip = Lang.CHANGE_BASEINFO_TIP
        Msg.send(msgRet,human.fd)
        return
    elseif type == SIGNATURE_TYPE then
        -- 改个性签名
        local strLen = string.len(param)
        if strLen > 150 then
            msgRet.tip = Lang.CHANGE_BASEINFO_STR_LEN_ERR
            Msg.send(msgRet,human.fd)
            return 
        end
        local newParam = FilterUtil.filter(param) 
        if param ~= newParam then
            return Broadcast.sendErr(human, Lang.ROLE_SINGATURE_DESC_FILTER)
        end
        human.db.signature = newParam
        msgRet.ret = CHANGE_BASEINFO_SUCCESS
        msgRet.tip = Lang.CHANGE_BASEINFO_TIP
        Msg.send(msgRet,human.fd)
    else
    end
end

function roleInfoIconQuery(human,type,param)
    if type == 1 then
        -- 公会查询
        local msgRet = Msg.gc.GC_ROLE_INFO_ICON_UNION
        local union = UnionDBLogic.getUnion(param)  
        if not union then
            return
        end  

        local lv = math.min(union.lv, #UnionExcel.union)
        local config = UnionExcel.union[lv]

        msgRet.unionUuid = union._id
        msgRet.name = union.name or ""
        msgRet.maxCnt = config.maxCnt
        msgRet.curCnt = union.curCnt
        msgRet.bannerID = union.bannerID
        msgRet.needLv = union.needLv or 0
        msgRet.notice = union.notice
        msgRet.lv = lv

        local presidentDB = RoleDBLogic.getDb(union.presidentUuid, "name")
        msgRet.presidentName = presidentDB and presidentDB.name or ""

        Msg.send(msgRet,human.fd)
    elseif type == 2 then
        local id = tonumber(param)
        local isActive = RoleHeadLogic.isActive(human, RoleHeadLogic.HEAD_TYPE_4, id)
        local msgRet = Msg.gc.GC_ROLE_INFO_ICON_CHENGHAO
        local config = RoleExcel.chenghao[id]
        msgRet.chenghao.id = id
	    msgRet.chenghao.name = config.name
	    msgRet.chenghao.desc = config.desc
	    local len = 0
	    for k,v in ipairs(config.attrs) do
	    	len = len + 1
	    	msgRet.chenghao.attrs[len].key = v[1]
	    	msgRet.chenghao.attrs[len].value = v[2]
	    end
	    msgRet.chenghao.attrs[0] = len
	    msgRet.chenghao.isActive = isActive and 1 or 0
        msgRet.panelID = config.panelID
        Msg.send(msgRet,human.fd)
    end
end

function RoleLogic_GetOnlineTime(human, nType)
    if not human.db.onlineTimeDayReport then
        human.db.onlineTimeDayReport = os.time()
    end

    local tMsgData = Msg.gc.GC_ONLINETIME_REPORT
    local nNowTime = os.time()

    tMsgData.time = nNowTime - human.db.onlineTimeDayReport
    tMsgData.nType = nType
    Msg.send(tMsgData, human.fd)
    print("[RoleLogic_GetOnlineTime] 下发协议结束")
end

function RoleLogic_CreateTime(uuid)
    Timer.addLater(5400, RoleLogic_OnTime, uuid)
end

function RoleLogic_OnTime(uuid)
    local human = ObjHuman.onlineUuid[uuid]
    if not human then
        return
    end

    RoleLogic_GetOnlineTime(human, 1)
    RoleLogic_CreateTime(human.db._id)
end

function onLogin(human)
   RoleLogic_CreateTime(human.db._id)
end

local function isChange(human)
    if not human.db.topupAcount or human.db.topupAcount <= 0 then
        return false
    end

    return true
end

function RoleLogic_QueryHumanInfo(human)
    local tMsgData = Msg.gc.GC_COMMON_HUMAN_INFO
    tMsgData.bChange = isChange(human) and 1 or 0

    Msg.send(tMsgData, human.fd)
end