%%%------------------------------------
%%% @Module  : lib_auction_common
%%% @Author  : zengzy
%%% @Created : 2019-01-15
%%% @Description: 拍卖奖池计算
%%%------------------------------------
-module(lib_auction_common).
-include("server.hrl").
-include("common.hrl").
-include("activitycalen.hrl").
-include("def_module.hrl").
-include("def_fun.hrl").
-include("auction_common.hrl").
-include ("def_goods.hrl").
-export([
		calc_auction_goods/2     %%计算拍卖物品
		,calc_auction_goods/3  	 %%跨服计算拍卖物品(带世界等级)
		,get_last_3_liveness/1   %%获取玩家活跃度前3日平均值
    ]).


%% ---------------------------------------------------------------------------
%% @doc 计算拍卖物品
-spec calc_auction_goods(Module, GuildList) -> Return when
    Module          :: integer(),                							%% 功能模块id
    GuildList       :: [{GuildId, Rank, Zone, RoleList}],
	GuildId 	    :: integer(), 											%% 公会id
	Rank 	    	:: integer(), 											%% 排名
	Zone 	    	:: integer(), 											%% 战区 没有则默认1
	RoleList 		:: [{RoleId::integer(), Lv::integer()}], 				%% RoleList:公会参加玩家id 格式 [{RoleId, Lv}]
    Return          :: [{GuildId::integer(), ObjectList::tuple()}].			%% 公会物品列表
%% ---------------------------------------------------------------------------
calc_auction_goods(ModuleId, GuildList) ->
	WorldLv = util:get_world_lv(),
	do_calc_auction_goods(ModuleId, WorldLv, GuildList, []).

%% ---------------------------------------------------------------------------
%% @doc 跨服计算拍卖物品
-spec calc_auction_goods(Module, GuildList, WorldLv) -> Return when
    Module          :: integer(),                									%% 功能模块id
    GuildList       :: [{GuildId, Rank, Zone, RoleList}],
	GuildId 	    :: integer(), 													%% 公会id
	Rank 	    	:: integer(), 													%% 排名
	Zone 	    	:: integer(), 													%% 战区 没有则默认1
	RoleList 		:: [{RoleId::integer(), Lv::integer(), LiveNess::integer()}], 	%% RoleList: 公会参加玩家id 格式 [{RoleId, Lv, LiveNess}]
																					%% LiveNess: 玩家活跃度前3日平均值
	WorldLv 		:: integer(), 													%% 世界等级
    Return          :: [{GuildId::integer(), ObjectList::tuple()}].					%% 公会物品列表
%% ---------------------------------------------------------------------------
calc_auction_goods(ModuleId, GuildList, WorldLv) ->
	do_calc_auction_goods(ModuleId, WorldLv, GuildList, []).

do_calc_auction_goods(_ModuleId, _WorldLv, [], GuildGoodList) -> GuildGoodList;
do_calc_auction_goods(ModuleId, WorldLv, [{GuildId, Rank, Zone, RoleList} | T], GuildGoodList) ->
	GoodsRankZone = get_goods_rank_zone(ModuleId, Zone),
	GoodsRankList = data_auction_common:get_module_rank_goods(ModuleId, GoodsRankZone, Rank),
	TodayTime = utime:unixdate(),
	{StTime, EtTime, NeedDay} = get_live_st_and_et(),
	RoleWorthList = calc_role_3_worth(RoleList, TodayTime, StTime, EtTime, NeedDay, []),
	RewardPoolList = calc_reward_pool_list(GoodsRankList, RoleWorthList, []),
	RewardGoodList = data_auction_common:get_pool_reward_goods(ModuleId, Zone, WorldLv, Rank),
	GoodsList = calc_goods_list(RewardGoodList, RewardPoolList, []),
	do_calc_auction_goods(ModuleId, WorldLv, T, [{GuildId, GoodsList} | GuildGoodList]).

%%获取参数设定的战区（根据功能区分）
get_goods_rank_zone(_ModuleId, _Zone) -> 1.

%%获取计算玩家活跃度的开始和结束时间
get_live_st_and_et() ->
    TodayTime = utime:unixdate(),
    OpenDay = util:get_open_day(),
    {StTime, EtTime} = if
        OpenDay == 1 ->
            NeedDay = 1,
            {TodayTime - ?NEED_DAY * ?ONE_DAY_SECONDS, TodayTime - ?ONE_DAY_SECONDS};
        OpenDay == 2 orelse OpenDay == 3 ->
            NeedDay = 1,
            {TodayTime - ?ONE_DAY_SECONDS, TodayTime - ?ONE_DAY_SECONDS};
        true ->
            NeedDay = ?NEED_DAY,
            {TodayTime - ?NEED_DAY * ?ONE_DAY_SECONDS, TodayTime - ?ONE_DAY_SECONDS}
    end,
    {StTime, EtTime, NeedDay}.

%%计算玩家前三日的奖池价值
calc_role_3_worth([], _TodayTime, _StTime, _EtTime, _NeedDay, RoleWorthList) -> RoleWorthList;
calc_role_3_worth([{_RoleId, Lv, LiveNess} | T], TodayTime, StTime, EtTime, NeedDay, RoleWorthList) ->
    RoleGoodList = data_auction_common:get_role_live_goods(Lv, LiveNess),
    Fun = fun({RewardId, Worth}, TmpList) ->
    	case lists:keyfind(RewardId, 1, TmpList) of
    		false -> [{RewardId, Worth} | TmpList];
    		{_, OldWorth} ->
    			lists:keystore(RewardId, 1, TmpList, {RewardId, OldWorth + Worth})
    	end
   	end,
   	NewRoleWorthList = lists:foldl(Fun, RoleWorthList, RoleGoodList),
   	calc_role_3_worth(T, TodayTime, StTime, EtTime, NeedDay, NewRoleWorthList);
