%%%--------------------------------------
%%% @Module  : lib_vip_bag_onsale.erl
%%% @Author  : ckx
%%% @Created : 2019-06-17
%%% @Description:  VIP特惠活动
%%%--------------------------------------

-module(lib_vip_bag_onsale).
-include("custom_act.hrl").
% -include("common.hrl").
-include("server.hrl").
-include("figure.hrl").
-include("errcode.hrl").
% -include("def_fun.hrl").
% -include("goods.hrl").
% -include("def_module.hrl").
-include("predefine.hrl").
-include("vip_bag_onsale.hrl").
-include("def_event.hrl").
-include("rec_event.hrl").

-export([
	login/1 					%% 玩家登录初始化PS
	,act_end/2 					%% 活动结束，清楚数据
	,reset/3 					%% 删除玩家PS中的活动数据
	,get_onsale_price/4 		%% 判断玩家是否以及有礼包价格
	,do_get_onsale_price/4 		%% 试试手气，获取礼包价格
	,get_reward_price_info/4 	%% 获取礼包价格信息
	,is_vip_level_right/4 		%% 判断玩家VIP等级是否满足领取礼包的要求
	,check_bag_status/2 		%% 获取礼包状态
	,handle_event/2 			%% VIP发生改变时，更新礼包状态
]).

