%%%-------------------------------------------------------------------
%%% @author tyl
%%% @doc
%%%     源樱之礼(阶段抽奖) - 积分商城
%%% @end
%%% Created : 2021-03-10
%%%-------------------------------------------------------------------
-module(sakura_store).

-include("sakura_gift.hrl").
-include("custom_act.hrl").
-include("server.hrl").
-include("common.hrl").
-include("def_module.hrl").
-include("predefine.hrl").
-include("def_goods.hrl").
-include("goods.hrl").
-include("figure.hrl").
-include("rec_event.hrl").
-include("def_event.hrl").
-include("errcode.hrl").

%% API
-export([
	sakura_store_info/2             %% 商城数据
	,exchange_store_goods/4         %% 商城兑换
	,put_dict_store/3               %% 商场缓存
]).


%% 商城数据
sakura_store_info(#player_status{id = RoleId, sid = Sid}, SubType) ->
	Type = ?CUSTOM_ACT_TYPE_SAKURA_GIFT,
	case lib_custom_act_api:is_open_act(Type, SubType) of
		true ->
			StoreGoods = data_sakura_gift:get_all_store_gift(SubType),
			BuyList = get_exchange_counts(RoleId, SubType, StoreGoods),
			#custom_act_data{act_data = ActData} =
				lib_custom_act_data:custom_act_data(?CUSTOM_ACT_TYPE_SAKURA_GIFT, SubType),
			case sakura_gift:trans_sakura_data(ActData) of
				#sakura_data{points = Points} -> ok;
				_ -> Points = 0
			end,
			lib_server_send:send_to_sid(
				Sid, pt_334, 33403, [SubType, Points, BuyList]
			);
		_ ->
			lib_server_send:send_to_sid(
				Sid, pt_331, 33100, [?ERRCODE(err331_act_closed)]
			)
	end,
	ok.

%% 商城兑换
exchange_store_goods(#player_status{sid = Sid, id = RoleId} = Player, SubType, RewardId, ExchangeNum) ->
	Type = ?CUSTOM_ACT_TYPE_SAKURA_GIFT,
	case lib_custom_act_api:is_open_act(Type, SubType) of
		true ->
			#custom_act_data{act_data = ActData} = CustomActData =
				lib_custom_act_data:custom_act_data(?CUSTOM_ACT_TYPE_SAKURA_GIFT, SubType),
			Points = case sakura_gift:trans_sakura_data(ActData) of
				         #sakura_data{points = TPoints} -> TPoints;
				         _ -> 0
			         end,
			ExcCount = get_exchange_counts(RoleId, SubType, RewardId),
			%% 检查活动子类型，检查point
			case data_sakura_gift:get_store_gift(RewardId) of
				#base_sakura_gift_point_reward{
					goods   = GiveGoods
					,limit  = LimitNum
					,points = NeedPoints
				} ->
					CheckList = [{reward_id, RewardId, SubType}, {need_points, NeedPoints}
						,{limit_num, LimitNum, ExcCount, ExchangeNum}
						,{enough_points, NeedPoints, ExchangeNum, Points}
					],
					case check_list(CheckList) of
						true ->
							FinGiveGoods = case GiveGoods of
											   [{_, _, _}|_] ->
												   [
													   {SGoodType, SRewardId, SNum*ExchangeNum}||
													   {SGoodType, SRewardId, SNum}<-GiveGoods
												   ];
											   _ ->
												   []
							               end,
							Produce = #produce{type = sakura_store, reward = FinGiveGoods},
							{ok, Player1} = lib_goods_api:send_reward_with_mail(
								Player, Produce, ?MOD_SAKURA_GIFT
							),
							%% 扣除积分，增加购买次数
							NewPoints  = max(0, Points - NeedPoints*ExchangeNum),
							NewActData = ActData#sakura_data{points = NewPoints},
							NewCustomActData = CustomActData#custom_act_data{
								act_data = NewActData, time = utime:unixtime()
							},
							lib_custom_act_data:save_custom_data(RoleId, NewCustomActData),
							add_exchange_counts(RoleId, SubType, RewardId, ExchangeNum),
							lib_server_send:send_to_sid(
								Sid, pt_334, 33404, [?SUCCESS, SubType, NewPoints, RewardId, ExcCount+ExchangeNum]
							),
							Player1;
						{false, Err} ->
							lib_server_send:send_to_sid(
								Sid, pt_334, 33404, [Err, SubType, Points, RewardId, ExcCount]
							),
							Player
					end;
				_ ->
					lib_server_send:send_to_sid(
						Sid, pt_334, 33404, [?ERRCODE(err334_store_good_cfg_err), SubType, Points, RewardId, ExcCount]
					),
					Player
			end;
		_ ->
			lib_server_send:send_to_sid(
				Sid, pt_331, 33100, [?ERRCODE(err331_act_closed)]
			),
			Player
	end.