calc_role_3_worth([{RoleId, Lv} | T], TodayTime, StTime, EtTime, NeedDay, RoleWorthList) ->
    LiveNess = case ets:lookup(?ETS_ACTIVITYCALEN, RoleId) of
        [#ets_activitycalen{create_time = Creatime, liveness_list = LiveNessList}] ->
        	%%今天注册，默认给120
            IsRegToday = utime:unixdate(Creatime) == TodayTime,
        	CalcLiveNessList = ?IF(IsRegToday, [{StTime, ?DEFAULT_LIVENESS}], LiveNessList),
            NewNeedDay = ?IF(IsRegToday, 1, NeedDay),
            Sum = lists:sum([ Val || {Time, Val} <- CalcLiveNessList, Time >= StTime, Time =< EtTime]),
            round(Sum / NewNeedDay);
        _ ->
            0
    end,
    RoleGoodList = data_auction_common:get_role_live_goods(Lv, LiveNess),
    Fun = fun({RewardId, Worth}, TmpList) ->
    	case lists:keyfind(RewardId, 1, TmpList) of
    		false -> [{RewardId, Worth} | TmpList];
    		{_, OldWorth} ->
    			lists:keystore(RewardId, 1, TmpList, {RewardId, OldWorth + Worth})
    	end
   	end,
   	NewRoleWorthList = lists:foldl(Fun, RoleWorthList, RoleGoodList),
   	calc_role_3_worth(T, TodayTime, StTime, EtTime, NeedDay, NewRoleWorthList);
calc_role_3_worth([_Info | T], TodayTime, StTime, EtTime, NeedDay, RoleWorthList) ->
	calc_role_3_worth(T, TodayTime, StTime, EtTime, NeedDay, RoleWorthList).

%%计算奖池内容
calc_reward_pool_list([], _, RewardPoolList) -> RewardPoolList;
calc_reward_pool_list(_, [], RewardPoolList) -> RewardPoolList;
calc_reward_pool_list([{RewardId, NeedWorth, Limit} | T], RoleWorthList, RewardPoolList) ->
	case lists:keyfind(RewardId, 1, RoleWorthList) of
		{_, RoleWorth} when RoleWorth >= NeedWorth ->
			calc_reward_pool_list(T, RoleWorthList, [{RewardId, RoleWorth, Limit} | RewardPoolList]);
		_ -> calc_reward_pool_list(T, RoleWorthList, RewardPoolList)
	end.

%%计算拍卖随机物品
calc_goods_list(_, [], GoodsList) -> GoodsList;
calc_goods_list([], _, GoodsList) -> GoodsList;
calc_goods_list(RewardGoodList, [{RewardId, RoleWorth, Limit} | T], GoodsList) ->
	case lists:keyfind(RewardId, 1, RewardGoodList) of
		false -> calc_goods_list(RewardGoodList, T, GoodsList);
		{_, RandList} ->
			NewGoodsList = calc_goods(RandList, RoleWorth, Limit, 0, GoodsList),
			calc_goods_list(RewardGoodList, T, NewGoodsList)
	end.

%%随机物品
calc_goods([], _, _, _, GoodsList) -> GoodsList;
calc_goods(_, _, Max, Max, GoodsList) -> GoodsList;
calc_goods(_, 0, _, _, GoodsList) -> GoodsList;
calc_goods(RandList, RoleWorth, Max, Min, GoodsList) ->
	FilterList = [{GoodId, Num, Worth} || {GoodId, Num, Worth} <- RandList, RoleWorth >= Worth],
	case FilterList == [] of
		true ->
			{GoodId, Num, Worth} = urand:list_rand(RandList),
			Ratio = round(RoleWorth / Worth * 100),
			case urand:rand(1, 100) of
				RandVal when RandVal =< Ratio ->
					[{?TYPE_GOODS, GoodId, Num} | GoodsList];
				_ -> GoodsList
			end;
		false ->
			{GoodId, Num, Worth} = urand:list_rand(FilterList),
			LeftRoleWorth = max(0, RoleWorth - Worth),
			calc_goods(RandList, LeftRoleWorth, Max, Min + 1, [{?TYPE_GOODS, GoodId, Num} | GoodsList])
	end.

%%获取前三日活跃度平均值
get_last_3_liveness(PS) ->
    #player_status{reg_time = CreateTime} = PS,
    TodayTime = utime:unixdate(),
    {StTime, EtTime, NeedDay} = get_live_st_and_et(),
    LiveNessList = lib_activitycalen_api:get_live_ness(PS, StTime, EtTime),
    IsRegToday = utime:unixdate(CreateTime) == TodayTime,
    CalcLiveNessList = ?IF(IsRegToday, [{StTime, ?DEFAULT_LIVENESS}], LiveNessList),
    Sum = lists:sum([ Val || {_Time, Val} <- CalcLiveNessList]),
    NewNeedDay = ?IF(IsRegToday, 1, NeedDay),
    round(Sum / NewNeedDay).