%% 登录更新玩家PS
login(RoleId) ->
	BagList = db_vip_bag_onsale_select(RoleId),
	F = fun([Type, SubType, Grade, Price, Percent], StateMap) ->
		case maps:get({Type, SubType}, StateMap, []) of
			[] ->
        		NewStateList = [{Grade, Price, Percent}];
        	StateList ->
        		NewStateList = [{Grade, Price, Percent} | StateList]
        end,
        maps:put({Type, SubType}, NewStateList, StateMap)
    end,
    LastStateMap = lists:foldl(F, #{}, BagList),
    #vip_bag_onsale{onsale_state = LastStateMap}.

%% 活动结束清除玩家活动数据
act_end(Type, SubType) ->
    spawn(fun()-> db_vip_bag_onsale_delete(Type, SubType) end),
    OnlineList = ets:tab2list(?ETS_ONLINE),
    IdList = [[PlayerId, Type, SubType] || #ets_online{id = PlayerId}<-OnlineList],
    lists:foreach(fun do_act_end/1, IdList).

do_act_end([PlayerId, Type, SubType]) ->
    lib_player:apply_cast(PlayerId, ?APPLY_CAST_STATUS, lib_vip_bag_onsale, reset, [Type, SubType]).

%% 删除在线玩家PS中关于该活动的数据
reset(PS, Type, SubType) ->
	#player_status{vip_bag_onsale = #vip_bag_onsale{onsale_state = OnsaleStateMap} = OnsaleState} = PS,
    NewOnsaleStateMap = maps:remove({Type, SubType}, OnsaleStateMap),
    PS#player_status{vip_bag_onsale = OnsaleState#vip_bag_onsale{onsale_state = NewOnsaleStateMap}}.

%% 判断玩家是否已经有礼包价格
%% false | {Price, Percent}
get_onsale_price(PS, Type, SubType, Grade) ->
	%% 判断是否已经有优惠价格
	#player_status{vip_bag_onsale = #vip_bag_onsale{onsale_state = OnsaleStateMap}} = PS,
	case maps:get({Type, SubType}, OnsaleStateMap, []) of
		[] -> false;
		StateList ->
			case lists:keyfind(Grade, 1, StateList) of
				%% 已获得优惠价格
				{Grade, Price, Percent} -> {Price, Percent};
				%% 未获得优惠价格
				false -> false
			end
	end.

%% 试试手气，获得礼包优惠价格
%% {false, ErrCode} | {Price, Percent, NewPS}
do_get_onsale_price(PS, Type, SubType, Grade) ->
	%% 查看是否已有特惠价格
	case get_onsale_price(PS, Type, SubType, Grade) of
		false ->
			%% 判断VIP等级是否满足
			case is_vip_level_right(PS, Type, SubType, Grade) of
				true ->
					%% 计算价格以及幸运值
					case cal_onsale_price_and_percent(Type, SubType, Grade) of
						{false, ErrCode} -> {false, ErrCode};
						%% 存储到数据库中，更新PS
						{Price, Percent} ->
							db_vip_bag_onsale_replace(PS#player_status.id, Type, SubType, Grade, Price, Percent),
							% ?DEBUG("UpdateDB SubType:~p Grade:~p Price:~p Percent:~p~n", [SubType, Grade, Price, Percent]),
							#player_status{vip_bag_onsale = #vip_bag_onsale{onsale_state = OnsaleStateMap}} = PS,
							case maps:get({Type, SubType}, OnsaleStateMap, []) of
								[] -> NewStateList = [{Grade, Price, Percent}];
								StateList -> NewStateList = [{Grade, Price, Percent} | StateList]
							end,
							NewOnsaleStateMap = maps:put({Type, SubType}, NewStateList, OnsaleStateMap),
							NewPS = PS#player_status{vip_bag_onsale = #vip_bag_onsale{onsale_state = NewOnsaleStateMap}},
							% ?DEBUG("UpdatePS SubType:~p Grade:~p Price:~p Percent:~p~n", [SubType, Grade, Price, Percent]),
							{Price, Percent, NewPS}
					end;
				{false, ErrCode} -> {false, ErrCode}
			end;
		%% 已经有优惠价格 操作失败=>已有特惠价格
		{_Price, _Percent} -> {false, ?ERRCODE(fail)}
	end.

%% 计算特惠价格和幸运值 {Price, Percent} | {false, ErrorCode}
cal_onsale_price_and_percent(Type, SubType, Grade) ->
	%% 获取配置中的价格区间，生成优惠价格
	case lib_custom_act_util:get_act_reward_cfg_info(Type, SubType, Grade) of
		#custom_act_reward_cfg{condition = Condition} ->
			case lists:keyfind(price_limit, 1, Condition) of
				{price_limit, [MinPrice, MaxPrice]} when MinPrice < MaxPrice ->
					%% 避免使用原生的随机函数
					% Price = round(rand:uniform() * max(MaxPrice - MinPrice, 0) + MinPrice),
					Price = urand:rand(MinPrice, MaxPrice),
					case cal_lucky_percentage((Price - MinPrice) / (MaxPrice - MinPrice), Condition) of
						{false, ErrCode} -> {false, ErrCode};
						Percent -> {Price, Percent}
					end;
				{price_limit, [_MinPrice, _MaxPrice]} -> {false, ?ERRCODE(config_err)};
				_ -> {false, ?ERRCODE(missing_config)}
			end;
		_ -> {false, ?ERRCODE(missing_config)}
	end.

%% 计算幸运百分比 Percent | {false, ErrorCode}
cal_lucky_percentage(PricePercent, Condition) ->
	case lists:keyfind(percent_range, 1, Condition) of
		{percent_range, [MinPercent, MaxPercent]} when MinPercent < MaxPercent->
			round(MinPercent + (MaxPercent - MinPercent) * (1 - PricePercent));
		{percent_range, [_MinPercent, _MaxPercent]} -> {false, ?ERRCODE(config_err)};
		%% 条件出错
		_ -> {false, ?ERRCODE(missing_config)}
	end.

%% 获取礼包价格信息
get_reward_price_info(PS, Type, SubType, Grade) ->
	case get_onsale_price(PS, Type, SubType, Grade) of
		{Price, Percent} -> skip;
		_ ->
			Price = 0,
			Percent = 0
	end,
	case lib_custom_act_util:get_act_reward_cfg_info(Type, SubType, Grade) of
		#custom_act_reward_cfg{condition = Condition} ->
			case lists:keyfind(normal_price, 1, Condition) of
				{normal_price, NormalPrice} -> {NormalPrice, Price, Percent};
				_ -> {false, ?ERRCODE(missing_config)}
			end;
		_ -> {false, ?ERRCODE(missing_config)}
	end.

%% 判断VIP等级是否满足条件 true | {false, ErrorCode}
is_vip_level_right(PS, Type, SubType, Grade) ->
	#player_status{figure = #figure{vip = VIP}} = PS,
	case lib_custom_act_util:get_act_reward_cfg_info(Type, SubType, Grade) of
		#custom_act_reward_cfg{condition = Condition} ->
			VIPNeedState = lib_custom_act_check:check_act_condtion([viplv], Condition),
			BagTypeState = lib_custom_act_check:check_act_condtion([bag_type], Condition),
			if
				VIPNeedState =/= false andalso BagTypeState =/= false ->
					[VIPNeed] = VIPNeedState,
					[BagType] = BagTypeState,
					if
						%% 超值礼包
						(VIP =:= VIPNeed) and (BagType =:= 0) ->
							true;
						%% VIPx礼包
						(VIP >= VIPNeed) and (BagType =:= 1) ->
							true;
						true ->
							{false, ?ERRCODE(err339_vip_lv_not_enough)}
					end;
				true -> {false, ?ERRCODE(missing_config)}
			end;
		_ -> {false, ?ERRCODE(missing_config)}
	end.

%% 获取礼包的状态 ?NOT_SHOW => 不显示，?ONLY_SHOW => 仅显示，?CAN_BUY => 可购买
check_bag_status(VIP, Condition) ->
	case lists:keyfind(bag_type, 1, Condition) of
		{bag_type, 0} ->
			case lists:keyfind(viplv, 1, Condition) of
				{viplv, VIP} -> ?CAN_BUY;
				_ -> ?NOT_SHOW
			end;
		{bag_type, 1} ->
			case lists:keyfind(viplv, 1, Condition) of
				{viplv, VIP_MIN} ->
					if
					 	VIP_MIN =< VIP -> ?CAN_BUY;
					 	VIP_MIN =:= VIP + 1 -> ?ONLY_SHOW;
					 	true -> ?NOT_SHOW
					end;
				_ -> ?NOT_SHOW
			end;
		_ -> ?NOT_SHOW
	end.

%% ------------------ 回调方法 ------------------
%% VIP发生改变时，更新礼包状态
handle_event(PS, #event_callback{type_id = ?EVENT_VIP, data=_Data}) when is_record(PS, player_status) ->
	SubTypeList = lib_custom_act_api:get_open_subtype_ids(?CUSTOM_ACT_TYPE_VIP_BAG_ONSALE),
    [lib_custom_act:ask_reward_status(PS, ?CUSTOM_ACT_TYPE_VIP_BAG_ONSALE, SubType) || SubType <- SubTypeList],
    {ok, PS};
handle_event(PS, _) -> {ok, PS}.

%% ------------------- db操作 -------------------
db_vip_bag_onsale_select(RoleId) ->
    SQL = io_lib:format(?sql_vip_bag_onsale_select, [RoleId]),
    db:get_all(SQL).

db_vip_bag_onsale_replace(RoleId, Act_type, Sub_type, Grade, Price, Percent) ->
	SQL = io_lib:format(?sql_vip_bag_onsale_replace, [RoleId, Act_type, Sub_type, Grade, Price, Percent]),
	db:execute(SQL).

db_vip_bag_onsale_delete(Act_type, Sub_type) ->
	SQL = io_lib:format(?sql_vip_bag_onsale_delete, [Act_type, Sub_type]),
	db:execute(SQL).