get_dict_store(RoleId, SubType) ->
	GoodsKey = ?SAKURA_GOODS(RoleId, SubType),
	case get(GoodsKey) of
		GoodsList when is_list(GoodsList) -> ok;
		_ ->
			GoodsList = get_goods_from_db(RoleId, SubType),
			put(GoodsKey, GoodsList)
	end,
	GoodsList.

put_dict_store(RoleId, SubType, GoodsList) when is_list(GoodsList) ->
	GoodsKey = ?SAKURA_GOODS(RoleId, SubType),
	put(GoodsKey, GoodsList),
	ok;
put_dict_store(_, _, _) ->
	ok.

get_goods_from_db(RoleId, SubType) ->
	case db:get_all(io_lib:format(?SQL_SELECT_SAKURA_STORE, [RoleId, SubType])) of
		[_|_] = DbList ->
			F = fun([RewardId, Times], TList) ->
				StoreGood = #role_sakura_goods{
					sub_type = SubType
					,goods_id = RewardId
					,exc_time = Times
				},
				[StoreGood|TList]
			    end,
			GoodsList = lists:foldl(F, [], DbList),
			GoodsList;
		_ ->
			[]
	end.

save_db_goods(RoleId, SubType, RewardId, Num) ->
	db:execute(io_lib:format(?SQL_SAVE_SAKURA_STORE, [RoleId, SubType, RewardId, Num])),
	ok.


%% -------------------------------- builtin_function ----------------------------------
%% 获取已经购买的次数
get_exchange_counts(RoleId, SubType, RewardList) when is_list(RewardList) ->
	F = fun(RewardId, TList) ->
		Times = get_exchange_counts(RoleId, SubType, RewardId),
		[{RewardId, Times}|TList]
	end,
	lists:foldl(F, [], RewardList);
get_exchange_counts(RoleId, SubType, RewardId) ->
	GoodList = get_dict_store(RoleId, SubType),
	case lists:keyfind(RewardId, #role_sakura_goods.goods_id, GoodList) of
		#role_sakura_goods{exc_time = Times} -> ok;
		_ -> Times = 0
	end,
	Times.

%% 增加购买的次数
add_exchange_counts(RoleId, SubType, RewardId, BuyNum) ->
	GoodsList = get_dict_store(RoleId, SubType),
	NewSakuraGood = case lists:keyfind(RewardId, #role_sakura_goods.goods_id, GoodsList) of
		                #role_sakura_goods{exc_time = Times} = SakuraGood ->
			                NewExcTimes = Times + BuyNum,
			                save_db_goods(RoleId, SubType, RewardId, NewExcTimes),
			                SakuraGood#role_sakura_goods{exc_time = NewExcTimes};
		                _ ->
			                save_db_goods(RoleId, SubType, RewardId, BuyNum),
			                #role_sakura_goods{
				                sub_type = SubType, goods_id = RewardId, exc_time = BuyNum
			                }
	                end,
	NewGoodsList = lists:keystore(
		RewardId, #role_sakura_goods.goods_id, GoodsList, NewSakuraGood
	),
	put_dict_store(RoleId, SubType, NewGoodsList).


check_list([]) -> true;
check_list([Check|T]) ->
	case check(Check) of
		true -> check_list(T);
		{false, Err} -> {false, Err}
	end.

check({reward_id, RewardId, SubType}) ->
	case data_sakura_gift:get_store_gift(RewardId) of
		#base_sakura_gift_point_reward{act_id = SubType} ->
			true;
		_ ->
			{false, ?ERRCODE(err331_sakura_store_reward_err)}
	end;
check({need_points, NeedPoints}) ->
	case NeedPoints > 0 of
		true ->
			true;
		_ ->
			{false, ?ERRCODE(err331_sakura_store_points_err)}
	end;
check({limit_num, LimitNum, BuyCount, ExchangeNum}) ->
	case LimitNum >= BuyCount+ExchangeNum of
		true ->
			true;
		_ ->
			{false, ?ERRCODE(err331_sakura_exchange_num_err)}
	end;
check({enough_points, NeedPoints, ExchangeNum, Points}) ->
	case ExchangeNum > 0 of
		true ->
			case Points >= NeedPoints*ExchangeNum of
				true ->
					true;
				_ ->
					{false, ?ERRCODE(err331_sakur_points_not_enough)}
			end;
		_ ->
			{false, ?ERRCODE(err331_sakura_exchange_num_err)}
	end;
check(_) ->
	{false, ?FAIL}.